[
  {
    "path": ".gitignore",
    "content": "build\nnode_modules\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "### v1.3.1\n- devtools: enabled selection\n- devtools: enabled reactive mode by default\n\n### v1.3\n- devtools: improved performance\n- devtools: reduced extension size\n\n### v1.2.5\n- devtools: improved subscriptions sorting\n\n### v1.2.4\n- devtools: improved subscriptions sorting\n\n### v1.2.3\n- devtools: subscriptions are now sorted\n\n### v1.2.2\n- devtools: fixed subscriptions icon\n\n### v1.2.1\n- devtools: renamed to Meteor MiniMongo Explorer\n\n### v1.2.0\n- devtools: methods listing\n- devtools: monospace font in subcriptions listing\n- devtools: natural sort of collections and subscriptions\n\n### v1.1.3\n- devtools: prevent panel duplication\n\n### v1.1.2\n- devtools: prevent panel duplication\n\n### v1.1.1\n- devtools: persistent state - no need to refresh devtools - even between pages\n\n### v1.1.0\n- devtools: improved performance\n- devtools: limiting documents\n- devtools: new table view\n\n### v1.0.1\n- devtools: fields are now sorted\n\n### v1.0.0\n- devtools: application in chrome web store\n\n### v0.9.0\n- devtools: limiting fields\n\n### v0.8.6\n- devtools: support for named local collections\n\n### v0.8.5\n- devtools: reactive mode fallback\n\n### v0.8.4\n- devtools: subscriptions listing is selectable\n\n### v0.8.3\n- devtools: subscriptions listing fix\n\n### v0.8.2\n- devtools: improved performance\n- devtools: reduced memory usage\n\n### v0.8.1\n- devtools: `Date` fields fix\n- devtools: UI tweaks\n\n### v0.8.0\n- devtools: subscriptions listing\n- devtools: case insensitive collections sorting\n\n### v0.7.2\n- devtools: visible only on sites using Meteor\n\n### v0.7.1\n- devtools: improved performance with many tabs opened\n- devtools: UI tweaks\n\n### v0.7.0\n- devtools: reduced extension size\n- devtools: improved performance\n- devtools: UI tweaks\n\n### v0.6.0\n- devtools: sorting\n- devtools: UI tweaks\n\n### v0.5.4\n- devtools: support for [ObjectId](https://docs.mongodb.org/manual/reference/object-id/)\n\n### v0.5.3\n- devtools: middle click closes tab\n\n### v0.5.2\n- devtools: query background transition\n- devtools: refresh refreshes queries\n- devtools: tabs are stackable\n- devtools: text view is selectable\n\n### v0.5.1\n- devtools: optimized reactive mode\n\n### v0.5.0\n- devtools: new UI built with [Photon](http://photonkit.com/)\n\n### v0.4.1\n- devtools: reactive mode hides `resfresh` button\n\n### v0.4.0\n- devtools: reactive mode\n\n### v0.3.4\n- devtools: improved spelling\n\n### v0.3.3\n- devtools: show help button\n- devtools: show/hide sidebar\n\n### v0.3.2\n- devtools: refresh refreshes queries\n- devtools: results count in tab\n\n### v0.3.1\n- devtools: retrieving data fix\n\n### v0.3.0\n- devtools: collections counts\n- devtools: collections listing\n- devtools: live querying\n- devtools: refreshing on request\n- devtools: snapshot of MiniMongo\n- devtools: tabs\n- devtools: text and object inspector mode\n- pageAction: removed\n\n### v0.2.1\n- pageAction: fixed width\n\n### v0.2.0\n- pageAction: object inspector\n\n### v0.1.0\n- pageAction: documents counts on collection listing\n- pageAction: visible only on sites using Meteor\n\n### v0.0.1\n- pageAction: collections listing\n- pageAction: live querying\n- pageAction: results count\n- pageAction: snapshot of MiniMongo\n"
  },
  {
    "path": "README.md",
    "content": "# Meteor MiniMongo Explorer\n\n### Handy Google Chrome extension for reviewing MiniMongo.\n\n![MiniMongoExplorer](https://raw.githubusercontent.com/radekmie/MiniMongoExplorer/master/binary/github-1.png)\n![MiniMongoExplorer](https://raw.githubusercontent.com/radekmie/MiniMongoExplorer/master/binary/github-2.png)\n![MiniMongoExplorer](https://raw.githubusercontent.com/radekmie/MiniMongoExplorer/master/binary/github-3.png)\n![MiniMongoExplorer](https://raw.githubusercontent.com/radekmie/MiniMongoExplorer/master/binary/github-4.png)\n\n### Features:\n\n- collections counts\n- collections listing\n- limiting fields\n- live sorting\n- live querying\n- methods listing\n- multiple tabs\n- subscriptions listing\n- object inspector mode\n- reactive mode\n\n### Installation:\n\nInstall MiniMongoExplorer from [Chrome Web Store](https://chrome.google.com/webstore/detail/minimongoexplorer/bpbalpgdnkieljogofnfjmgcnjcaiheg).\n\n### Development:\n\n- clone this repo\n- `npm install`\n- `npm run build:chrome` to rebuild\n- `npm run watch:chrome` to rebuild on file change\n- build extension is in `build` directory\n"
  },
  {
    "path": "chrome/background.js",
    "content": "import 'file-loader?name=manifest.json!./manifest.json';\nimport 'file-loader?name=images/icon16.png!../extension/assets/images/icon16.png';\nimport 'file-loader?name=images/icon32.png!../extension/assets/images/icon32.png';\nimport 'file-loader?name=images/icon64.png!../extension/assets/images/icon64.png';\n\nimport { NEW } from '../extension/lib/reduxConstants';\n\nlet sockets = {};\n\nchrome.runtime.onConnect.addListener(port => {\n    let onMessage = message => {\n        if (NEW === message.type) {\n            sockets[message.id] = port;\n        }\n\n        chrome.tabs.sendMessage(message.id, message);\n    };\n\n    port.onMessage.addListener(onMessage);\n    port.onDisconnect.addListener(port => {\n        port.onMessage.removeListener(onMessage);\n\n        sockets = Object.keys(sockets)\n            .filter(socket => sockets[socket] !== port)\n            .reduce((a, b) => ({ ...a, [b]: sockets[b] }), {});\n    });\n});\n\nchrome.runtime.onMessage.addListener((message, sender) => {\n    if (sender.tab && sender.tab.id && sockets[sender.tab.id]) {\n        sockets[sender.tab.id].postMessage(message);\n    }\n});\n"
  },
  {
    "path": "chrome/content.js",
    "content": "chrome.runtime.onMessage.addListener(message => window.postMessage(message, '*'));\n\nwindow.addEventListener('message', event => {\n    if (event.source === window && event.data.message && event.data.process === true) {\n        chrome.runtime.sendMessage(event.data.message);\n    }\n});\n"
  },
  {
    "path": "chrome/devtools.js",
    "content": "let panelNeeded = true;\nlet panelNeededId = -1;\nlet panelNeededCheck = () =>\n    panelNeeded && chrome.devtools.inspectedWindow.eval('!!Meteor.connection.status', isMeteor => {\n        if (isMeteor && panelNeeded) {\n            clearInterval(panelNeededId);\n\n            panelNeeded   = false;\n            panelNeededId = false;\n\n            chrome.devtools.panels.create('MiniMongoExplorer', 'images/icon64.png', 'panel.html');\n        }\n    })\n;\n\npanelNeededId = setInterval(panelNeededCheck, 100);\n\nchrome.devtools.network.onNavigated.addListener(panelNeededCheck);\n"
  },
  {
    "path": "chrome/manifest.json",
    "content": "{\n    \"name\": \"Meteor MiniMongo Explorer\",\n    \"version\": \"1.3.1\",\n    \"short_name\": \"MiniMongoExplorer\",\n\n    \"homepage_url\": \"https://github.com/radekmie/MiniMongoExplorer\",\n\n    \"permissions\": [\n        \"tabs\"\n    ],\n\n    \"icons\": {\n        \"16\": \"images/icon16.png\",\n        \"32\": \"images/icon32.png\",\n        \"64\": \"images/icon64.png\"\n    },\n\n    \"background\": {\n        \"persistent\": false,\n        \"scripts\": [\n            \"background.js\"\n        ]\n    },\n\n    \"content_scripts\": [\n        {\n            \"matches\": [\n                \"http://*/*\",\n                \"https://*/*\"\n            ],\n\n            \"js\": [\n                \"content.js\"\n            ]\n        }\n    ],\n\n    \"devtools_page\": \"devtools.html\",\n\n    \"manifest_version\": 2,\n    \"minimum_chrome_version\": \"26\",\n    \"content_security_policy\": \"script-src 'self' 'unsafe-eval'; object-src 'self'\"\n}\n"
  },
  {
    "path": "chrome/panel.css",
    "content": "@import '../extension/components/MiniMongoExplorer.css';\n"
  },
  {
    "path": "chrome/panel.js",
    "content": "import { createElement } from 'react';\nimport { render }        from 'react-dom';\n\nimport ready             from '../extension/lib/ready';\nimport inject            from '../extension/lib/inject';\nimport create            from '../extension/lib/reduxState';\nimport store             from '../extension/lib/reduxStore';\nimport parse             from '../extension/lib/injectParse';\nimport { DEL, NEW, SET } from '../extension/lib/reduxConstants';\n\nimport MiniMongoExplorer from '../extension/components/MiniMongoExplorer';\n\ndocument.addEventListener('DOMContentLoaded', () => {\n    let port = chrome.runtime.connect();\n    if (port) {\n        let dispatch = payload => {\n            store.dispatch   ({ type: SET, payload });\n            port .postMessage({ type: SET, payload, id: chrome.devtools.inspectedWindow.tabId });\n        };\n\n        let renderId;\n        let renderDirect    = () => render(createElement(MiniMongoExplorer, { dispatch, ...store.getState() }), document.body);\n        let renderThrottled = () => {\n            if (renderId) {\n                cancelAnimationFrame(renderId);\n            }\n\n            renderId = requestAnimationFrame(renderDirect);\n        };\n\n        store.subscribe(renderThrottled);\n\n        var initialize = refresh => {\n            let payload = refresh ? store.getState() : create();\n            if (payload) {\n                store.dispatch   ({ type: NEW, payload });\n                port .postMessage({ type: NEW, payload, id: chrome.devtools.inspectedWindow.tabId });\n            }\n        };\n\n        var connect = initialized => chrome.devtools.inspectedWindow.eval(inject, () => {\n            port.onMessage.addListener(message => store.dispatch(parse(message)));\n\n            let retry = () => chrome.devtools.inspectedWindow.eval(ready, loaded => {\n                if (loaded) {\n                    initialize(initialized);\n                } else {\n                    setTimeout(retry, 100);\n                }\n            });\n\n            retry();\n        });\n\n        chrome.devtools.network.onNavigated.addListener(connect);\n        connect();\n\n        window.addEventListener('beforeunload', () => {\n            port.postMessage({ type: DEL, id: chrome.devtools.inspectedWindow.tabId });\n            port.disconnect();\n        });\n    }\n});\n"
  },
  {
    "path": "extension/assets/translations/en.js",
    "content": "export default {\n    github: 'MiniMongoExplorer on GitHub',\n\n    help: {\n        toggle: 'Toggle help'\n    },\n\n    mode: [\n        'Switch to table mode',\n        'Switch to text mode',\n        'Switch to object mode'\n    ],\n\n    methods: {\n        name: 'Method',\n        toggle: 'Toggle methods'\n    },\n\n    reactivity: {\n        disable: 'Disable reactivity',\n        enable:  'Enable reactivity'\n    },\n\n    sidebar: {\n        hide: 'Hide sidebar',\n        show: 'Show sidebar'\n    },\n\n    subscriptions: {\n        name:   'Subscription',\n        params: 'Params',\n        ready:  'Is ready',\n        toggle: 'Toggle subscriptions'\n    },\n\n    ui: {\n        close:       'Close all tabs',\n        collections: 'Collections',\n        no:          '✗',\n        query:       'Query',\n        refresh:     'Refresh snapshot',\n        yes:         '✔'\n    }\n};\n"
  },
  {
    "path": "extension/assets/vendor/photon.css",
    "content": "/*!\n * =====================================================\n * Photon v0.1.2\n * Copyright 2016 Connor Sears\n * Licensed under MIT (https://github.com/connors/proton/blob/master/LICENSE)\n *\n * v0.1.2 designed by @connors.\n * =====================================================\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  vertical-align: baseline;\n}\n\naudio:not([controls]) {\n  display: none;\n}\n\na:active,\na:hover {\n  outline: 0;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb,\nstrong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\nsmall {\n  font-size: 80%;\n}\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\npre {\n  overflow: auto;\n}\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit;\n  font: inherit;\n  margin: 0;\n}\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield;\n  box-sizing: content-box;\n}\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\nlegend {\n  border: 0;\n  padding: 0;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n\n* {\n  cursor: default;\n  -webkit-user-select: none;\n}\n\ninput,\ntextarea {\n  -webkit-user-select: text;\n}\n\nform,\ninput,\noptgroup,\nselect,\ntextarea {\n  -webkit-user-select: text;\n  -webkit-app-region: no-drag;\n}\n\n* {\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n}\n\nhtml {\n  height: 100%;\n  width: 100%;\n  overflow: hidden;\n}\n\nbody {\n  height: 100%;\n  padding: 0;\n  margin: 0;\n  font-family: system, -apple-system, \".SFNSDisplay-Regular\", \"Helvetica Neue\", Helvetica, \"Segoe UI\", sans-serif;\n  font-size: 13px;\n  line-height: 1.6;\n  color: #333;\n  background-color: transparent;\n}\n\nhr {\n  margin: 15px 0;\n  overflow: hidden;\n  background: transparent;\n  border: 0;\n  border-bottom: 1px solid #ddd;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n  font-weight: 500;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\nh1 {\n  font-size: 36px;\n}\n\nh2 {\n  font-size: 30px;\n}\n\nh3 {\n  font-size: 24px;\n}\n\nh4 {\n  font-size: 18px;\n}\n\nh5 {\n  font-size: 14px;\n}\n\nh6 {\n  font-size: 12px;\n}\n\n.window {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  display: flex;\n  flex-direction: column;\n  background-color: #fff;\n}\n\n.window-content {\n  position: relative;\n  overflow-y: auto;\n  display: flex;\n  flex: 1;\n}\n\n.selectable-text {\n  cursor: text;\n  -webkit-user-select: text;\n}\n\n.text-center {\n  text-align: center;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.pull-left {\n  float: left;\n}\n\n.pull-right {\n  float: right;\n}\n\n.padded {\n  padding: 10px;\n}\n\n.padded-less {\n  padding: 5px;\n}\n\n.padded-more {\n  padding: 20px;\n}\n\n.padded-vertically {\n  padding-top: 10px;\n  padding-bottom: 10px;\n}\n\n.padded-vertically-less {\n  padding-top: 5px;\n  padding-bottom: 5px;\n}\n\n.padded-vertically-more {\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n\n.padded-horizontally {\n  padding-right: 10px;\n  padding-left: 10px;\n}\n\n.padded-horizontally-less {\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\n.padded-horizontally-more {\n  padding-right: 20px;\n  padding-left: 20px;\n}\n\n.padded-top {\n  padding-top: 10px;\n}\n\n.padded-top-less {\n  padding-top: 5px;\n}\n\n.padded-top-more {\n  padding-top: 20px;\n}\n\n.padded-bottom {\n  padding-bottom: 10px;\n}\n\n.padded-bottom-less {\n  padding-bottom: 5px;\n}\n\n.padded-bottom-more {\n  padding-bottom: 20px;\n}\n\n.sidebar {\n  background-color: #f5f5f4;\n}\n\n.draggable {\n  -webkit-app-region: drag;\n}\n\n.not-draggable {\n  -webkit-app-region: no-drag;\n}\n\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after {\n  clear: both;\n}\n\n.btn {\n  display: inline-block;\n  padding: 3px 8px;\n  margin-bottom: 0;\n  font-size: 12px;\n  line-height: 1.4;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  cursor: default;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06);\n  -webkit-app-region: no-drag;\n}\n.btn:focus {\n  outline: none;\n  box-shadow: none;\n}\n\n.btn-mini {\n  padding: 2px 6px;\n}\n\n.btn-large {\n  padding: 6px 12px;\n}\n\n.btn-form {\n  padding-right: 20px;\n  padding-left: 20px;\n}\n\n.btn-default {\n  color: #333;\n  border-top-color: #c2c0c2;\n  border-right-color: #c2c0c2;\n  border-bottom-color: #a19fa1;\n  border-left-color: #c2c0c2;\n  background-color: #fcfcfc;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fcfcfc), color-stop(100%, #f1f1f1));\n  background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);\n  background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);\n}\n.btn-default:active {\n  background-color: #ddd;\n  background-image: none;\n}\n\n.btn-primary,\n.btn-positive,\n.btn-negative,\n.btn-warning {\n  color: #fff;\n  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n}\n\n.btn-primary {\n  border-color: #388df8;\n  border-bottom-color: #0866dc;\n  background-color: #6eb4f7;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6eb4f7), color-stop(100%, #1a82fb));\n  background-image: -webkit-linear-gradient(top, #6eb4f7 0%, #1a82fb 100%);\n  background-image: linear-gradient(to bottom, #6eb4f7 0%, #1a82fb 100%);\n}\n.btn-primary:active {\n  background-color: #3e9bf4;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9bf4), color-stop(100%, #0469de));\n  background-image: -webkit-linear-gradient(top, #3e9bf4 0%, #0469de 100%);\n  background-image: linear-gradient(to bottom, #3e9bf4 0%, #0469de 100%);\n}\n\n.btn-positive {\n  border-color: #29a03b;\n  border-bottom-color: #248b34;\n  background-color: #5bd46d;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bd46d), color-stop(100%, #29a03b));\n  background-image: -webkit-linear-gradient(top, #5bd46d 0%, #29a03b 100%);\n  background-image: linear-gradient(to bottom, #5bd46d 0%, #29a03b 100%);\n}\n.btn-positive:active {\n  background-color: #34c84a;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #34c84a), color-stop(100%, #248b34));\n  background-image: -webkit-linear-gradient(top, #34c84a 0%, #248b34 100%);\n  background-image: linear-gradient(to bottom, #34c84a 0%, #248b34 100%);\n}\n\n.btn-negative {\n  border-color: #fb2f29;\n  border-bottom-color: #fb1710;\n  background-color: #fd918d;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fd918d), color-stop(100%, #fb2f29));\n  background-image: -webkit-linear-gradient(top, #fd918d 0%, #fb2f29 100%);\n  background-image: linear-gradient(to bottom, #fd918d 0%, #fb2f29 100%);\n}\n.btn-negative:active {\n  background-color: #fc605b;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fc605b), color-stop(100%, #fb1710));\n  background-image: -webkit-linear-gradient(top, #fc605b 0%, #fb1710 100%);\n  background-image: linear-gradient(to bottom, #fc605b 0%, #fb1710 100%);\n}\n\n.btn-warning {\n  border-color: #fcaa0e;\n  border-bottom-color: #ee9d02;\n  background-color: #fece72;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fece72), color-stop(100%, #fcaa0e));\n  background-image: -webkit-linear-gradient(top, #fece72 0%, #fcaa0e 100%);\n  background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%);\n}\n.btn-warning:active {\n  background-color: #fdbc40;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdbc40), color-stop(100%, #ee9d02));\n  background-image: -webkit-linear-gradient(top, #fdbc40 0%, #ee9d02 100%);\n  background-image: linear-gradient(to bottom, #fdbc40 0%, #ee9d02 100%);\n}\n\n.btn .icon {\n  float: left;\n  width: 14px;\n  height: 14px;\n  margin-top: 1px;\n  margin-bottom: 1px;\n  color: #737475;\n  font-size: 14px;\n  line-height: 1;\n}\n\n.btn .icon-text {\n  margin-right: 5px;\n}\n\n.btn-dropdown:after {\n  font-family: \"photon-entypo\";\n  margin-left: 5px;\n  content: '\\e873';\n}\n\n.btn-group {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n  -webkit-app-region: no-drag;\n}\n.btn-group .btn {\n  position: relative;\n  float: left;\n}\n.btn-group .btn:focus, .btn-group .btn:active {\n  z-index: 2;\n}\n.btn-group .btn.active {\n  z-index: 3;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-group > .btn:first-child {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group .btn + .btn {\n  border-left: 1px solid #c2c0c2;\n}\n.btn-group .btn + .btn.active {\n  border-left: 0;\n}\n.btn-group .active {\n  color: #fff;\n  border: 1px solid transparent;\n  background-color: #6d6c6d;\n  background-image: none;\n}\n.btn-group .active .icon {\n  color: #fff;\n}\n\n.toolbar {\n  min-height: 22px;\n  box-shadow: inset 0 1px 0 #f5f4f5;\n  background-color: #e8e6e8;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e8e6e8), color-stop(100%, #d1cfd1));\n  background-image: -webkit-linear-gradient(top, #e8e6e8 0%, #d1cfd1 100%);\n  background-image: linear-gradient(to bottom, #e8e6e8 0%, #d1cfd1 100%);\n}\n.toolbar:before, .toolbar:after {\n  display: table;\n  content: \" \";\n}\n.toolbar:after {\n  clear: both;\n}\n\n.toolbar-header {\n  border-bottom: 1px solid #c2c0c2;\n}\n.toolbar-header .title {\n  margin-top: 1px;\n}\n\n.toolbar-footer {\n  border-top: 1px solid #c2c0c2;\n  -webkit-app-region: drag;\n}\n\n.title {\n  margin: 0;\n  font-size: 12px;\n  font-weight: 400;\n  text-align: center;\n  color: #555;\n  cursor: default;\n}\n\n.toolbar-borderless {\n  border-top: 0;\n  border-bottom: 0;\n}\n\n.toolbar-actions {\n  margin-top: 4px;\n  margin-bottom: 3px;\n  padding-right: 3px;\n  padding-left: 3px;\n  padding-bottom: 3px;\n  -webkit-app-region: drag;\n}\n.toolbar-actions:before, .toolbar-actions:after {\n  display: table;\n  content: \" \";\n}\n.toolbar-actions:after {\n  clear: both;\n}\n.toolbar-actions > .btn,\n.toolbar-actions > .btn-group {\n  margin-left: 4px;\n  margin-right: 4px;\n}\n\nlabel {\n  display: inline-block;\n  font-size: 13px;\n  margin-bottom: 5px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\ninput[type=\"search\"] {\n  box-sizing: border-box;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  line-height: normal;\n}\n\n.form-control {\n  display: inline-block;\n  width: 100%;\n  min-height: 25px;\n  padding: 5px 10px;\n  font-size: 13px;\n  line-height: 1.6;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  outline: none;\n}\n.form-control:focus {\n  border-color: #6db3fd;\n  box-shadow: 0 0 0 3px #6db3fd;\n}\n\ntextarea {\n  height: auto;\n}\n\n.form-group {\n  margin-bottom: 10px;\n}\n\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n}\n\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-left: -20px;\n  margin-top: 4px;\n}\n\n.form-actions .btn {\n  margin-right: 10px;\n}\n.form-actions .btn:last-child {\n  margin-right: 0;\n}\n\n.pane-group {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  display: flex;\n}\n\n.pane {\n  position: relative;\n  overflow-y: auto;\n  flex: 1;\n  border-left: 1px solid #ddd;\n}\n.pane:first-child {\n  border-left: 0;\n}\n\n.pane-sm {\n  max-width: 220px;\n  min-width: 150px;\n}\n\n.pane-mini {\n  width: 80px;\n  flex: none;\n}\n\n.pane-one-fourth {\n  width: 25%;\n  flex: none;\n}\n\n.pane-one-third {\n  width: 33.3%;\n  flex: none;\n}\n\nimg {\n  -webkit-user-drag: text;\n}\n\n.img-circle {\n  border-radius: 50%;\n}\n\n.img-rounded {\n  border-radius: 4px;\n}\n\n.list-group {\n  width: 100%;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.list-group * {\n  margin: 0;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.list-group-item {\n  padding: 10px;\n  font-size: 12px;\n  color: #414142;\n  border-top: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top: 0;\n}\n.list-group-item.active, .list-group-item.selected {\n  color: #fff;\n  background-color: #116cd6;\n}\n\n.list-group-header {\n  padding: 10px;\n}\n\n.media-object {\n  margin-top: 3px;\n}\n\n.media-object.pull-left {\n  margin-right: 10px;\n}\n\n.media-object.pull-right {\n  margin-left: 10px;\n}\n\n.media-body {\n  overflow: hidden;\n}\n\n.nav-group {\n  font-size: 14px;\n}\n\n.nav-group-item {\n  padding: 2px 10px 2px 25px;\n  display: block;\n  color: #333;\n  text-decoration: none;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n.nav-group-item:active, .nav-group-item.active {\n  background-color: #dcdfe1;\n}\n.nav-group-item .icon {\n  width: 19px;\n  height: 18px;\n  float: left;\n  color: #737475;\n  margin-top: -3px;\n  margin-right: 7px;\n  font-size: 18px;\n  text-align: center;\n}\n\n.nav-group-title {\n  margin: 0;\n  padding: 10px 10px 2px;\n  font-size: 12px;\n  font-weight: 500;\n  color: #666666;\n}\n\n@font-face {\n  font-family: \"photon-entypo\";\n  src: url(\"../fonts/photon-entypo.woff\") format(\"woff\");\n  font-weight: normal;\n  font-style: normal;\n}\n.icon:before {\n  position: relative;\n  display: inline-block;\n  font-family: \"photon-entypo\";\n  speak: none;\n  font-size: 100%;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.icon-note:before {\n  content: '\\e800';\n}\n\n/* '' */\n.icon-note-beamed:before {\n  content: '\\e801';\n}\n\n/* '' */\n.icon-music:before {\n  content: '\\e802';\n}\n\n/* '' */\n.icon-search:before {\n  content: '\\e803';\n}\n\n/* '' */\n.icon-flashlight:before {\n  content: '\\e804';\n}\n\n/* '' */\n.icon-mail:before {\n  content: '\\e805';\n}\n\n/* '' */\n.icon-heart:before {\n  content: '\\e806';\n}\n\n/* '' */\n.icon-heart-empty:before {\n  content: '\\e807';\n}\n\n/* '' */\n.icon-star:before {\n  content: '\\e808';\n}\n\n/* '' */\n.icon-star-empty:before {\n  content: '\\e809';\n}\n\n/* '' */\n.icon-user:before {\n  content: '\\e80a';\n}\n\n/* '' */\n.icon-users:before {\n  content: '\\e80b';\n}\n\n/* '' */\n.icon-user-add:before {\n  content: '\\e80c';\n}\n\n/* '' */\n.icon-video:before {\n  content: '\\e80d';\n}\n\n/* '' */\n.icon-picture:before {\n  content: '\\e80e';\n}\n\n/* '' */\n.icon-camera:before {\n  content: '\\e80f';\n}\n\n/* '' */\n.icon-layout:before {\n  content: '\\e810';\n}\n\n/* '' */\n.icon-menu:before {\n  content: '\\e811';\n}\n\n/* '' */\n.icon-check:before {\n  content: '\\e812';\n}\n\n/* '' */\n.icon-cancel:before {\n  content: '\\e813';\n}\n\n/* '' */\n.icon-cancel-circled:before {\n  content: '\\e814';\n}\n\n/* '' */\n.icon-cancel-squared:before {\n  content: '\\e815';\n}\n\n/* '' */\n.icon-plus:before {\n  content: '\\e816';\n}\n\n/* '' */\n.icon-plus-circled:before {\n  content: '\\e817';\n}\n\n/* '' */\n.icon-plus-squared:before {\n  content: '\\e818';\n}\n\n/* '' */\n.icon-minus:before {\n  content: '\\e819';\n}\n\n/* '' */\n.icon-minus-circled:before {\n  content: '\\e81a';\n}\n\n/* '' */\n.icon-minus-squared:before {\n  content: '\\e81b';\n}\n\n/* '' */\n.icon-help:before {\n  content: '\\e81c';\n}\n\n/* '' */\n.icon-help-circled:before {\n  content: '\\e81d';\n}\n\n/* '' */\n.icon-info:before {\n  content: '\\e81e';\n}\n\n/* '' */\n.icon-info-circled:before {\n  content: '\\e81f';\n}\n\n/* '' */\n.icon-back:before {\n  content: '\\e820';\n}\n\n/* '' */\n.icon-home:before {\n  content: '\\e821';\n}\n\n/* '' */\n.icon-link:before {\n  content: '\\e822';\n}\n\n/* '' */\n.icon-attach:before {\n  content: '\\e823';\n}\n\n/* '' */\n.icon-lock:before {\n  content: '\\e824';\n}\n\n/* '' */\n.icon-lock-open:before {\n  content: '\\e825';\n}\n\n/* '' */\n.icon-eye:before {\n  content: '\\e826';\n}\n\n/* '' */\n.icon-tag:before {\n  content: '\\e827';\n}\n\n/* '' */\n.icon-bookmark:before {\n  content: '\\e828';\n}\n\n/* '' */\n.icon-bookmarks:before {\n  content: '\\e829';\n}\n\n/* '' */\n.icon-flag:before {\n  content: '\\e82a';\n}\n\n/* '' */\n.icon-thumbs-up:before {\n  content: '\\e82b';\n}\n\n/* '' */\n.icon-thumbs-down:before {\n  content: '\\e82c';\n}\n\n/* '' */\n.icon-download:before {\n  content: '\\e82d';\n}\n\n/* '' */\n.icon-upload:before {\n  content: '\\e82e';\n}\n\n/* '' */\n.icon-upload-cloud:before {\n  content: '\\e82f';\n}\n\n/* '' */\n.icon-reply:before {\n  content: '\\e830';\n}\n\n/* '' */\n.icon-reply-all:before {\n  content: '\\e831';\n}\n\n/* '' */\n.icon-forward:before {\n  content: '\\e832';\n}\n\n/* '' */\n.icon-quote:before {\n  content: '\\e833';\n}\n\n/* '' */\n.icon-code:before {\n  content: '\\e834';\n}\n\n/* '' */\n.icon-export:before {\n  content: '\\e835';\n}\n\n/* '' */\n.icon-pencil:before {\n  content: '\\e836';\n}\n\n/* '' */\n.icon-feather:before {\n  content: '\\e837';\n}\n\n/* '' */\n.icon-print:before {\n  content: '\\e838';\n}\n\n/* '' */\n.icon-retweet:before {\n  content: '\\e839';\n}\n\n/* '' */\n.icon-keyboard:before {\n  content: '\\e83a';\n}\n\n/* '' */\n.icon-comment:before {\n  content: '\\e83b';\n}\n\n/* '' */\n.icon-chat:before {\n  content: '\\e83c';\n}\n\n/* '' */\n.icon-bell:before {\n  content: '\\e83d';\n}\n\n/* '' */\n.icon-attention:before {\n  content: '\\e83e';\n}\n\n/* '' */\n.icon-alert:before {\n  content: '\\e83f';\n}\n\n/* '' */\n.icon-vcard:before {\n  content: '\\e840';\n}\n\n/* '' */\n.icon-address:before {\n  content: '\\e841';\n}\n\n/* '' */\n.icon-location:before {\n  content: '\\e842';\n}\n\n/* '' */\n.icon-map:before {\n  content: '\\e843';\n}\n\n/* '' */\n.icon-direction:before {\n  content: '\\e844';\n}\n\n/* '' */\n.icon-compass:before {\n  content: '\\e845';\n}\n\n/* '' */\n.icon-cup:before {\n  content: '\\e846';\n}\n\n/* '' */\n.icon-trash:before {\n  content: '\\e847';\n}\n\n/* '' */\n.icon-doc:before {\n  content: '\\e848';\n}\n\n/* '' */\n.icon-docs:before {\n  content: '\\e849';\n}\n\n/* '' */\n.icon-doc-landscape:before {\n  content: '\\e84a';\n}\n\n/* '' */\n.icon-doc-text:before {\n  content: '\\e84b';\n}\n\n/* '' */\n.icon-doc-text-inv:before {\n  content: '\\e84c';\n}\n\n/* '' */\n.icon-newspaper:before {\n  content: '\\e84d';\n}\n\n/* '' */\n.icon-book-open:before {\n  content: '\\e84e';\n}\n\n/* '' */\n.icon-book:before {\n  content: '\\e84f';\n}\n\n/* '' */\n.icon-folder:before {\n  content: '\\e850';\n}\n\n/* '' */\n.icon-archive:before {\n  content: '\\e851';\n}\n\n/* '' */\n.icon-box:before {\n  content: '\\e852';\n}\n\n/* '' */\n.icon-rss:before {\n  content: '\\e853';\n}\n\n/* '' */\n.icon-phone:before {\n  content: '\\e854';\n}\n\n/* '' */\n.icon-cog:before {\n  content: '\\e855';\n}\n\n/* '' */\n.icon-tools:before {\n  content: '\\e856';\n}\n\n/* '' */\n.icon-share:before {\n  content: '\\e857';\n}\n\n/* '' */\n.icon-shareable:before {\n  content: '\\e858';\n}\n\n/* '' */\n.icon-basket:before {\n  content: '\\e859';\n}\n\n/* '' */\n.icon-bag:before {\n  content: '\\e85a';\n}\n\n/* '' */\n.icon-calendar:before {\n  content: '\\e85b';\n}\n\n/* '' */\n.icon-login:before {\n  content: '\\e85c';\n}\n\n/* '' */\n.icon-logout:before {\n  content: '\\e85d';\n}\n\n/* '' */\n.icon-mic:before {\n  content: '\\e85e';\n}\n\n/* '' */\n.icon-mute:before {\n  content: '\\e85f';\n}\n\n/* '' */\n.icon-sound:before {\n  content: '\\e860';\n}\n\n/* '' */\n.icon-volume:before {\n  content: '\\e861';\n}\n\n/* '' */\n.icon-clock:before {\n  content: '\\e862';\n}\n\n/* '' */\n.icon-hourglass:before {\n  content: '\\e863';\n}\n\n/* '' */\n.icon-lamp:before {\n  content: '\\e864';\n}\n\n/* '' */\n.icon-light-down:before {\n  content: '\\e865';\n}\n\n/* '' */\n.icon-light-up:before {\n  content: '\\e866';\n}\n\n/* '' */\n.icon-adjust:before {\n  content: '\\e867';\n}\n\n/* '' */\n.icon-block:before {\n  content: '\\e868';\n}\n\n/* '' */\n.icon-resize-full:before {\n  content: '\\e869';\n}\n\n/* '' */\n.icon-resize-small:before {\n  content: '\\e86a';\n}\n\n/* '' */\n.icon-popup:before {\n  content: '\\e86b';\n}\n\n/* '' */\n.icon-publish:before {\n  content: '\\e86c';\n}\n\n/* '' */\n.icon-window:before {\n  content: '\\e86d';\n}\n\n/* '' */\n.icon-arrow-combo:before {\n  content: '\\e86e';\n}\n\n/* '' */\n.icon-down-circled:before {\n  content: '\\e86f';\n}\n\n/* '' */\n.icon-left-circled:before {\n  content: '\\e870';\n}\n\n/* '' */\n.icon-right-circled:before {\n  content: '\\e871';\n}\n\n/* '' */\n.icon-up-circled:before {\n  content: '\\e872';\n}\n\n/* '' */\n.icon-down-open:before {\n  content: '\\e873';\n}\n\n/* '' */\n.icon-left-open:before {\n  content: '\\e874';\n}\n\n/* '' */\n.icon-right-open:before {\n  content: '\\e875';\n}\n\n/* '' */\n.icon-up-open:before {\n  content: '\\e876';\n}\n\n/* '' */\n.icon-down-open-mini:before {\n  content: '\\e877';\n}\n\n/* '' */\n.icon-left-open-mini:before {\n  content: '\\e878';\n}\n\n/* '' */\n.icon-right-open-mini:before {\n  content: '\\e879';\n}\n\n/* '' */\n.icon-up-open-mini:before {\n  content: '\\e87a';\n}\n\n/* '' */\n.icon-down-open-big:before {\n  content: '\\e87b';\n}\n\n/* '' */\n.icon-left-open-big:before {\n  content: '\\e87c';\n}\n\n/* '' */\n.icon-right-open-big:before {\n  content: '\\e87d';\n}\n\n/* '' */\n.icon-up-open-big:before {\n  content: '\\e87e';\n}\n\n/* '' */\n.icon-down:before {\n  content: '\\e87f';\n}\n\n/* '' */\n.icon-left:before {\n  content: '\\e880';\n}\n\n/* '' */\n.icon-right:before {\n  content: '\\e881';\n}\n\n/* '' */\n.icon-up:before {\n  content: '\\e882';\n}\n\n/* '' */\n.icon-down-dir:before {\n  content: '\\e883';\n}\n\n/* '' */\n.icon-left-dir:before {\n  content: '\\e884';\n}\n\n/* '' */\n.icon-right-dir:before {\n  content: '\\e885';\n}\n\n/* '' */\n.icon-up-dir:before {\n  content: '\\e886';\n}\n\n/* '' */\n.icon-down-bold:before {\n  content: '\\e887';\n}\n\n/* '' */\n.icon-left-bold:before {\n  content: '\\e888';\n}\n\n/* '' */\n.icon-right-bold:before {\n  content: '\\e889';\n}\n\n/* '' */\n.icon-up-bold:before {\n  content: '\\e88a';\n}\n\n/* '' */\n.icon-down-thin:before {\n  content: '\\e88b';\n}\n\n/* '' */\n.icon-left-thin:before {\n  content: '\\e88c';\n}\n\n/* '' */\n.icon-right-thin:before {\n  content: '\\e88d';\n}\n\n/* '' */\n.icon-up-thin:before {\n  content: '\\e88e';\n}\n\n/* '' */\n.icon-ccw:before {\n  content: '\\e88f';\n}\n\n/* '' */\n.icon-cw:before {\n  content: '\\e890';\n}\n\n/* '' */\n.icon-arrows-ccw:before {\n  content: '\\e891';\n}\n\n/* '' */\n.icon-level-down:before {\n  content: '\\e892';\n}\n\n/* '' */\n.icon-level-up:before {\n  content: '\\e893';\n}\n\n/* '' */\n.icon-shuffle:before {\n  content: '\\e894';\n}\n\n/* '' */\n.icon-loop:before {\n  content: '\\e895';\n}\n\n/* '' */\n.icon-switch:before {\n  content: '\\e896';\n}\n\n/* '' */\n.icon-play:before {\n  content: '\\e897';\n}\n\n/* '' */\n.icon-stop:before {\n  content: '\\e898';\n}\n\n/* '' */\n.icon-pause:before {\n  content: '\\e899';\n}\n\n/* '' */\n.icon-record:before {\n  content: '\\e89a';\n}\n\n/* '' */\n.icon-to-end:before {\n  content: '\\e89b';\n}\n\n/* '' */\n.icon-to-start:before {\n  content: '\\e89c';\n}\n\n/* '' */\n.icon-fast-forward:before {\n  content: '\\e89d';\n}\n\n/* '' */\n.icon-fast-backward:before {\n  content: '\\e89e';\n}\n\n/* '' */\n.icon-progress-0:before {\n  content: '\\e89f';\n}\n\n/* '' */\n.icon-progress-1:before {\n  content: '\\e8a0';\n}\n\n/* '' */\n.icon-progress-2:before {\n  content: '\\e8a1';\n}\n\n/* '' */\n.icon-progress-3:before {\n  content: '\\e8a2';\n}\n\n/* '' */\n.icon-target:before {\n  content: '\\e8a3';\n}\n\n/* '' */\n.icon-palette:before {\n  content: '\\e8a4';\n}\n\n/* '' */\n.icon-list:before {\n  content: '\\e8a5';\n}\n\n/* '' */\n.icon-list-add:before {\n  content: '\\e8a6';\n}\n\n/* '' */\n.icon-signal:before {\n  content: '\\e8a7';\n}\n\n/* '' */\n.icon-trophy:before {\n  content: '\\e8a8';\n}\n\n/* '' */\n.icon-battery:before {\n  content: '\\e8a9';\n}\n\n/* '' */\n.icon-back-in-time:before {\n  content: '\\e8aa';\n}\n\n/* '' */\n.icon-monitor:before {\n  content: '\\e8ab';\n}\n\n/* '' */\n.icon-mobile:before {\n  content: '\\e8ac';\n}\n\n/* '' */\n.icon-network:before {\n  content: '\\e8ad';\n}\n\n/* '' */\n.icon-cd:before {\n  content: '\\e8ae';\n}\n\n/* '' */\n.icon-inbox:before {\n  content: '\\e8af';\n}\n\n/* '' */\n.icon-install:before {\n  content: '\\e8b0';\n}\n\n/* '' */\n.icon-globe:before {\n  content: '\\e8b1';\n}\n\n/* '' */\n.icon-cloud:before {\n  content: '\\e8b2';\n}\n\n/* '' */\n.icon-cloud-thunder:before {\n  content: '\\e8b3';\n}\n\n/* '' */\n.icon-flash:before {\n  content: '\\e8b4';\n}\n\n/* '' */\n.icon-moon:before {\n  content: '\\e8b5';\n}\n\n/* '' */\n.icon-flight:before {\n  content: '\\e8b6';\n}\n\n/* '' */\n.icon-paper-plane:before {\n  content: '\\e8b7';\n}\n\n/* '' */\n.icon-leaf:before {\n  content: '\\e8b8';\n}\n\n/* '' */\n.icon-lifebuoy:before {\n  content: '\\e8b9';\n}\n\n/* '' */\n.icon-mouse:before {\n  content: '\\e8ba';\n}\n\n/* '' */\n.icon-briefcase:before {\n  content: '\\e8bb';\n}\n\n/* '' */\n.icon-suitcase:before {\n  content: '\\e8bc';\n}\n\n/* '' */\n.icon-dot:before {\n  content: '\\e8bd';\n}\n\n/* '' */\n.icon-dot-2:before {\n  content: '\\e8be';\n}\n\n/* '' */\n.icon-dot-3:before {\n  content: '\\e8bf';\n}\n\n/* '' */\n.icon-brush:before {\n  content: '\\e8c0';\n}\n\n/* '' */\n.icon-magnet:before {\n  content: '\\e8c1';\n}\n\n/* '' */\n.icon-infinity:before {\n  content: '\\e8c2';\n}\n\n/* '' */\n.icon-erase:before {\n  content: '\\e8c3';\n}\n\n/* '' */\n.icon-chart-pie:before {\n  content: '\\e8c4';\n}\n\n/* '' */\n.icon-chart-line:before {\n  content: '\\e8c5';\n}\n\n/* '' */\n.icon-chart-bar:before {\n  content: '\\e8c6';\n}\n\n/* '' */\n.icon-chart-area:before {\n  content: '\\e8c7';\n}\n\n/* '' */\n.icon-tape:before {\n  content: '\\e8c8';\n}\n\n/* '' */\n.icon-graduation-cap:before {\n  content: '\\e8c9';\n}\n\n/* '' */\n.icon-language:before {\n  content: '\\e8ca';\n}\n\n/* '' */\n.icon-ticket:before {\n  content: '\\e8cb';\n}\n\n/* '' */\n.icon-water:before {\n  content: '\\e8cc';\n}\n\n/* '' */\n.icon-droplet:before {\n  content: '\\e8cd';\n}\n\n/* '' */\n.icon-air:before {\n  content: '\\e8ce';\n}\n\n/* '' */\n.icon-credit-card:before {\n  content: '\\e8cf';\n}\n\n/* '' */\n.icon-floppy:before {\n  content: '\\e8d0';\n}\n\n/* '' */\n.icon-clipboard:before {\n  content: '\\e8d1';\n}\n\n/* '' */\n.icon-megaphone:before {\n  content: '\\e8d2';\n}\n\n/* '' */\n.icon-database:before {\n  content: '\\e8d3';\n}\n\n/* '' */\n.icon-drive:before {\n  content: '\\e8d4';\n}\n\n/* '' */\n.icon-bucket:before {\n  content: '\\e8d5';\n}\n\n/* '' */\n.icon-thermometer:before {\n  content: '\\e8d6';\n}\n\n/* '' */\n.icon-key:before {\n  content: '\\e8d7';\n}\n\n/* '' */\n.icon-flow-cascade:before {\n  content: '\\e8d8';\n}\n\n/* '' */\n.icon-flow-branch:before {\n  content: '\\e8d9';\n}\n\n/* '' */\n.icon-flow-tree:before {\n  content: '\\e8da';\n}\n\n/* '' */\n.icon-flow-line:before {\n  content: '\\e8db';\n}\n\n/* '' */\n.icon-flow-parallel:before {\n  content: '\\e8dc';\n}\n\n/* '' */\n.icon-rocket:before {\n  content: '\\e8dd';\n}\n\n/* '' */\n.icon-gauge:before {\n  content: '\\e8de';\n}\n\n/* '' */\n.icon-traffic-cone:before {\n  content: '\\e8df';\n}\n\n/* '' */\n.icon-cc:before {\n  content: '\\e8e0';\n}\n\n/* '' */\n.icon-cc-by:before {\n  content: '\\e8e1';\n}\n\n/* '' */\n.icon-cc-nc:before {\n  content: '\\e8e2';\n}\n\n/* '' */\n.icon-cc-nc-eu:before {\n  content: '\\e8e3';\n}\n\n/* '' */\n.icon-cc-nc-jp:before {\n  content: '\\e8e4';\n}\n\n/* '' */\n.icon-cc-sa:before {\n  content: '\\e8e5';\n}\n\n/* '' */\n.icon-cc-nd:before {\n  content: '\\e8e6';\n}\n\n/* '' */\n.icon-cc-pd:before {\n  content: '\\e8e7';\n}\n\n/* '' */\n.icon-cc-zero:before {\n  content: '\\e8e8';\n}\n\n/* '' */\n.icon-cc-share:before {\n  content: '\\e8e9';\n}\n\n/* '' */\n.icon-cc-remix:before {\n  content: '\\e8ea';\n}\n\n/* '' */\n.icon-github:before {\n  content: '\\e8eb';\n}\n\n/* '' */\n.icon-github-circled:before {\n  content: '\\e8ec';\n}\n\n/* '' */\n.icon-flickr:before {\n  content: '\\e8ed';\n}\n\n/* '' */\n.icon-flickr-circled:before {\n  content: '\\e8ee';\n}\n\n/* '' */\n.icon-vimeo:before {\n  content: '\\e8ef';\n}\n\n/* '' */\n.icon-vimeo-circled:before {\n  content: '\\e8f0';\n}\n\n/* '' */\n.icon-twitter:before {\n  content: '\\e8f1';\n}\n\n/* '' */\n.icon-twitter-circled:before {\n  content: '\\e8f2';\n}\n\n/* '' */\n.icon-facebook:before {\n  content: '\\e8f3';\n}\n\n/* '' */\n.icon-facebook-circled:before {\n  content: '\\e8f4';\n}\n\n/* '' */\n.icon-facebook-squared:before {\n  content: '\\e8f5';\n}\n\n/* '' */\n.icon-gplus:before {\n  content: '\\e8f6';\n}\n\n/* '' */\n.icon-gplus-circled:before {\n  content: '\\e8f7';\n}\n\n/* '' */\n.icon-pinterest:before {\n  content: '\\e8f8';\n}\n\n/* '' */\n.icon-pinterest-circled:before {\n  content: '\\e8f9';\n}\n\n/* '' */\n.icon-tumblr:before {\n  content: '\\e8fa';\n}\n\n/* '' */\n.icon-tumblr-circled:before {\n  content: '\\e8fb';\n}\n\n/* '' */\n.icon-linkedin:before {\n  content: '\\e8fc';\n}\n\n/* '' */\n.icon-linkedin-circled:before {\n  content: '\\e8fd';\n}\n\n/* '' */\n.icon-dribbble:before {\n  content: '\\e8fe';\n}\n\n/* '' */\n.icon-dribbble-circled:before {\n  content: '\\e8ff';\n}\n\n/* '' */\n.icon-stumbleupon:before {\n  content: '\\e900';\n}\n\n/* '' */\n.icon-stumbleupon-circled:before {\n  content: '\\e901';\n}\n\n/* '' */\n.icon-lastfm:before {\n  content: '\\e902';\n}\n\n/* '' */\n.icon-lastfm-circled:before {\n  content: '\\e903';\n}\n\n/* '' */\n.icon-rdio:before {\n  content: '\\e904';\n}\n\n/* '' */\n.icon-rdio-circled:before {\n  content: '\\e905';\n}\n\n/* '' */\n.icon-spotify:before {\n  content: '\\e906';\n}\n\n/* '' */\n.icon-spotify-circled:before {\n  content: '\\e907';\n}\n\n/* '' */\n.icon-qq:before {\n  content: '\\e908';\n}\n\n/* '' */\n.icon-instagram:before {\n  content: '\\e909';\n}\n\n/* '' */\n.icon-dropbox:before {\n  content: '\\e90a';\n}\n\n/* '' */\n.icon-evernote:before {\n  content: '\\e90b';\n}\n\n/* '' */\n.icon-flattr:before {\n  content: '\\e90c';\n}\n\n/* '' */\n.icon-skype:before {\n  content: '\\e90d';\n}\n\n/* '' */\n.icon-skype-circled:before {\n  content: '\\e90e';\n}\n\n/* '' */\n.icon-renren:before {\n  content: '\\e90f';\n}\n\n/* '' */\n.icon-sina-weibo:before {\n  content: '\\e910';\n}\n\n/* '' */\n.icon-paypal:before {\n  content: '\\e911';\n}\n\n/* '' */\n.icon-picasa:before {\n  content: '\\e912';\n}\n\n/* '' */\n.icon-soundcloud:before {\n  content: '\\e913';\n}\n\n/* '' */\n.icon-mixi:before {\n  content: '\\e914';\n}\n\n/* '' */\n.icon-behance:before {\n  content: '\\e915';\n}\n\n/* '' */\n.icon-google-circles:before {\n  content: '\\e916';\n}\n\n/* '' */\n.icon-vkontakte:before {\n  content: '\\e917';\n}\n\n/* '' */\n.icon-smashing:before {\n  content: '\\e918';\n}\n\n/* '' */\n.icon-sweden:before {\n  content: '\\e919';\n}\n\n/* '' */\n.icon-db-shape:before {\n  content: '\\e91a';\n}\n\n/* '' */\n.icon-logo-db:before {\n  content: '\\e91b';\n}\n\n/* '' */\ntable {\n  width: 100%;\n  border: 0;\n  border-collapse: separate;\n  font-size: 12px;\n  text-align: left;\n}\n\nthead {\n  background-color: #f5f5f4;\n}\n\ntbody {\n  background-color: #fff;\n}\n\n.table-striped tr:nth-child(even) {\n  background-color: #f5f5f4;\n}\n\ntr:active,\n.table-striped tr:active:nth-child(even) {\n  color: #fff;\n  background-color: #116cd6;\n}\n\nthead tr:active {\n  color: #333;\n  background-color: #f5f5f4;\n}\n\nth {\n  font-weight: normal;\n  border-right: 1px solid #ddd;\n  border-bottom: 1px solid #ddd;\n}\n\nth,\ntd {\n  padding: 2px 15px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\nth:last-child,\ntd:last-child {\n  border-right: 0;\n}\n\n.tab-group {\n  margin-top: -1px;\n  display: flex;\n  border-top: 1px solid #989698;\n  border-bottom: 1px solid #989698;\n}\n\n.tab-item {\n  position: relative;\n  flex: 1;\n  padding: 3px;\n  font-size: 12px;\n  text-align: center;\n  border-left: 1px solid #989698;\n  background-color: #b8b6b8;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8b6b8), color-stop(100%, #b0aeb0));\n  background-image: -webkit-linear-gradient(top, #b8b6b8 0%, #b0aeb0 100%);\n  background-image: linear-gradient(to bottom, #b8b6b8 0%, #b0aeb0 100%);\n}\n.tab-item:first-child {\n  border-left: 0;\n}\n.tab-item.active {\n  background-color: #d4d2d4;\n  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4d2d4), color-stop(100%, #cccacc));\n  background-image: -webkit-linear-gradient(top, #d4d2d4 0%, #cccacc 100%);\n  background-image: linear-gradient(to bottom, #d4d2d4 0%, #cccacc 100%);\n}\n.tab-item .icon-close-tab {\n  position: absolute;\n  top: 50%;\n  left: 5px;\n  width: 15px;\n  height: 15px;\n  font-size: 15px;\n  line-height: 15px;\n  text-align: center;\n  color: #666;\n  opacity: 0;\n  transition: opacity .1s linear, background-color .1s linear;\n  border-radius: 3px;\n  transform: translateY(-50%);\n  z-index: 10;\n}\n.tab-item:after {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  content: \"\";\n  background-color: rgba(0, 0, 0, 0.08);\n  opacity: 0;\n  transition: opacity .1s linear;\n  z-index: 1;\n}\n.tab-item:hover:not(.active):after {\n  opacity: 1;\n}\n.tab-item:hover .icon-close-tab {\n  opacity: 1;\n}\n.tab-item .icon-close-tab:hover {\n  background-color: rgba(0, 0, 0, 0.08);\n}\n\n.tab-item-fixed {\n  flex: none;\n  padding: 3px 10px;\n}\n"
  },
  {
    "path": "extension/components/Help.js",
    "content": "import React, { Component } from 'react';\n\nimport translations from '../assets/translations/en';\n\nexport default class Help extends Component {\n    shouldComponentUpdate = () => false;\n\n    render = () =>\n        <section className=\"pane\">\n            <section className=\"pane-group\">\n                <section className=\"pane pane-center pane-flex\">\n                    <section className=\"nav-group\">\n                        <span className=\"nav-group-item\"><i className=\"icon icon-left\" /> {translations.sidebar.hide}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-right\" /> {translations.sidebar.show}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-play\" /> {translations.reactivity.enable}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-stop\" /> {translations.reactivity.disable}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-lifebuoy\" /> {translations.help.toggle}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-cloud-thunder\" /> {translations.subscriptions.toggle}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-direction\" /> {translations.methods.toggle}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-newspaper\" /> {translations.mode[0]}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-menu\" /> {translations.mode[1]}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-quote\" /> {translations.mode[2]}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-arrows-ccw\" /> {translations.ui.refresh}</span>\n                        <span className=\"nav-group-item\"><i className=\"icon icon-cancel\" /> {translations.ui.close}</span>\n                    </section>\n                </section>\n            </section>\n        </section>\n    ;\n}\n"
  },
  {
    "path": "extension/components/Methods.js",
    "content": "import React         from 'react';\nimport { PropTypes } from 'react';\n\nimport translations from '../assets/translations/en';\n\nconst Methods = ({ methods }) =>\n    <section className=\"pane pane-scroll\">\n        <table className=\"table-striped\">\n            <thead>\n                <tr>\n                    <td className=\"text-center\"><b>{translations.methods.name}</b></td>\n                </tr>\n            </thead>\n\n            <tbody>\n                {methods.map(method =>\n                    <tr key={method}>\n                        <td>\n                            <code>{method}</code>\n                        </td>\n                    </tr>\n                )}\n            </tbody>\n        </table>\n    </section>\n;\n\nMethods.propTypes = {\n    methods: PropTypes.arrayOf(PropTypes.string).isRequired\n};\n\nexport default Methods;\n"
  },
  {
    "path": "extension/components/MiniMongoExplorer.css",
    "content": "@import '../assets/vendor/photon.css';\n\n* {\n    -webkit-user-select: unset;\n}\n\npre {\n    margin: 0;\n}\n\ntd {\n    vertical-align: top;\n}\n\n.btn.active {\n    color: #fff;\n    border: 1px solid transparent;\n    background-color: #6d6c6d;\n    background-image: none;\n}\n\n.btn.active .icon {\n    color: #fff;\n}\n\n.form-control {\n    flex: 1;\n\n    resize: vertical;\n\n    border-top:   none;\n    border-left:  none;\n    border-right: none;\n\n    font-family: monospace;\n\n    box-shadow: none !important;\n    border-radius: 0 !important;\n\n    transition: background   250ms linear,\n                border-color 250ms linear;\n}\n\n.form-error {\n    background: rgba(252, 96, 91, 0.25);\n}\n\n.form-error:focus {\n    border-color: rgb(252, 96, 91);\n}\n\n.form-group {\n    width: 100% !important;\n\n    margin: 0;\n\n    flex-shrink: 0;\n}\n\n.nav-group {\n    padding: 5px 0;\n}\n\n.nav-group-item {\n    padding: 0 5px 0 15px;\n\n    white-space:   initial;\n    text-overflow: initial;\n}\n\n.nav-group-item > :first-of-type {\n    margin-right: 10px;\n}\n\n.nav-group-sm {\n    line-height: 1.3;\n}\n\n.nav-group-title {\n    padding: 0 5px 2px;\n}\n\n.pane-center {\n    align-items:     center;\n    justify-content: center;\n}\n\n.pane-center .nav-group-item:active {\n  background-color: #fff;\n}\n\n.pane-flex {\n    display: flex;\n\n    flex-direction: column;\n}\n\n.pane-scroll {\n    display: flex;\n\n    flex: 1;\n\n    overflow: auto;\n\n    white-space: pre;\n}\n\n.pane-scroll pre {\n    flex: 1;\n\n    cursor: auto;\n}\n\n.pane-scroll {\n    margin-top: -6px !important;\n}\n\n.pane-scroll > div,\n.pane-scroll > pre {\n    padding: 5px;\n}\n\n.pane-scroll > section > * {\n    border: 0 !important;\n}\n\n.pane-sm {\n    max-width: initial;\n\n    overflow-y: auto;\n    overflow-x: hidden;\n}\n\n.tab-item {\n    padding: 3px 15px 2px;\n}\n\n.tab-item > .icon-close-tab {\n    left: initial;\n    right: 2.5px;\n}\n\n.tab-item > span:last-of-type {\n    margin-left: 2.5px;\n}\n\n.tab-item > span:last-of-type:before {\n    content: \"(\";\n}\n\n.tab-item > span:last-of-type:after {\n    content: \")\";\n}\n\n.tab-group {\n    flex-shrink: 0;\n    flex-wrap: wrap;\n}\n\n.table-striped {\n    margin-top: 6px;\n}\n\n.table-striped tr:active {\n  color: #333 !important;\n  background-color: #fff !important;\n}\n\n.table-striped tr:nth-child(even) {\n  background-color: #f5f5f4 !important;\n}\n\n.table-striped thead tr:active {\n  background-color: #f5f5f4 !important;\n}\n\n.toolbar-actions {\n    margin:  3px 0 4px;\n    padding: 0 4px;\n}\n\n.toolbar-actions > .btn {\n    margin-right: 0;\n}\n\n.toolbar-actions > .btn-group {\n    margin-left: 0;\n}\n"
  },
  {
    "path": "extension/components/MiniMongoExplorer.js",
    "content": "import React         from 'react';\nimport { Component } from 'react';\nimport { PropTypes } from 'react';\n\nimport safeDocumentSorter    from '../lib/safeDocumentSorter';\nimport safeDocumentMatcher   from '../lib/safeDocumentMatcher';\nimport safeDocumentProjector from '../lib/safeDocumentProjector';\n\nimport Help          from './Help';\nimport View          from './View';\nimport Query         from './Query';\nimport Result        from './Result';\nimport Methods       from './Methods';\nimport Sidebar       from './Sidebar';\nimport Toolbar       from './Toolbar';\nimport Subscriptions from './Subscriptions';\n\nexport default class MiniMongoExplorer extends Component {\n    static propTypes = {\n        tab:  PropTypes.number.isRequired,\n        tabs: PropTypes.arrayOf(PropTypes.shape({\n            collection: PropTypes.string.isRequired,\n            count:      PropTypes.number.isRequired,\n            error:      PropTypes.bool.isRequired,\n            id:         PropTypes.number.isRequired,\n            query:      PropTypes.string.isRequired,\n            result:     PropTypes.object.isRequired\n        })).isRequired,\n\n        dispatch: PropTypes.func.isRequired,\n\n        isHelpView:          PropTypes.bool.isRequired,\n        isMethodsView:       PropTypes.bool.isRequired,\n        isReactive:          PropTypes.bool.isRequired,\n        isSidebarView:       PropTypes.bool.isRequired,\n        isSubscriptionsView: PropTypes.bool.isRequired,\n\n        methods: PropTypes.arrayOf(PropTypes.string).isRequired,\n\n        mode: PropTypes.number.isRequired,\n\n        snapshot:          PropTypes.object.isRequired,\n        snapshotRequested: PropTypes.bool.isRequired,\n        snapshotTimestamp: PropTypes.number.isRequired,\n\n        subscriptions: PropTypes.object.isRequired\n    };\n\n\n\n    componentWillReceiveProps = ({ snapshot, snapshotTimestamp }) => {\n        if (this.props.snapshotTimestamp < snapshotTimestamp) {\n            this.props.dispatch({\n                tabs: this.props.tabs.map(tab =>\n                    ({ ...tab, ...this.getResult(tab.collection, tab.query, snapshot) })\n                )\n            });\n        }\n    };\n\n\n\n    render = () =>\n        <section className=\"window\">\n            <section className=\"window-content\">\n                <section className=\"pane-group\">\n                    {this.props.isSidebarView && (\n                        <Sidebar collections={this.getCollections()} onTabOpen={this.onTabOpen} />\n                    )}\n\n                    {this.props.isHelpView\n                        ? <Help />\n                        : this.props.isSubscriptionsView\n                            ? <Subscriptions data={this.props.subscriptions} />\n                            : this.props.isMethodsView\n                                ? <Methods methods={this.props.methods} />\n                                : (tab =>\n                                    <View\n                                        onTabClose={this.onTabClose}\n                                        onTabSelect={this.onTabSelect}\n                                        tab={this.props.tab}\n                                        tabs={this.props.tabs}\n                                    >\n                                        {tab && (\n                                            <Query error={tab.error} query={tab.query} onQuery={this.onQuery} />\n                                        )}\n\n                                        {tab && (\n                                            <Result data={tab.result} mode={this.props.mode} />\n                                        )}\n                                    </View>\n                                )(this.getTab())\n                    }\n                </section>\n            </section>\n\n            <Toolbar\n                isHelpView={this.props.isHelpView}\n                isMethodsView={this.props.isMethodsView}\n                isReactive={this.props.isReactive}\n                isSidebarView={this.props.isSidebarView}\n                isSubscriptionsView={this.props.isSubscriptionsView}\n                mode={this.props.mode}\n                onRefresh={this.onRefresh}\n                onTabClose={this.onTabClose}\n                onToggleHelp={this.onToggleHelp}\n                onToggleMethods={this.onToggleMethods}\n                onToggleMode={this.onToggleMode}\n                onToggleReactivity={this.onToggleReactivity}\n                onToggleSidebar={this.onToggleSidebar}\n                onToggleSubscriptions={this.onToggleSubscriptions}\n            />\n        </section>\n    ;\n\n\n\n    getCollections = () =>\n        Object.keys(this.props.snapshot).sort().map(collection => ({\n            name: collection,\n            count: Object.keys(this.props.snapshot[collection]).length\n        }));\n    ;\n\n    getId = doc =>\n        doc._id\n            ? typeof doc._id === 'string'\n                ? doc._id\n                : doc._id._str\n            : `noID#${Math.random().toFixed(15).slice(2)}`\n    ;\n\n    getResult = (collection, query = '{query: {}, fields: {}, sort: {}, limit: 50}', snapshot = this.props.snapshot) => {\n        let limit;\n        let error;\n        let sorter    = safeDocumentSorter(query);\n        let matcher   = safeDocumentMatcher(query);\n        let projector = safeDocumentProjector(query);\n\n        try {\n            let parsed = eval(`(${query})`);\n            if (parsed && parsed.limit !== undefined) {\n                error = parsed.limit < 0;\n                limit = Math.max(0, parsed.limit);\n            }\n        } catch (_) {\n            limit = 50;\n            error = true;\n        }\n\n        let documentsArray = Object.keys(snapshot[collection])\n            .map(_id => snapshot[collection][_id])\n            .filter(matcher.action)\n            .sort(sorter.action)\n        ;\n\n        return {\n            collection,\n\n            query,\n            error: error || sorter.error || matcher.error || projector.error,\n\n            count:  documentsArray.length,\n            result: documentsArray\n                .slice(0, limit)\n                .map(projector.action)\n                .reduce((result, doc) => ({ ...result, [this.getId(doc)]: doc }), {})\n        };\n    };\n\n    getTab = () =>\n        this.props.tabs.filter(tab => tab.id === this.props.tab)[0]\n    ;\n\n\n\n    onQuery = query =>\n        this.props.dispatch({\n            tabs: this.props.tabs.map(tab =>\n                tab.id === this.props.tab\n                    ? ({ ...tab, ...this.getResult(tab.collection, query) })\n                    : tab\n            )\n        })\n    ;\n\n    onRefresh = () =>\n        this.props.dispatch({\n            snapshotRequested: true\n        });\n    ;\n\n    onTabClose = id =>\n        this.props.dispatch({\n            tab:  id === -1 ? -1 : this.props.tab === id ? -1 : this.props.tab,\n            tabs: id === -1 ? [] : this.props.tabs.filter(tab => tab.id !== id)\n        })\n    ;\n\n    onTabOpen = collection => {\n        const id = Date.now();\n\n        this.props.dispatch({\n            tab:  id,\n            tabs: this.props.tabs.concat({ id, ...this.getResult(collection) }),\n            isHelpView:  false,\n            isMethodsView: false,\n            isSubscriptionsView: false\n        });\n    };\n\n    onTabSelect = id =>\n        this.props.dispatch({\n            tab: id\n        })\n    ;\n\n    onToggleHelp = previous =>\n        this.props.dispatch({\n            isHelpView: !previous,\n            isMethodsView: false,\n            isSubscriptionsView: false\n        })\n    ;\n\n    onToggleMethods = previous =>\n        this.props.dispatch({\n            isHelpView: false,\n            isMethodsView: !previous,\n            isSubscriptionsView: false\n        })\n    ;\n\n    onToggleMode = previous =>\n        this.props.dispatch({\n            mode: (previous + 1) % 3\n        })\n    ;\n\n    onToggleReactivity = previous =>\n        this.props.dispatch({\n            isReactive: !previous\n        })\n    ;\n\n    onToggleSidebar = previous =>\n        this.props.dispatch({\n            isSidebarView: !previous\n        })\n    ;\n\n    onToggleSubscriptions = previous =>\n        this.props.dispatch({\n            isHelpView: false,\n            isMethodsView: false,\n            isSubscriptionsView: !previous\n        })\n    ;\n}\n"
  },
  {
    "path": "extension/components/Query.js",
    "content": "import React         from 'react';\nimport { PropTypes } from 'react';\n\nimport Textarea from './Textarea';\n\nimport translations from '../assets/translations/en';\n\nconst Query = ({ error, query, onQuery }) =>\n    <section className=\"form-group\">\n        <Textarea error={error} title={translations.ui.query} value={query} onChange={onQuery} />\n    </section>\n;\n\nQuery.propTypes = {\n    error:   PropTypes.bool.isRequired,\n    onQuery: PropTypes.func.isRequired,\n    query:   PropTypes.string.isRequired\n};\n\nexport default Query;\n"
  },
  {
    "path": "extension/components/Result.js",
    "content": "import React               from 'react';\nimport { PropTypes }       from 'react';\nimport { TableInspector }  from 'react-inspector';\nimport { ObjectInspector } from 'react-inspector';\n\nimport theme from '../lib/theme';\n\nconst columns = data => {\n    for (let property in data) {\n        return Object.keys(data[property]).filter(column => column !== '_id');\n    }\n};\n\nconst Result = ({ data, mode }) =>\n    <section className=\"pane-scroll\">\n        {mode === 0 && (\n            <ObjectInspector data={data} expandLevel={1} theme={theme} />\n        )}\n\n        {mode === 1 && (\n            <section>\n                <TableInspector data={data} columns={columns(data)} theme={theme} />\n            </section>\n        )}\n\n        {mode === 2 && (\n            <pre>\n                {JSON\n                    .stringify(data, null, 4)\n                    .replace(/[\\u00A0-\\u9999<>\\&]/gim, char => `&#${char.charCodeAt(0)};`)\n                }\n            </pre>\n        )}\n    </section>\n;\n\nResult.propTypes = {\n    data: PropTypes.object.isRequired,\n    mode: PropTypes.number.isRequired\n};\n\nexport default Result;\n"
  },
  {
    "path": "extension/components/Sidebar.js",
    "content": "import React         from 'react';\nimport { PropTypes } from 'react';\n\nimport translations from '../assets/translations/en';\n\nconst Sidebar = ({ collections, onTabOpen }) =>\n    <section className=\"pane-sm sidebar\">\n        <section className=\"nav-group nav-group-sm\">\n            <h1 className=\"nav-group-title\">\n                {translations.ui.collections}\n            </h1>\n\n            {collections.map(collection =>\n                <a key={collection.name} onClick={() => onTabOpen(collection.name)} className=\"nav-group-item\">\n                    <span className=\"pull-left\">{collection.name}</span>\n                    <span className=\"pull-right\">{collection.count}</span>\n                </a>\n            )}\n        </section>\n    </section>\n;\n\nSidebar.propTypes = {\n    collections: PropTypes.array.isRequired,\n    onTabOpen:   PropTypes.func.isRequired\n};\n\nexport default Sidebar;\n"
  },
  {
    "path": "extension/components/Subscriptions.js",
    "content": "import React               from 'react';\nimport { PropTypes }       from 'react';\nimport { ObjectInspector } from 'react-inspector';\n\nimport theme from '../lib/theme';\n\nimport translations from '../assets/translations/en';\n\nconst Subscriptions = ({ data }) =>\n    <section className=\"pane pane-scroll\">\n        <table className=\"table-striped\">\n            <thead>\n                <tr>\n                    <td className=\"text-center\"><b>{translations.subscriptions.name}</b></td>\n                    <td className=\"text-center\"><b>{translations.subscriptions.ready}</b></td>\n                    <td className=\"text-center\"><b>{translations.subscriptions.params}</b></td>\n                </tr>\n            </thead>\n\n            <tbody>\n                {Object.keys(data).sort((a, b) => data[a].name.localeCompare(data[b].name)).map(subscription =>\n                    <tr key={subscription}>\n                        <td>\n                            <code>{data[subscription].name}</code>\n                        </td>\n                        <td className=\"text-center\">\n                            {data[subscription].ready\n                                ? translations.ui.yes\n                                : translations.ui.no\n                            }\n                        </td>\n                        <td>\n                            <ObjectInspector data={data[subscription].params} theme={theme} />\n                        </td>\n                    </tr>\n                )}\n            </tbody>\n        </table>\n    </section>\n;\n\nSubscriptions.propTypes = {\n    data: PropTypes.object.isRequired\n};\n\nexport default Subscriptions;\n"
  },
  {
    "path": "extension/components/Textarea.js",
    "content": "import React, { Component, PropTypes } from 'react';\n\nexport default class Textarea extends Component {\n    static propTypes = {\n        error:    PropTypes.bool.isRequired,\n        onChange: PropTypes.func.isRequired,\n        title:    PropTypes.string.isRequired,\n        value:    PropTypes.string.isRequired\n    };\n\n    state = { value: '' };\n\n    componentDidMount = () =>\n        this.setState({ value: this.props.value })\n    ;\n\n    componentWillReceiveProps = props =>\n        this.setState({ value: props.value })\n    ;\n\n    render = () =>\n        <textarea\n            className={`form-control${this.props.error ? ' form-error' : ''}`}\n            onChange={event => this.onChange(event.currentTarget.value)}\n            rows=\"1\"\n            spellCheck={false}\n            title={this.props.title}\n            value={this.state.value}\n        />\n    ;\n\n    onChange = value =>\n        this.setState({ value }, () => this.props.onChange(value))\n    ;\n}\n"
  },
  {
    "path": "extension/components/Toolbar.js",
    "content": "import React         from 'react';\nimport { PropTypes } from 'react';\n\nimport translations from '../assets/translations/en';\n\nconst Toolbar = ({\n    isHelpView,\n    isMethodsView,\n    isReactive,\n    isSidebarView,\n    isSubscriptionsView,\n    mode,\n    onRefresh,\n    onTabClose,\n    onToggleHelp,\n    onToggleMethods,\n    onToggleMode,\n    onToggleReactivity,\n    onToggleSidebar,\n    onToggleSubscriptions\n}) =>\n    <section className=\"toolbar toolbar-footer\">\n        <section className=\"toolbar-actions\">\n            <section className=\"btn-group\">\n                <button\n                    className=\"btn btn-default btn-mini\"\n                    onClick={() => onToggleSidebar(isSidebarView)}\n                    title={isSidebarView ? translations.sidebar.hide : translations.sidebar.show}\n                >\n                    <i className={`icon icon-${isSidebarView ? 'left' : 'right'}`} />\n                </button>\n\n                <button\n                    className=\"btn btn-default btn-mini\"\n                    onClick={() => onToggleReactivity(isReactive)}\n                    title={isReactive ? translations.reactivity.disable : translations.reactivity.enable}\n                >\n                    <i className={`icon icon-${isReactive ? 'stop' : 'play'}`} />\n                </button>\n\n                <button\n                    className=\"btn btn-default btn-mini\"\n                    onClick={() => onToggleMode(mode)}\n                    title={translations.mode[mode]}\n                >\n                    <i className={`icon icon-${['newspaper', 'menu', 'quote'][mode]}`} />\n                </button>\n\n                <button\n                    className=\"btn btn-default btn-mini\"\n                    onClick={() => onRefresh()}\n                    title={translations.ui.refresh}\n                >\n                    <i className=\"icon icon-arrows-ccw\" />\n                </button>\n\n                <button\n                    className=\"btn btn-default btn-mini\"\n                    onClick={() => onTabClose(-1)}\n                    title={translations.ui.close}\n                >\n                    <i className=\"icon icon-cancel\" />\n                </button>\n            </section>\n\n            <a\n                className=\"btn btn-default btn-mini pull-right\"\n                href=\"https://github.com/radekmie/MiniMongoExplorer\"\n                target=\"_blank\"\n                title={translations.github}\n            >\n                <i className=\"icon icon-github\" />\n            </a>\n\n            <button\n                className={`btn btn-default btn-mini pull-right${isHelpView ? ' active' : ''}`}\n                onClick={() => onToggleHelp(isHelpView)}\n                title={translations.help.toggle}\n            >\n                <i className=\"icon icon-lifebuoy\" />\n            </button>\n\n            <button\n                className={`btn btn-default btn-mini pull-right${isSubscriptionsView ? ' active' : ''}`}\n                onClick={() => onToggleSubscriptions(isSubscriptionsView)}\n                title={translations.subscriptions.toggle}\n            >\n                <i className=\"icon icon-cloud-thunder\" />\n            </button>\n\n            <button\n                className={`btn btn-default btn-mini pull-right${isMethodsView ? ' active' : ''}`}\n                onClick={() => onToggleMethods(isMethodsView)}\n                title={translations.methods.toggle}\n            >\n                <i className=\"icon icon-direction\" />\n            </button>\n        </section>\n    </section>\n;\n\nToolbar.propTypes = {\n    isHelpView:            PropTypes.bool.isRequired,\n    isMethodsView:         PropTypes.bool.isRequired,\n    isReactive:            PropTypes.bool.isRequired,\n    isSidebarView:         PropTypes.bool.isRequired,\n    isSubscriptionsView:   PropTypes.bool.isRequired,\n    mode:                  PropTypes.number.isRequired,\n    onRefresh:             PropTypes.func.isRequired,\n    onTabClose:            PropTypes.func.isRequired,\n    onToggleHelp:          PropTypes.func.isRequired,\n    onToggleMethods:       PropTypes.func.isRequired,\n    onToggleMode:          PropTypes.func.isRequired,\n    onToggleReactivity:    PropTypes.func.isRequired,\n    onToggleSidebar:       PropTypes.func.isRequired,\n    onToggleSubscriptions: PropTypes.func.isRequired\n};\n\nexport default Toolbar;\n"
  },
  {
    "path": "extension/components/View.js",
    "content": "import React         from 'react';\nimport { PropTypes } from 'react';\n\nconst View = ({ children, tab, tabs, onTabClose, onTabSelect }) =>\n    <section className=\"pane pane-flex\">\n        {tabs.length > 0 &&\n            <section className=\"tab-group\">\n                {tabs.map(({ collection, count, id }) =>\n                    <section\n                        className={`tab-item${id === tab ? ' active' : ''}`}\n                        key={id}\n                        onClick={event => (event.button == 1 ? onTabClose : onTabSelect)(id)}\n                    >\n                        <i className=\"icon icon-cancel icon-close-tab\" onClick={event => (event.stopPropagation(), onTabClose(id))} />\n                        {collection}\n\n                        <span>\n                            {count}\n                        </span>\n                    </section>\n                )}\n            </section>\n        }\n\n        {children}\n    </section>\n;\n\nView.propTypes = {\n    children:    PropTypes.node,\n    onTabClose:  PropTypes.func.isRequired,\n    onTabSelect: PropTypes.func.isRequired,\n    tab:         PropTypes.number.isRequired,\n    tabs:        PropTypes.array.isRequired\n};\n\nexport default View;\n"
  },
  {
    "path": "extension/lib/inject.js",
    "content": "import { ADD, CHA, DEL, NEW, REM, SET } from './reduxConstants';\n\nexport default '(' + function (ADD, CHA, DEL, NEW, REM, SET) {\n    var initialize = function () {\n        if (typeof Meteor === 'undefined' && Meteor.connection) {\n            return;\n        }\n\n        var snapshotLocals  = typeof Mongo   !== 'undefined' && new Mongo.Collection(null)._driver.noConnCollections;\n        var snapshotTracker = typeof Tracker !== 'undefined' && Tracker.autorun;\n        var snapshotActions = [\n            {\n                hook: function (run) {\n                    this.observers = [];\n\n                    var collections = Meteor.connection._mongo_livedata_collections;\n                    if (collections) {\n                        Object.keys(collections).forEach(function (collection) {\n                            collections[collection].find({}, { transform: null }).observe({\n                                addedAt:   (doc,    index) => run(collection, ADD, { index: index, doc: doc }),\n                                changedAt: (doc, _, index) => run(collection, CHA, { index: index, doc: doc }),\n                                removedAt: (     _, index) => run(collection, REM, { index: index })\n                            });\n                        });\n                    }\n\n                    if (snapshotLocals) {\n                        Object.keys(snapshotLocals).forEach(function (collection) {\n                            snapshotLocals[collection].find({}, { transform: null }).observe({\n                                addedAt:   (doc,    index) => run(collection, ADD, { index: index, doc: doc }),\n                                changedAt: (doc, _, index) => run(collection, CHA, { index: index, doc: doc }),\n                                removedAt: (     _, index) => run(collection, REM, { index: index })\n                            });\n                        });\n                    }\n                },\n\n                stop: function () {\n                    if (this.observers) {\n                        this.observers.forEach(function (observer) {\n                            observer.stop()\n                        });\n\n                        this.observers = [];\n                    }\n                },\n\n                data: function (collection, action, options) {\n                    if (collection) {\n                        return {\n                            type: action,\n                            payload: {\n                                snapshotTimestamp: Date.now(),\n                                snapshotRequested: false,\n                                snapshot: {\n                                    collection: collection,\n                                    options:    options\n                                }\n                            }\n                        };\n                    } else {\n                        var snapshot = {};\n\n                        var collections = Meteor.connection._mongo_livedata_collections;\n                        if (collections) {\n                            Object.keys(collections).forEach(function (collection) {\n                                var docs = collections[collection]._docs._map;\n\n                                snapshot[collection] = Object\n                                    .keys(docs)\n                                    .reduce((snapshot, _id) => snapshot.concat(docs[_id]), []);\n                            });\n                        }\n\n                        if (snapshotLocals) {\n                            Object.keys(snapshotLocals).forEach(function (collection) {\n                                var docs = snapshotLocals[collection]._docs._map;\n\n                                snapshot[collection] = Object\n                                    .keys(docs)\n                                    .reduce((snapshot, _id) => snapshot.concat(docs[_id]), []);\n                            });\n                        }\n\n                        return {\n                            type: SET,\n                            payload: {\n                                snapshotTimestamp: Date.now(),\n                                snapshotRequested: false,\n                                snapshot: snapshot\n                            }\n                        };\n                    }\n                }\n            },\n            {\n                hook: function (run) {\n                    this.interval = setInterval(run, 10000);\n                },\n\n                stop: function () {\n                    if (this.interval) {\n                        clearInterval(this.interval);\n                        this.interval = undefined;\n                    }\n                },\n\n                data: function () {\n                    var methods = Meteor.connection._methodHandlers;\n                    if (methods) {\n                        methods = Object.keys(methods).sort();\n                    } else {\n                        methods = [];\n                    }\n\n                    return {\n                        type: SET,\n                        payload: {\n                            methods: methods\n                        }\n                    };\n                }\n            },\n            {\n                hook: function (run) {\n                    if (snapshotTracker) {\n                        var subscriptions = Meteor.connection._subscriptions;\n                        if (subscriptions) {\n                            this.computation = Tracker.autorun(function () {\n                                Object.keys(subscriptions).forEach(function (subscription) {\n                                    subscriptions[subscription].readyDeps.depend();\n                                });\n\n                                Tracker.afterFlush(run);\n                            });\n                        }\n                    }\n\n                    this.interval = setInterval(run, 1000);\n                },\n\n                stop: function () {\n                    if (this.computation) {\n                        this.computation.stop();\n                        this.computation = undefined;\n                    }\n\n                    if (this.interval) {\n                        clearInterval(this.interval);\n                        this.interval = undefined;\n                    }\n                },\n\n                data: function () {\n                    var subscriptions = Meteor.connection._subscriptions;\n                    if (subscriptions) {\n                        subscriptions = Object\n                            .keys(subscriptions)\n                            .reduce(function (snapshot, subscription) {\n                                snapshot[subscription] = {\n                                    name:   subscriptions[subscription].name,\n                                    ready:  subscriptions[subscription].ready,\n                                    params: subscriptions[subscription].params\n                                };\n\n                                return snapshot;\n                            }, {});\n                    } else {\n                        subscriptions = {};\n                    }\n\n                    return {\n                        type: SET,\n                        payload: {\n                            subscriptions: subscriptions\n                        }\n                    };\n                }\n            }\n        ];\n\n        var snapshotActionsRun = function (once) {\n            snapshotActions.forEach(function (action) {\n                var send = function () {\n                    var data = action.data.apply(undefined, arguments);\n                    if (data) {\n                        window.postMessage({\n                            process: true,\n                            message: JSON.stringify(data)\n                        }, '*');\n                    }\n                };\n\n                if (!once && action.hook) {\n                    action.hook(send);\n                } else {\n                    send();\n                }\n            });\n        };\n\n        var snapshotActionsStop = function () {\n            snapshotActions.forEach(function (action) {\n                if (action.stop) {\n                    action.stop();\n                }\n            });\n        };\n\n        var onMessage = function (event) {\n            if (event.data) {\n                switch (event.data.type) {\n                    case DEL:\n                        snapshotActionsStop();\n                    break;\n\n                    case NEW:\n                        if (event.data.payload.isReactive) {\n                            snapshotActionsStop();\n                            snapshotActionsRun();\n                        }\n\n                        snapshotActionsRun(true);\n                    break;\n\n                    case SET:\n                        event.data.payload.isReactive === true  && snapshotActionsRun();\n                        event.data.payload.isReactive === false && snapshotActionsStop();\n                        event.data.payload.snapshotRequested && snapshotActionsRun(true);\n                    break;\n                }\n            }\n        };\n\n        window.addEventListener('message', onMessage, false);\n    };\n\n    if (document.readyState === 'complete') {\n        initialize();\n    } else {\n        document.addEventListener('DOMContentLoaded', initialize, false);\n    }\n} + `)('${ADD}', '${CHA}', '${DEL}', '${NEW}', '${REM}', '${SET}')`;\n"
  },
  {
    "path": "extension/lib/injectParse.js",
    "content": "export const ISODate = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*))(?:Z|(\\+|-)([\\d|:]*))?$/;\nexport default string =>\n    JSON.parse(string, (key, value) =>\n        typeof value === 'string'\n            ? ISODate.test(value)\n                ? new Date(value)\n                : value\n            : value\n    )\n;\n"
  },
  {
    "path": "extension/lib/ready.js",
    "content": "export default '(' + function () {\n    return document.readyState === 'complete';\n} + ')()';\n"
  },
  {
    "path": "extension/lib/reduxConstants.js",
    "content": "export const ADD = 'ADD';\nexport const CHA = 'CHA';\nexport const DEL = 'DEL';\nexport const NEW = 'NEW';\nexport const REM = 'REM';\nexport const SET = 'SET';\n"
  },
  {
    "path": "extension/lib/reduxReducer.js",
    "content": "import { ADD, CHA, DEL, NEW, REM, SET } from './reduxConstants';\n\nexport default (state = {}, { type, payload }) => {\n    let collection;\n\n    switch (type) {\n        case DEL: return {};\n        case NEW: return { ...payload, tabs: [] };\n        case SET: return { ...state, ...payload };\n\n        case ADD:\n            collection = state.snapshot[payload.snapshot.collection].slice();\n            collection[payload.snapshot.options.index] = payload.snapshot.options.doc;\n\n            return { ...state, ...payload, snapshot: { ...state.snapshot, [payload.snapshot.collection]: collection } };\n\n        case CHA:\n            collection = state.snapshot[payload.snapshot.collection].slice();\n            collection[payload.snapshot.options.index] = payload.snapshot.options.doc;\n\n            return { ...state, ...payload, snapshot: { ...state.snapshot, [payload.snapshot.collection]: collection } };\n\n        case REM:\n            collection = state.snapshot[payload.snapshot.collection].slice();\n            collection.splice(payload.snapshot.options.index, 1);\n\n            return { ...state, ...payload, snapshot: { ...state.snapshot, [payload.snapshot.collection]: collection } };\n\n        default: return state;\n    }\n};\n"
  },
  {
    "path": "extension/lib/reduxState.js",
    "content": "export default () => ({\n    tab:  -1,\n    tabs: [],\n\n    isHelpView: true,\n    isMethodsView: false,\n    isReactive: true,\n    isSidebarView: true,\n    isSubscriptionsView: false,\n\n    mode: 0,\n\n    methods: [],\n\n    snapshot: {},\n    snapshotRequested: false,\n    snapshotTimestamp: Date.now(),\n\n    subscriptions: {}\n});\n"
  },
  {
    "path": "extension/lib/reduxStore.js",
    "content": "import { createStore } from 'redux';\n\nimport reducer from './reduxReducer';\n\nexport default createStore(reducer);\n"
  },
  {
    "path": "extension/lib/safeDocumentMatcher.js",
    "content": "import DocumentMatcher from 'marsdb/dist/DocumentMatcher';\n\nconst defaultAction = () => true;\n\nexport default query => {\n    try {\n        let parsed = eval(`(${query})`);\n        if (parsed && parsed.query) {\n            const helper = new DocumentMatcher(parsed.query);\n            const action = doc => helper.documentMatches(doc).result;\n\n            return {action, error: false};\n        }\n\n        return {action: defaultAction, error: false};\n    } catch (_) {\n        return {action: defaultAction, error: true};\n    }\n};\n"
  },
  {
    "path": "extension/lib/safeDocumentProjector.js",
    "content": "import DocumentProjector from 'marsdb/dist/DocumentProjector';\n\nconst defaultAction = doc => Object.keys(doc).sort().reduce((object, key) => ({ ...object, [key]: doc[key] }), {});\n\nexport default query => {\n    try {\n        let parsed = eval(`(${query})`);\n        if (parsed && parsed.fields) {\n            const helper = new DocumentProjector(parsed.fields);\n            const action = doc => defaultAction(helper.project(doc));\n\n            return {action, error: false};\n        }\n\n        return {action: defaultAction, error: false};\n    } catch (_) {\n        return {action: defaultAction, error: true};\n    }\n};\n"
  },
  {
    "path": "extension/lib/safeDocumentSorter.js",
    "content": "import DocumentSorter from 'marsdb/dist/DocumentSorter';\n\nconst defaultAction = () => 0;\n\nexport default query => {\n    try {\n        let parsed = eval(`(${query})`);\n        if (parsed && parsed.sort) {\n            const helper = new DocumentSorter(parsed.sort);\n            const action = helper.getComparator()\n\n            return {action, error: false};\n        }\n\n        return {action: defaultAction, error: false};\n    } catch (_) {\n        return {action: defaultAction, error: true};\n    }\n};\n"
  },
  {
    "path": "extension/lib/theme.js",
    "content": "import { chromeLight } from 'react-inspector';\n\nexport default {\n    ...chromeLight,\n    BASE_BACKGROUND_COLOR: 'transparent'\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"MiniMongoExplorer\",\n  \"version\": \"1.3.1\",\n  \"private\": true,\n  \"contributors\": [\n    {\n      \"name\": \"Radosław Miernik\",\n      \"email\": \"<radekmie@gmail.com>\"\n    }\n  ],\n  \"scripts\": {\n    \"build:chrome\": \"./node_modules/.bin/webpack --config webpack.config.chrome.babel.js -p\",\n    \"watch:chrome\": \"./node_modules/.bin/webpack --config webpack.config.chrome.babel.js --watch\"\n  },\n  \"devDependencies\": {\n    \"babel-core\": \"6.24.1\",\n    \"babel-loader\": \"7.0.0\",\n    \"babel-preset-env\": \"1.5.1\",\n    \"babel-preset-react\": \"6.24.1\",\n    \"babel-preset-stage-0\": \"6.24.1\",\n    \"css-loader\": \"0.28.4\",\n    \"file-loader\": \"0.11.1\",\n    \"html-webpack-plugin\": \"2.28.0\",\n    \"marsdb\": \"0.6.11\",\n    \"react\": \"15.5.4\",\n    \"react-dom\": \"15.5.4\",\n    \"react-inspector\": \"2.0.0\",\n    \"redux\": \"3.6.0\",\n    \"style-loader\": \"0.18.1\",\n    \"url-loader\": \"0.5.8\",\n    \"webpack\": \"2.6.1\"\n  },\n  \"babel\": {\n    \"presets\": [\n      [\n        \"env\",\n        {\n          \"targets\": {\n            \"chrome\": 26\n          }\n        }\n      ],\n      \"react\",\n      \"stage-0\"\n    ]\n  }\n}\n"
  },
  {
    "path": "webpack.config.babel.js",
    "content": "import webpack    from 'webpack';\nimport { join }   from 'path';\nimport HTMLPlugin from 'html-webpack-plugin';\n\nexport default ({ directory, entry, pages = [] }) => ({\n    entry,\n\n    output: { path: join(__dirname, 'build', directory), filename: '[name].js' },\n    module: {\n        loaders: [\n            { exclude: /node_modules/, loader: 'url-loader',              test: /\\.woff$/ },\n            { exclude: /node_modules/, loader: 'babel-loader',            test: /\\.js$/ },\n            { exclude: /node_modules/, loader: 'style-loader!css-loader', test: /\\.css$/ }\n        ]\n    },\n\n    plugins: [\n        new webpack.DefinePlugin({\n            process: {\n                env: {\n                    NODE_ENV: JSON.stringify('production')\n                }\n            }\n        }),\n        new webpack.optimize.UglifyJsPlugin({\n            comments: false,\n            compress: {\n                warnings: false\n            },\n            sourceMap: false\n        }),\n        new webpack.optimize.OccurrenceOrderPlugin(),\n\n        ...pages.map(chunk => new HTMLPlugin({\n            title: null,\n\n            chunks:     [chunk],\n            filename: `${chunk}.html`,\n\n            minify: {\n                collapseWhitespace:  true,\n                removeEmptyElements: true\n            }\n        }))\n    ]\n});\n"
  },
  {
    "path": "webpack.config.chrome.babel.js",
    "content": "import config from './webpack.config.babel';\n\nexport default config({\n    directory: 'chrome',\n\n    entry: {\n        content:    './chrome/content.js',\n        devtools:   './chrome/devtools.js',\n        background: './chrome/background.js',\n\n        panel: [\n            './chrome/panel.js',\n            './chrome/panel.css'\n        ]\n    },\n\n    pages: [\n        'panel',\n        'devtools'\n    ]\n});\n"
  }
]