From b1f4582607a005057496dc251a6318a533a720e2 Mon Sep 17 00:00:00 2001 From: Paul Varache Date: Tue, 13 Feb 2018 15:37:25 +0000 Subject: [PATCH] POC --- .eslintrc.json | 6 + .gitignore | 1 + README.md | 110 +- app/main.js | 52 + app/preload.js | 1 + app/res/icon_180.png | Bin 0 -> 4059 bytes app/src/index.html | 13 + app/src/main.css | 3 + lib/about/about.css | 63 + lib/about/about.html | 12 + lib/about/index.js | 92 ++ lib/about/preload.js | 48 + lib/file-server.js | 8 + lib/index.js | 7 + lib/menu/index.js | 162 ++ lib/shell/index.js | 125 ++ lib/shell/preload.js | 38 + lib/spa-file-protocol-handler.js | 16 + lib/titlebar/events.js | 9 + lib/titlebar/index.js | 38 + lib/titlebar/preload.js | 151 ++ lib/titlebar/titlebar.html | 167 +++ package-lock.json | 2415 ++++++++++++++++++++++++++++++ package.json | 22 + res/classic-menu.png | Bin 0 -> 53788 bytes res/classic.png | Bin 0 -> 61596 bytes res/uwp-menu.png | Bin 0 -> 35388 bytes res/uwp.png | Bin 0 -> 42502 bytes 28 files changed, 3557 insertions(+), 2 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 app/main.js create mode 100644 app/preload.js create mode 100644 app/res/icon_180.png create mode 100644 app/src/index.html create mode 100644 app/src/main.css create mode 100644 lib/about/about.css create mode 100644 lib/about/about.html create mode 100644 lib/about/index.js create mode 100644 lib/about/preload.js create mode 100644 lib/file-server.js create mode 100644 lib/index.js create mode 100644 lib/menu/index.js create mode 100644 lib/shell/index.js create mode 100644 lib/shell/preload.js create mode 100644 lib/spa-file-protocol-handler.js create mode 100644 lib/titlebar/events.js create mode 100644 lib/titlebar/index.js create mode 100644 lib/titlebar/preload.js create mode 100644 lib/titlebar/titlebar.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 res/classic-menu.png create mode 100644 res/classic.png create mode 100644 res/uwp-menu.png create mode 100644 res/uwp.png diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..929fa51 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "kano", + "rules": { + "no-param-reassign": ["error", { "props": false }] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md index fe82025..59580d9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,108 @@ -# kano-desktop-shell -Abstraction layer on top of electron to provide common features in a shell ready to use +# Kano Desktop Shell + +Abstraction layer on top of electron to provide common features in a shell ready to use. + +## Features + + - Static SPA content delivery (Through registered custom protocol) + - Window state managment (electron-window-state) + - UWP style titlebar for windows with dropdown menu + - Default menu items (clipboard, selection, help) + - About page (Help/About or AppName/About on macOS) + - Developer mode option (5 clicks on icon in the about page) + +### Future Features + + - Update checking and menu options + +## Style + +### Windows + +UWP style Titlebar + +![Classic](res/uwp.png?raw=true) +![Classic](res/uwp-menu.png?raw=true) + +Classic style titlebar (Windows 10) + +![Classic](res/classic.png?raw=true) +![Classic](res/classic-menu.png?raw=true) + +## API + +`Shell`: Use this class to create a new app with a browser window serving content from a local directory + +options: + - `root`, (required) Root of the local directory you want to serve in the browser window. + - `scheme`, Scheme that will be used in the server protocol (Default: `shell`) + - `width`, Width of the main window (Default: `800`). + - `height`, Height of the main window (Default: `600`). + - `preload`, path to a preload script (Default: none). + - `titlebar`, Enables the titlebar (Default: `true`). + - `uwpTitlebar`, Enables the UWP style titlebar for windows (Default: `true`). + - `devMode`, Enables developer mode (DevTool options) (Default: `false`). + - `menuTransform`, Function that will receive the shell menu and should return a modified version of it to add custom menu and menu items. + - `windowOptions`, Any option that will be passed down to electron's `BrowserWindow` constructor. + +Methods: + + - `updateMenu()`: Triggers an update of the menu bar. + - `isDevMode()`: Return a boolean. `true` if in developer mode `false` if not. + +## Example + +```js +const { app } = require('electron'); +const { Shell, Shellmenu } = require('kano-desktop-shell'); +const path = require('path'); + +const CONTENT_SCHEME = 'my-custom-app'; +// Location of the static content to serve. This will be served through a custom protocol +const CONTENT_ROOT = path.join(__dirname, './src'); + +// Custom menu Item added +ShellItem.addItem('my-item', { label: 'My Menu Item', click() { console.log('My Menu Item') } }); + +// Create new Shell with custom options +// Includes automatic window state managment and UWP style titlebar for windows +// Custom preload as module supported +const shell = new Shell({ + root: CONTENT_ROOT, + scheme: CONTENT_SCHEME, + // Can provide custom width and height + width: 1440, + height: 900, + // Supports preload script + preload: path.join(__dirname, 'preload.js'), + titlebar: true, + // Enable UWP style titlebar + uwpTitlebar: true, + devMode: false, + menuTransform(menu) { + const submenu = [ShellMenu.createMenuItem('my-item')]; + // Can update when dev mode changes + if (shell.isDevMode()) { + submenu.push(ShellMenu.createMenuItem('separator')); + // Can add custom runtime generated menu items + submenu.push({ label: 'Dev option' }); + } + // Inject in list of menus + menu.splice(1, 0, { + label: 'Custom Menu', + submenu, + }); + return menu; + }, + // Set custom window options through this object + windowOptions: { + icon: path.join(__dirname, 'res/icon_180.png'), + }, +}); + +app.on('ready', () => { + shell.createWindow(); + // The main window is accessible through properties + console.log(shell.window); +}); +``` \ No newline at end of file diff --git a/app/main.js b/app/main.js new file mode 100644 index 0000000..ce148ab --- /dev/null +++ b/app/main.js @@ -0,0 +1,52 @@ +const { app } = require('electron'); +const { Shell, ShellMenu } = require('../lib'); +const path = require('path'); + +const CONTENT_SCHEME = 'kano-shell'; +const CONTENT_ROOT = path.join(__dirname, './src'); + +// Custom menu Item added +ShellMenu.addItem('my-item', { label: 'My Menu Item', click() { console.log('My Menu Item'); } }); + +app.setName('My app'); + +// Create new Shell with custom options +// Includes automatic window state managment and UWP style titlebar for windows +// Custom preload as module supported +const shell = new Shell({ + root: CONTENT_ROOT, + scheme: CONTENT_SCHEME, + // Can provide custom width and height + width: 1440, + height: 900, + // Supports preload script + preload: path.join(__dirname, 'preload.js'), + titlebar: true, + // Enable UWP style titlebar + uwpTitlebar: true, + devMode: false, + menuTransform(menu) { + const submenu = [ShellMenu.createMenuItem('my-item')]; + // Can update when dev mode changes + if (shell.isDevMode()) { + submenu.push(ShellMenu.createMenuItem('separator')); + // Can add custom runtime generated menu items + submenu.push({ label: 'Dev option' }); + } + // Inject in list of menus + menu.splice(1, 0, { + label: 'Custom Menu', + submenu, + }); + return menu; + }, + windowOptions: { + icon: path.join(__dirname, 'res/icon_180.png'), + }, +}); + +app.on('ready', () => { + shell.createWindow(); + // The main window is accessible through properties + console.log(shell.window); +}); diff --git a/app/preload.js b/app/preload.js new file mode 100644 index 0000000..a956582 --- /dev/null +++ b/app/preload.js @@ -0,0 +1 @@ +console.log('CHROMIUM CONTEXT'); diff --git a/app/res/icon_180.png b/app/res/icon_180.png new file mode 100644 index 0000000000000000000000000000000000000000..1218e51ccc66506ce5bd19ca76c213e1921be1f8 GIT binary patch literal 4059 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 N002ovPDHLkV1h&_oQePd literal 0 HcmV?d00001 diff --git a/app/src/index.html b/app/src/index.html new file mode 100644 index 0000000..5ca8e1d --- /dev/null +++ b/app/src/index.html @@ -0,0 +1,13 @@ + + + + + + + Kano Desktop Shell + + + + + + \ No newline at end of file diff --git a/app/src/main.css b/app/src/main.css new file mode 100644 index 0000000..b8e98c2 --- /dev/null +++ b/app/src/main.css @@ -0,0 +1,3 @@ +html, body { + margin: 0; +} \ No newline at end of file diff --git a/lib/about/about.css b/lib/about/about.css new file mode 100644 index 0000000..5f2a9ca --- /dev/null +++ b/lib/about/about.css @@ -0,0 +1,63 @@ +body, +html { + width: 100%; + height: 100%; + -webkit-user-select: none; + user-select: none; + -webkit-app-region: drag; +} + +body { + margin: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + color: #333; + background-color: #eee; + font-size: 12px; + font-family: 'Helvetica', 'Arial', 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'メイリオ', Meiryo, 'MS Pゴシック', 'MS PGothic', sans-serif; +} + +.logo { + width: 200px; + -webkit-user-select: none; + user-select: none; +} + +.title, +.copyright, +.description { + margin: 0.2em; +} + +.clickable { + cursor: pointer; +} + +.description { + margin-bottom: 1em; + text-align: center; +} + +.versions { + border-collapse: collapse; + margin-top: 1em; +} + +.copyright, +.versions { + color: #999; +} + +.link { + cursor: pointer; + color: #80a0c2; +} + +.bug-report-link { + -webkit-app-region: no-drag; + position: absolute; + right: 0.5em; + bottom: 0.5em; +} \ No newline at end of file diff --git a/lib/about/about.html b/lib/about/about.html new file mode 100644 index 0000000..0608a85 --- /dev/null +++ b/lib/about/about.html @@ -0,0 +1,12 @@ + + + + + + + About + + + + + \ No newline at end of file diff --git a/lib/about/index.js b/lib/about/index.js new file mode 100644 index 0000000..54f1c93 --- /dev/null +++ b/lib/about/index.js @@ -0,0 +1,92 @@ +const { EventEmitter } = require('events'); +const path = require('path'); +const { + BrowserWindow, + remote, + shell, + ipcMain, +} = require('electron'); + +class About extends EventEmitter { + constructor(opts = {}) { + super(); + this.window = null; + + this.indexPage = `file://${path.join(__dirname, 'about.html')}`; + + this.winOptions = Object.assign( + { + width: 400, + height: 400, + useContentSize: true, + titleBarStyle: 'hidden-inset', + show: !opts.adjustWindowSize, + icon: opts.iconPath, + }, + opts.winOptions || {}, + ); + + this.winOptions.webPreferences = Object.assign({}, this.winOptions.webPreferences || {}, { + nodeIntegration: false, + preload: path.join(__dirname, 'preload.js'), + }); + + this.options = opts; + } + openWindow() { + if (this.window !== null) { + this.window.focus(); + return this.window; + } + + ipcMain.on('about:enable-dev-mode', (event) => { + if (event.sender === this.window.webContents) { + this.emit('enable-dev-mode'); + } + }); + + this.window = new (BrowserWindow || remote.BrowserWindow)(this.winOptions); + + this.window.aboutOptions = this.options; + + this.window.once('closed', () => { + this.window = null; + }); + this.window.loadURL(this.indexPage); + + this.window.webContents.on('will-navigate', (e, url) => { + e.preventDefault(); + shell.openExternal(url); + }); + this.window.webContents.on('new-window', (e, url) => { + e.preventDefault(); + shell.openExternal(url); + }); + + this.window.webContents.once('dom-ready', () => { + if (this.options.openDevtools) { + if (process.versions.electron >= '1.4') { + this.window.webContents.openDevTools({ mode: 'detach' }); + } else { + this.window.webContents.openDevTools(); + } + } + }); + + this.window.once('ready-to-show', () => { + this.window.show(); + }); + + this.window.setMenu(null); + + return this.window; + } + close() { + if (!this.window) { + return; + } + this.window.close(); + } +} + +module.exports = About; diff --git a/lib/about/preload.js b/lib/about/preload.js new file mode 100644 index 0000000..eddfb04 --- /dev/null +++ b/lib/about/preload.js @@ -0,0 +1,48 @@ +const { remote, ipcRenderer } = require('electron'); + +const currentWindow = remote.getCurrentWindow(); +const { aboutOptions } = currentWindow; +const { versions } = process; + +let clicks = 0; +let { devMode } = aboutOptions; + +function updateUI() { + const template = ` + + +

${remote.app.getName()} ${remote.app.getVersion()}

+

${aboutOptions.description || ''}

+ +
${devMode ? 'Developer Mode enabled' : ''}
+ + ${['electron', 'chrome', 'node', 'v8'].map(key => ``).join('')} +
${key}${versions[key]}
+
+ +
+ +`; + document.body.innerHTML = template; +} + +function enableDevMode() { + devMode = true; + ipcRenderer.send('about:enable-dev-mode'); + updateUI(); +} + +function onIconClick() { + clicks += 1; + if (clicks >= 5) { + enableDevMode(); + } +} + +window.addEventListener('DOMContentLoaded', () => { + updateUI(); + const icon = document.getElementById('app-icon'); + icon.addEventListener('click', onIconClick); +}); diff --git a/lib/file-server.js b/lib/file-server.js new file mode 100644 index 0000000..1735b66 --- /dev/null +++ b/lib/file-server.js @@ -0,0 +1,8 @@ +const { protocol } = require('electron'); +const spaHandler = require('./spa-file-protocol-handler'); + +function registerProtocol(scheme, root, handler = () => {}) { + protocol.registerFileProtocol(scheme, spaHandler(root), handler); +} + +module.exports = { registerProtocol }; diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..efbace4 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,7 @@ +const Shell = require('./shell'); +const ShellMenu = require('./menu'); + +module.exports = { + Shell, + ShellMenu, +}; diff --git a/lib/menu/index.js b/lib/menu/index.js new file mode 100644 index 0000000..4540e61 --- /dev/null +++ b/lib/menu/index.js @@ -0,0 +1,162 @@ +const { app, Menu } = require('electron'); + +const ITEMS = { + about: { + label: 'About', + }, + undo: { + label: 'Undo', + accelerator: 'CmdOrCtrl+Z', + selector: 'undo:', + }, + redo: { + label: 'Redo', + accelerator: 'Shift+CmdOrCtrl+Z', + selector: 'redo:', + }, + selectAll: { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + selector: 'selectAll:', + }, + copy: { + label: 'Copy', + accelerator: 'CmdOrCtrl+C', + selector: 'copy:', + }, + cut: { + label: 'Cut', + accelerator: 'CmdOrCtrl+X', + selector: 'cut:', + }, + paste: { + label: 'Paste', + accelerator: 'CmdOrCtrl+V', + selector: 'paste:', + }, + separator: { + type: 'separator', + }, + reload: { role: 'reload' }, + forcereload: { role: 'forcereload' }, + toggledevtools: { role: 'toggledevtools' }, +}; + +class ShellMenu { + constructor(window, about, options) { + this.options = Object.assign({ + transform(menu) { + return menu; + }, + }, options); + this.window = window; + + /* Menus for context menus */ + + this.selectionMenuTemplate = [ + ShellMenu.createMenuItem('copy'), + ShellMenu.createMenuItem('selectAll'), + ]; + + this.editMenuTemplate = [ + ShellMenu.createMenuItem('undo'), + ShellMenu.createMenuItem('redo'), + ShellMenu.createMenuItem('separator'), + ShellMenu.createMenuItem('cut'), + ShellMenu.createMenuItem('copy'), + ShellMenu.createMenuItem('paste'), + ShellMenu.createMenuItem('selectAll'), + ]; + + this.aboutItem = ShellMenu.createMenuItem('about'); + + this.aboutItem.click = () => { + about.openWindow(); + }; + + this.window.webContents.on('context-menu', (e, props) => { + const { selectionText, isEditable } = props; + if (isEditable) { + this.inputMenu.popup(this.window); + } else if (selectionText && selectionText.trim() !== '') { + this.selectionMenu.popup(this.window); + } + }); + } + + static createMenuItem(name) { + return Object.assign({}, ITEMS[name]); + } + + static addItem(id, item) { + ITEMS[id] = item; + } + + build(debug) { + const menuTemplate = []; + this.selectionMenu = Menu.buildFromTemplate(this.selectionMenuTemplate); + this.inputMenu = Menu.buildFromTemplate(this.editMenuTemplate); + + const edit = { + label: 'Edit', + submenu: this.editMenuTemplate, + }; + + menuTemplate.push(edit); + + const view = { + label: 'View', + submenu: [], + }; + + if (debug) { + if (view.submenu.length > 0) { + view.submenu.push(ShellMenu.createMenuItem('separator')); + } + view.submenu = view.submenu.concat([ + ShellMenu.createMenuItem('reload'), + ShellMenu.createMenuItem('forcereload'), + ShellMenu.createMenuItem('toggledevtools'), + ]); + } + + if (view.submenu.length > 0) { + menuTemplate.push(view); + } + + const help = { + label: 'Help', + submenu: [], + }; + + if (process.platform !== 'darwin') { + help.submenu.push(this.aboutItem); + } + + if (help.submenu.length > 0) { + menuTemplate.push(help); + } + // The `app name` menu is specific to MacOS windowing system paradigm + if (process.platform === 'darwin') { + const appName = { + label: app.getName(), + submenu: [ + this.aboutItem, + ShellMenu.createMenuItem('reload'), + { role: 'services', submenu: [] }, + ShellMenu.createMenuItem('reload'), + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, + ShellMenu.createMenuItem('reload'), + { role: 'quit' }, + ], + }; + menuTemplate.unshift(appName); + } + const { transform } = this.options; + this.menu = Menu.buildFromTemplate(transform(menuTemplate)); + } +} + +module.exports = ShellMenu; diff --git a/lib/shell/index.js b/lib/shell/index.js new file mode 100644 index 0000000..6f27e9c --- /dev/null +++ b/lib/shell/index.js @@ -0,0 +1,125 @@ +const { + BrowserWindow, + protocol, + app, +} = require('electron'); +const appServer = require('../file-server'); +const Titlebar = require('../titlebar'); +const About = require('../about'); +const MenuGenerator = require('../menu'); +const path = require('path'); +const windowStateKeeper = require('electron-window-state'); + +const defaultOptions = { + scheme: 'shell', + titlebar: true, + uwpTitlebar: true, + width: 800, + height: 600, + devMode: false, + windowOptions: { + show: false, + autoHideMenuBar: true, + }, +}; + +class Shell { + constructor(opts) { + this.options = Object.assign({}, defaultOptions, opts); + if (!this.options.root) { + throw new Error('Missing root option'); + } + protocol.registerStandardSchemes([this.options.scheme], { secure: true }); + app.on('ready', () => { + appServer.registerProtocol(this.options.scheme, this.options.root); + }); + this.about = new About({ + iconPath: this.options.windowOptions.icon, + openDevtools: this.options.devMode, + }); + this.about.on('enable-dev-mode', () => { + this.options.devMode = true; + this.updateMenu(); + }); + } + createWindow() { + this.windowState = windowStateKeeper({ + defaultWidth: this.options.width, + defaultHeight: this.options.height, + }); + this.windowOptions = Object.assign({}, { + x: this.windowState.x, + y: this.windowState.y, + width: this.windowState.width, + height: this.windowState.height, + frame: this.options.titlebar && (!this.options.uwpTitlebar || !Shell.isWin()), + webPreferences: { + nodeIntegration: false, + preload: path.join(__dirname, 'preload.js'), + }, + }, this.options.windowOptions); + this.window = new BrowserWindow(this.windowOptions); + + this.menuGenerator = new MenuGenerator( + this.window, + this.about, + { transform: this.options.menuTransform }, + ); + + this.updateMenu(); + + this.window.shell = this; + + this.window.on('closed', () => { + this.about.close(); + this.window = null; + }); + + this.window.once('ready-to-show', () => { + this.window.show(); + }); + + // Quit when all windows are closed. + app.on('window-all-closed', () => { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } + }); + + app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (this.window === null) { + this.createWindow(); + } + }); + + if (Shell.isWin() && this.options.titlebar && this.options.uwpTitlebar) { + Titlebar.setup(this.window); + } + + this.window.loadURL(`${this.options.scheme}://index`); + + this.windowState.manage(this.window); + } + + updateMenu() { + this.menuGenerator.build(this.options.devMode); + + this.menu = this.menuGenerator.menu; + + this.window.setMenu(this.menu); + } + + static isWin() { + return process.platform !== 'darwin'; + } + + isDevMode() { + return this.options.devMode; + } +} + +module.exports = Shell; diff --git a/lib/shell/preload.js b/lib/shell/preload.js new file mode 100644 index 0000000..636b8ef --- /dev/null +++ b/lib/shell/preload.js @@ -0,0 +1,38 @@ +/* eslint global-require: "off" */ +/* eslint import/no-dynamic-require: "off" */ +const { remote } = require('electron'); + +const currentWindow = remote.getCurrentWindow(); +const { shell } = currentWindow; + +function setupTitlebar() { + // Dynamically require this one on windows + const Titlebar = require('../titlebar/preload'); + const titlebar = new Titlebar(); + + titlebar.element.style.background = '#C9C3C2'; + titlebar.element.setAttribute('draggable', ''); + + window.addEventListener('DOMContentLoaded', () => { + titlebar.setup(); + }); + if (!shell.window.isMenuBarVisible()) { + titlebar.noMenu = true; + } +} + +function loadPreloadScript() { + if (!shell) { + return; + } + + if (shell.options.preload) { + require(shell.options.preload); + } +} + +if (shell.constructor.isWin() && shell.options.uwpTitlebar && shell.options.titlebar) { + setupTitlebar(); +} + +loadPreloadScript(); diff --git a/lib/spa-file-protocol-handler.js b/lib/spa-file-protocol-handler.js new file mode 100644 index 0000000..d037cd4 --- /dev/null +++ b/lib/spa-file-protocol-handler.js @@ -0,0 +1,16 @@ +const url = require('url'); +const path = require('path'); + +module.exports = function getHandler(root, fallback = 'index.html') { + return (req, callback) => { + // Parse the url to extract the pathname + const u = url.parse(req.url); + const parts = u.pathname.split('/'); + // If the path contains an extension, it is a request for a file + const isFile = parts[parts.length - 1].indexOf('.') !== -1; + // Replace the path with the fallback file if the request is not for a file + const filename = isFile ? u.pathname : fallback; + const file = path.normalize(`${root}/${filename}`); + callback({ path: file }); + }; +}; diff --git a/lib/titlebar/events.js b/lib/titlebar/events.js new file mode 100644 index 0000000..4a0035f --- /dev/null +++ b/lib/titlebar/events.js @@ -0,0 +1,9 @@ +const PROXY_EVENTS = [ + 'close', + 'maximize', + 'un-maximize', + 'minimize', + 'menu', +]; + +module.exports = PROXY_EVENTS; diff --git a/lib/titlebar/index.js b/lib/titlebar/index.js new file mode 100644 index 0000000..3069f84 --- /dev/null +++ b/lib/titlebar/index.js @@ -0,0 +1,38 @@ +const EVENTS = require('./events'); +const { ipcMain } = require('electron'); + +const actions = { + close(window) { + window.close(); + }, + maximize(window) { + window.maximize(); + }, + minimize(window) { + window.minimize(); + }, + 'un-maximize': (window) => { + window.unmaximize(); + }, + menu(window) { + if (window.shell) { + window.shell.menu.popup(window); + } + }, +}; + +const Titlebar = { + setup(window) { + EVENTS.forEach((eventName) => { + ipcMain.on(eventName, (event) => { + if (event.sender === window.webContents) { + actions[eventName](window); + } + }); + }); + window.on('maximize', () => window.webContents.send('maximize')); + window.on('unmaximize', () => window.webContents.send('unmaximize')); + }, +}; + +module.exports = Titlebar; diff --git a/lib/titlebar/preload.js b/lib/titlebar/preload.js new file mode 100644 index 0000000..a58d368 --- /dev/null +++ b/lib/titlebar/preload.js @@ -0,0 +1,151 @@ +const fs = require('fs'); +const path = require('path'); +const { ipcRenderer } = require('electron'); + +const EVENTS = require('./events'); + +const TEMPLATE_STRING = fs.readFileSync(path.join(__dirname, 'titlebar.html'), 'utf-8'); + +const MAXIMIZED_ATTRIBUTE = 'maximized'; +const MENU_ATTRIBUTE = 'no-menu'; + +class WindowsTitlebar extends HTMLElement { + constructor() { + super(); + this.root = this.attachShadow({ mode: 'open' }); + this.root.innerHTML = TEMPLATE_STRING; + + this.minimizeButton = this.root.querySelector('.titlebar-minimize'); + this.resizeButton = this.root.querySelector('.titlebar-resize'); + this.closeButton = this.root.querySelector('.titlebar-close'); + this.titleContainer = this.root.querySelector('.titlebar-title'); + this.menu = this.root.querySelector('.titlebar-menu'); + + this.updateMenuIcon(); + + this.addListeners(); + } + + addListeners() { + this.addEventListener('dblclick', event => this.onDoubleclick(event)); + this.minimizeButton.addEventListener('click', event => this.clickMinimize(event)); + this.resizeButton.addEventListener('click', event => this.clickResize(event)); + this.closeButton.addEventListener('click', event => this.clickClose(event)); + this.menu.addEventListener('click', event => this.clickMenu(event)); + + ipcRenderer.on('maximize', e => this.onMaximized(e)); + ipcRenderer.on('unmaximize', e => this.onUnMaximized(e)); + } + + updateMenuIcon() { + if (this.noMenu) { + this.menu.setAttribute('hidden', ''); + } else { + this.menu.removeAttribute('hidden'); + } + } + + setup() { + this.titleElement = document.querySelector('title'); + + if (!this.titleElement) { + return; + } + + this.mutationObserver = new MutationObserver(() => { + this.updateTitle(); + }).observe( + this.titleElement, + { subtree: true, characterData: true }, + ); + this.updateTitle(); + } + + updateTitle() { + if (!this.titleElement) { + return; + } + const title = this.titleElement.textContent; + this.titleContainer.textContent = title; + } + + onMaximized() { + this.classList.add('fullscreen'); + } + + onUnMaximized() { + this.classList.remove('fullscreen'); + } + + clickMenu() { + this.dispatchEvent(new CustomEvent('menu')); + } + + clickClose() { + this.dispatchEvent(new CustomEvent('close')); + } + + clickMinimize() { + this.dispatchEvent(new CustomEvent('minimize')); + } + + clickResize() { + if (this.maximized) { + this.dispatchEvent(new CustomEvent('un-maximize')); + } else { + this.dispatchEvent(new CustomEvent('maximize')); + } + + this.maximized = !this.maximized; + } + + onDoubleclick(event) { + if (!(this.minimizeButton.contains(event.target) + || this.resizeButton.contains(event.target) + || this.closeButton.contains(event.target))) { + this.clickResize(event); + } + } + + get maximized() { + return this.hasAttribute(MAXIMIZED_ATTRIBUTE); + } + + set maximized(value) { + if (!value) { + this.removeAttribute(MAXIMIZED_ATTRIBUTE); + } else { + this.setAttribute(MAXIMIZED_ATTRIBUTE, ''); + } + } + + get noMenu() { + return this.hasAttribute(MENU_ATTRIBUTE); + } + + set noMenu(value) { + if (!value) { + this.removeAttribute(MENU_ATTRIBUTE); + } else { + this.setAttribute(MENU_ATTRIBUTE, ''); + } + this.updateMenuIcon(); + } +} + +customElements.define('windows-titlebar', WindowsTitlebar); + +class Titlebar { + constructor() { + this.element = document.createElement('windows-titlebar'); + } + setup(container = document.body) { + EVENTS.forEach(eventName => ( + this.element.addEventListener(eventName, () => ipcRenderer.send(eventName)) + )); + container.appendChild(this.element); + this.element.setup(); + } +} + +module.exports = Titlebar; diff --git a/lib/titlebar/titlebar.html b/lib/titlebar/titlebar.html new file mode 100644 index 0000000..37526c7 --- /dev/null +++ b/lib/titlebar/titlebar.html @@ -0,0 +1,167 @@ + +
+ + + + + + + +
+
+
+
+
+
+ + + +
+
+ + + + + + + + + + + +
+
+ + + +
+
\ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..bec0c48 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2415 @@ +{ + "name": "kano-desktop-shell", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.3.tgz", + "integrity": "sha512-wqrPE4Uvj2fmL0E5JFQiY7D/5bAKvVUfWTnQ5NEV35ULkAU0j3QuqIi9Qyrytz8M5hsrh8Kijt+FsdLQaZR+IA==" + }, + "acorn": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz", + "integrity": "sha512-XLmq3H/BVvW6/GbxKryGxWORz1ebilSsUDlyC27bXhWGWAZWkGwS6FLHjOlwFXNFoWFQEO/Df4u0YYd0K3BQgQ==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "5.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "supports-color": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", + "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.4", + "typedarray": "0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", + "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.2" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "electron": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/electron/-/electron-1.8.2.tgz", + "integrity": "sha512-0TV5Hy92g8ACnPn+PVol6a/2uk+khzmRtWxhah/FcKs6StCytm5hD14QqOdZxEdJN8HljXIVCayN/wJX+0wDiQ==", + "requires": { + "@types/node": "8.9.3", + "electron-download": "3.3.0", + "extract-zip": "1.6.6" + } + }, + "electron-download": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz", + "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=", + "requires": { + "debug": "2.6.9", + "fs-extra": "0.30.0", + "home-path": "1.0.5", + "minimist": "1.2.0", + "nugget": "2.0.1", + "path-exists": "2.1.0", + "rc": "1.2.5", + "semver": "5.5.0", + "sumchecker": "1.3.1" + } + }, + "electron-window-state": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-4.1.1.tgz", + "integrity": "sha1-azT9wxs4UU3+yLfI97XUrdtnYy0=", + "requires": { + "deep-equal": "1.0.1", + "jsonfile": "2.4.0", + "mkdirp": "0.5.1" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + } + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.17.0.tgz", + "integrity": "sha512-AyxBUCANU/o/xC0ijGMKavo5Ls3oK6xykiOITlMdjFjrKOsqLrA7Nf5cnrDgcKrHzBirclAZt63XO7YZlVUPwA==", + "dev": true, + "requires": { + "ajv": "5.5.2", + "babel-code-frame": "6.26.0", + "chalk": "2.3.1", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.1.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "1.0.0", + "espree": "3.5.3", + "esquery": "1.0.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.3.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.1.0", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.5", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.5.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "0.1.1" + } + }, + "eslint-config-kano": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-kano/-/eslint-config-kano-0.1.0.tgz", + "integrity": "sha512-LQOrSt2GfXZy+KNyd+PcrRIFiqIovssuGJbpX+zyfrc9EO0WeUixtHciTn3RUPOi42O0QygnuJgN+U+mv/kefQ==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "12.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "2.6.9", + "resolve": "1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + } + }, + "eslint-plugin-html": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-4.0.2.tgz", + "integrity": "sha512-CrQd0F8GWdNWnu4PFrYZl+LjUCXNVy2h0uhDMtnf/7VKc9HRcnkXSrlg0BSGfptZPSzmwnnwCaREAa9+fnQhYw==", + "dev": true, + "requires": { + "htmlparser2": "3.9.2" + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "dev": true, + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.2", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.3.tgz", + "integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==", + "dev": true, + "requires": { + "acorn": "5.4.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "requires": { + "pend": "1.2.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz", + "integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "home-path": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.5.tgz", + "integrity": "sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=" + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.4.1", + "domutils": "1.7.0", + "entities": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.4" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", + "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.1", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.5", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.1" + } + }, + "nugget": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", + "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", + "requires": { + "debug": "2.6.9", + "minimist": "1.2.0", + "pretty-bytes": "1.0.4", + "progress-stream": "1.2.0", + "request": "2.83.0", + "single-line-log": "1.1.2", + "throttleit": "0.0.2" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "pretty-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "progress-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", + "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", + "requires": { + "speedometer": "0.1.4", + "through2": "0.2.3" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "rc": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz", + "integrity": "sha1-J1zWh/bjs2zHVrqibf7oCnkDAf0=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "single-line-log": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", + "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", + "requires": { + "string-width": "1.0.2" + } + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "speedometer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz", + "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "sumchecker": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz", + "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=", + "requires": { + "debug": "2.6.9", + "es6-promise": "4.2.4" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "chalk": "2.3.1", + "lodash": "4.17.5", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", + "requires": { + "readable-stream": "1.1.14", + "xtend": "2.1.2" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + } + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "requires": { + "object-keys": "0.4.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "requires": { + "fd-slicer": "1.0.1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a2e68c4 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "kano-desktop-shell", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "demo": "electron app/" + }, + "author": "", + "license": "ISC", + "dependencies": { + "electron": "^1.8.2", + "electron-window-state": "^4.1.1" + }, + "devDependencies": { + "eslint": "^4.17.0", + "eslint-config-kano": "^0.1.0", + "eslint-plugin-html": "^4.0.2", + "eslint-plugin-import": "^2.8.0" + } +} diff --git a/res/classic-menu.png b/res/classic-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..477089c11cae5cb12722707969135298ffb2e22e GIT binary patch literal 53788 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