diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..9569b6efc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,17 @@ +build/** +components/** +dist/** +libtextsecure/** +coverage/** + +# these aren't ready yet, pulling files in one-by-one +js/** +test/** +/*.js +!main.js +!prepare_build.js + +# all of these files will be new +!test/server/**/*.js + +# all of app/ is included diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..f4db62c1e --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,41 @@ +// For reference: https://github.com/airbnb/javascript + +module.exports = { + settings: { + 'import/core-modules': [ + 'electron' + ] + }, + + extends: [ + 'airbnb-base', + ], + + rules: { + 'comma-dangle': ['error', { + arrays: 'always-multiline', + objects: 'always-multiline', + imports: 'always-multiline', + exports: 'always-multiline', + functions: 'never', + }], + + // putting params on their own line helps stay within line length limit + 'function-paren-newline': ['error', 'consistent'], + + // 90 characters allows three+ side-by-side screens on a standard-size monitor + 'max-len': ['error', { + code: 90, + ignoreUrls: true, + }], + + // it helps readability to put public API at top, + 'no-use-before-define': 'off', + + // useful for unused or internal fields + 'no-underscore-dangle': 'off', + + // though we have a logger, we still remap console to log to disk + 'no-console': 'off', + } +}; diff --git a/.gitignore b/.gitignore index 357b5f23e..368ae7923 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules .sass-cache +coverage/* build/curve25519_compiled.js build/icons/* stylesheets/*.css.map @@ -11,3 +12,5 @@ config/local-*.json *.provisionprofile release/ /dev-app-update.yml +.nyc_output/ +*.sublime* diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..4bc5d6181 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +7.9.0 diff --git a/.travis.yml b/.travis.yml index acee1fe24..762a4df20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 'node' + - '7.9.0' os: - linux dist: trusty @@ -9,6 +9,8 @@ install: script: - yarn run generate - yarn prepare-build + - yarn eslint + - yarn test-server - ./node_modules/.bin/build --em.environment=$SIGNAL_ENV --config.mac.bundleVersion='$TRAVIS_BUILD_NUMBER' --publish=never - ./travis.sh env: diff --git a/.yarnclean b/.yarnclean index 3d9c26626..9f5015970 100644 --- a/.yarnclean +++ b/.yarnclean @@ -39,3 +39,6 @@ Gruntfile.js # misc *.gz *.md + +# asset directories +!nyc/node_modules/istanbul-reports/lib/html/assets diff --git a/app/auto_update.js b/app/auto_update.js index ab454b29c..efcb70e67 100644 --- a/app/auto_update.js +++ b/app/auto_update.js @@ -1,4 +1,4 @@ -const autoUpdater = require('electron-updater').autoUpdater +const { autoUpdater } = require('electron-updater'); const { dialog } = require('electron'); const config = require('./config'); @@ -18,7 +18,7 @@ function checkForUpdates() { autoUpdater.checkForUpdates(); } -var showingDialog = false; +let showingDialog = false; function showUpdateDialog(mainWindow, messages) { if (showingDialog) { return; @@ -29,21 +29,21 @@ function showUpdateDialog(mainWindow, messages) { type: 'info', buttons: [ messages.autoUpdateRestartButtonLabel.message, - messages.autoUpdateLaterButtonLabel.message + messages.autoUpdateLaterButtonLabel.message, ], title: messages.autoUpdateNewVersionTitle.message, message: messages.autoUpdateNewVersionMessage.message, detail: messages.autoUpdateNewVersionInstructions.message, defaultId: LATER_BUTTON, cancelId: RESTART_BUTTON, - } + }; - dialog.showMessageBox(mainWindow, options, function(response) { - if (response == RESTART_BUTTON) { + dialog.showMessageBox(mainWindow, options, (response) => { + if (response === RESTART_BUTTON) { // We delay these update calls because they don't seem to work in this // callback - but only if the message box has a parent window. // Fixes this bug: https://github.com/WhisperSystems/Signal-Desktop/issues/1864 - setTimeout(function() { + setTimeout(() => { windowState.markShouldQuit(); autoUpdater.quitAndInstall(); }, 200); @@ -54,7 +54,7 @@ function showUpdateDialog(mainWindow, messages) { } function onError(error) { - console.log("Got an error while updating: ", error.stack); + console.log('Got an error while updating: ', error.stack); } function initialize(getMainWindow, messages) { @@ -66,7 +66,7 @@ function initialize(getMainWindow, messages) { return; } - autoUpdater.addListener('update-downloaded', function() { + autoUpdater.addListener('update-downloaded', () => { showUpdateDialog(getMainWindow(), messages); }); autoUpdater.addListener('error', onError); @@ -77,5 +77,5 @@ function initialize(getMainWindow, messages) { } module.exports = { - initialize + initialize, }; diff --git a/app/config.js b/app/config.js index 047d9c15e..d716be53e 100644 --- a/app/config.js +++ b/app/config.js @@ -1,9 +1,12 @@ const path = require('path'); +const config = require('config'); + const packageJson = require('../package.json'); const environment = packageJson.environment || process.env.NODE_ENV || 'development'; +config.environment = environment; // Set environment vars to configure node-config before requiring it process.env.NODE_ENV = environment; @@ -19,8 +22,6 @@ if (environment === 'production') { process.env.SUPPRESS_NO_CONFIG_WARNING = ''; } -const config = require('config'); -config.environment = environment; // Log resulting env vars in use by config [ @@ -30,9 +31,9 @@ config.environment = environment; 'ALLOW_CONFIG_MUTATIONS', 'HOSTNAME', 'NODE_APP_INSTANCE', - 'SUPPRESS_NO_CONFIG_WARNING' -].forEach(function(s) { - console.log(s + ' ' + config.util.getEnv(s)); + 'SUPPRESS_NO_CONFIG_WARNING', +].forEach((s) => { + console.log(`${s} ${config.util.getEnv(s)}`); }); module.exports = config; diff --git a/app/locale.js b/app/locale.js index b3e7bea0e..fddce1f27 100644 --- a/app/locale.js +++ b/app/locale.js @@ -1,9 +1,9 @@ const path = require('path'); const fs = require('fs'); -const app = require('electron').app; +const { app } = require('electron'); const _ = require('lodash'); -const logger = require('./logging').getLogger(); +const logging = require('./logging'); function normalizeLocaleName(locale) { if (/^en-/.test(locale)) { @@ -28,7 +28,8 @@ function getLocaleMessages(locale) { } function load() { - let english = getLocaleMessages('en'); + const logger = logging.getLogger(); + const english = getLocaleMessages('en'); let appLocale = app.getLocale(); if (process.env.NODE_ENV === 'test') { @@ -49,7 +50,7 @@ function load() { // We start with english, then overwrite that with anything present in locale messages = _.merge(english, messages); } catch (e) { - logger.error('Problem loading messages for locale ' + localeName + ' ' + e.stack); + logger.error(`Problem loading messages for locale ${localeName} ${e.stack}`); logger.error('Falling back to en locale'); localeName = 'en'; @@ -58,10 +59,10 @@ function load() { return { name: localeName, - messages + messages, }; } module.exports = { - load: load + load, }; diff --git a/app/logging.js b/app/logging.js index 1257c24d0..bad52467a 100644 --- a/app/logging.js +++ b/app/logging.js @@ -1,22 +1,31 @@ const path = require('path'); const fs = require('fs'); -const electron = require('electron') +const electron = require('electron'); const bunyan = require('bunyan'); const mkdirp = require('mkdirp'); const _ = require('lodash'); +const readFirstLine = require('firstline'); +const readLastLines = require('read-last-lines').read; - -const app = electron.app; -const ipc = electron.ipcMain; +const { + app, + ipcMain: ipc, +} = electron; const LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace']; - let logger; -function dropFirst(args) { - return Array.prototype.slice.call(args, 1); -} +module.exports = { + initialize, + getLogger, + // for tests only: + isLineAfterDate, + eliminateOutOfDateFiles, + eliminateOldEntries, + fetchLog, + fetch, +}; function initialize() { if (logger) { @@ -27,38 +36,114 @@ function initialize() { const logPath = path.join(basePath, 'logs'); mkdirp.sync(logPath); - const logFile = path.join(logPath, 'log.log'); + return cleanupLogs(logPath).then(() => { + const logFile = path.join(logPath, 'log.log'); - logger = bunyan.createLogger({ - name: 'log', - streams: [{ - level: 'debug', - stream: process.stdout - }, { - type: 'rotating-file', - path: logFile, - period: '1d', - count: 3 - }] - }); + logger = bunyan.createLogger({ + name: 'log', + streams: [{ + level: 'debug', + stream: process.stdout, + }, { + type: 'rotating-file', + path: logFile, + period: '1d', + count: 3, + }], + }); - LEVELS.forEach(function(level) { - ipc.on('log-' + level, function() { - // first parameter is the event, rest are provided arguments - var args = dropFirst(arguments); - logger[level].apply(logger, args); + LEVELS.forEach((level) => { + ipc.on(`log-${level}`, (first, ...rest) => { + logger[level](...rest); + }); + }); + + ipc.on('fetch-log', (event) => { + fetch(logPath).then((data) => { + event.sender.send('fetched-log', data); + }, (error) => { + logger.error(`Problem loading log from disk: ${error.stack}`); + }); }); }); +} - ipc.on('fetch-log', function(event) { - fetch(logPath).then(function(data) { - event.sender.send('fetched-log', data); - }, function(error) { - logger.error('Problem loading log from disk: ' + error.stack); - }); +function cleanupLogs(logPath) { + const now = new Date(); + const earliestDate = new Date(Date.UTC( + now.getUTCFullYear(), + now.getUTCMonth(), + now.getUTCDate() - 3 + )); + + return eliminateOutOfDateFiles(logPath, earliestDate).then((remaining) => { + const files = _.filter(remaining, file => !file.start && file.end); + + if (!files.length) { + return null; + } + + return eliminateOldEntries(files, earliestDate); }); } +function isLineAfterDate(line, date) { + if (!line) { + return false; + } + + try { + const data = JSON.parse(line); + return (new Date(data.time)).getTime() > date.getTime(); + } catch (e) { + console.log('error parsing log line', e.stack, line); + return false; + } +} + +function eliminateOutOfDateFiles(logPath, date) { + const files = fs.readdirSync(logPath); + const paths = files.map(file => path.join(logPath, file)); + + return Promise.all(_.map( + paths, + target => Promise.all([ + readFirstLine(target), + readLastLines(target, 2), + ]).then((results) => { + const start = results[0]; + const end = results[1].split('\n'); + + const file = { + path: target, + start: isLineAfterDate(start, date), + end: isLineAfterDate(end[end.length - 1], date) + || isLineAfterDate(end[end.length - 2], date), + }; + + if (!file.start && !file.end) { + fs.unlinkSync(file.path); + } + + return file; + }) + )); +} + +function eliminateOldEntries(files, date) { + const earliest = date.getTime(); + + return Promise.all(_.map( + files, + file => fetchLog(file.path).then((lines) => { + const recent = _.filter(lines, line => (new Date(line.time)).getTime() >= earliest); + const text = _.map(recent, line => JSON.stringify(line)).join('\n'); + + return fs.writeFileSync(file.path, `${text}\n`); + }) + )); +} + function getLogger() { if (!logger) { throw new Error('Logger hasn\'t been initialized yet!'); @@ -68,18 +153,19 @@ function getLogger() { } function fetchLog(logFile) { - return new Promise(function(resolve, reject) { - fs.readFile(logFile, { encoding: 'utf8' }, function(err, text) { + return new Promise((resolve, reject) => { + fs.readFile(logFile, { encoding: 'utf8' }, (err, text) => { if (err) { return reject(err); } const lines = _.compact(text.split('\n')); - const data = _.compact(lines.map(function(line) { + const data = _.compact(lines.map((line) => { try { return _.pick(JSON.parse(line), ['level', 'time', 'msg']); + } catch (e) { + return null; } - catch (e) {} })); return resolve(data); @@ -89,19 +175,17 @@ function fetchLog(logFile) { function fetch(logPath) { const files = fs.readdirSync(logPath); - const paths = files.map(function(file) { - return path.join(logPath, file) - }); + const paths = files.map(file => path.join(logPath, file)); // creating a manual log entry for the final log result - var now = new Date(); + const now = new Date(); const fileListEntry = { level: 30, // INFO time: now.toJSON(), - msg: 'Loaded this list of log files from logPath: ' + files.join(', '), + msg: `Loaded this list of log files from logPath: ${files.join(', ')}`, }; - return Promise.all(paths.map(fetchLog)).then(function(results) { + return Promise.all(paths.map(fetchLog)).then((results) => { const data = _.flatten(results); data.push(fileListEntry); @@ -111,18 +195,14 @@ function fetch(logPath) { } -function logAtLevel() { - const level = arguments[0]; - const args = Array.prototype.slice.call(arguments, 1); - +function logAtLevel(level, ...args) { if (logger) { // To avoid [Object object] in our log since console.log handles non-strings smoothly - const str = args.map(function(item) { + const str = args.map((item) => { if (typeof item !== 'string') { try { return JSON.stringify(item); - } - catch (e) { + } catch (e) { return item; } } @@ -131,20 +211,16 @@ function logAtLevel() { }); logger[level](str.join(' ')); } else { - console._log.apply(console, consoleArgs); + console._log(...args); } } - -console._log = console.log; -console.log = _.partial(logAtLevel, 'info'); -console._error = console.error; -console.error = _.partial(logAtLevel, 'error'); -console._warn = console.warn; -console.warn = _.partial(logAtLevel, 'warn'); - - -module.exports = { - initialize, - getLogger, -}; +// This blows up using mocha --watch, so we ensure it is run just once +if (!console._log) { + console._log = console.log; + console.log = _.partial(logAtLevel, 'info'); + console._error = console.error; + console.error = _.partial(logAtLevel, 'error'); + console._warn = console.warn; + console.warn = _.partial(logAtLevel, 'warn'); +} diff --git a/app/menu.js b/app/menu.js index 4eacc20ef..f12c6a35b 100644 --- a/app/menu.js +++ b/app/menu.js @@ -1,18 +1,20 @@ function createTemplate(options, messages) { - const showDebugLog = options.showDebugLog; - const showAbout = options.showAbout; - const openReleaseNotes = options.openReleaseNotes; - const openNewBugForm = options.openNewBugForm; - const openSupportPage = options.openSupportPage; - const openForums = options.openForums; + const { + showDebugLog, + showAbout, + openReleaseNotes, + openNewBugForm, + openSupportPage, + openForums, + } = options; - let template = [{ + const template = [{ label: messages.mainMenuFile.message, submenu: [ { role: 'quit', }, - ] + ], }, { label: messages.mainMenuEdit.message, @@ -43,8 +45,8 @@ function createTemplate(options, messages) { }, { role: 'selectall', - } - ] + }, + ], }, { label: messages.mainMenuView.message, @@ -77,7 +79,7 @@ function createTemplate(options, messages) { { role: 'toggledevtools', }, - ] + ], }, { label: messages.mainMenuWindow.message, @@ -86,7 +88,7 @@ function createTemplate(options, messages) { { role: 'minimize', }, - ] + ], }, { label: messages.mainMenuHelp.message, @@ -118,7 +120,7 @@ function createTemplate(options, messages) { label: messages.aboutSignalDesktop.message, click: showAbout, }, - ] + ], }]; if (process.platform === 'darwin') { @@ -129,8 +131,10 @@ function createTemplate(options, messages) { } function updateForMac(template, messages, options) { - const showWindow = options.showWindow; - const showAbout = options.showAbout; + const { + showWindow, + showAbout, + } = options; // Remove About item and separator from Help menu, since it's on the first menu template[4].submenu.pop(); @@ -162,13 +166,13 @@ function updateForMac(template, messages, options) { { role: 'quit', }, - ] + ], }); // Add to Edit menu template[1].submenu.push( { - type: 'separator' + type: 'separator', }, { label: messages.speech.message, @@ -179,11 +183,12 @@ function updateForMac(template, messages, options) { { role: 'stopspeaking', }, - ] + ], } ); - // Add to Window menu + // Replace Window menu + // eslint-disable-next-line no-param-reassign template[3].submenu = [ { accelerator: 'CmdOrCtrl+W', diff --git a/app/tray_icon.js b/app/tray_icon.js index 535e9504d..d32ff7652 100644 --- a/app/tray_icon.js +++ b/app/tray_icon.js @@ -1,23 +1,24 @@ -const electron = require('electron') const path = require('path'); -const app = electron.app; -const Menu = electron.Menu; -const Tray = electron.Tray; +const { + app, + Menu, + Tray, +} = require('electron'); let trayContextMenu = null; let tray = null; function createTrayIcon(getMainWindow, messages) { - // A smaller icon is needed on macOS tray = new Tray( - process.platform == "darwin" ? - path.join(__dirname, '..', 'images', 'icon_16.png') : - path.join(__dirname, '..', 'images', 'icon_256.png')); + process.platform === 'darwin' ? + path.join(__dirname, '..', 'images', 'icon_16.png') : + path.join(__dirname, '..', 'images', 'icon_256.png') + ); - tray.toggleWindowVisibility = function () { - var mainWindow = getMainWindow(); + tray.toggleWindowVisibility = () => { + const mainWindow = getMainWindow(); if (mainWindow) { if (mainWindow.isVisible()) { mainWindow.hide(); @@ -33,31 +34,28 @@ function createTrayIcon(getMainWindow, messages) { } } tray.updateContextMenu(); - } + }; - tray.updateContextMenu = function () { - - var mainWindow = getMainWindow(); + tray.updateContextMenu = () => { + const mainWindow = getMainWindow(); // NOTE: we want to have the show/hide entry available in the tray icon // context menu, since the 'click' event may not work on all platforms. // For details please refer to: // https://github.com/electron/electron/blob/master/docs/api/tray.md. - trayContextMenu = Menu.buildFromTemplate([ - { - id: 'toggleWindowVisibility', - label: messages[mainWindow.isVisible() ? 'hide' : 'show'].message, - click: tray.toggleWindowVisibility - }, - { - id: 'quit', - label: messages.quit.message, - click: app.quit.bind(app) - } - ]); + trayContextMenu = Menu.buildFromTemplate([{ + id: 'toggleWindowVisibility', + label: messages[mainWindow.isVisible() ? 'hide' : 'show'].message, + click: tray.toggleWindowVisibility, + }, + { + id: 'quit', + label: messages.quit.message, + click: app.quit.bind(app), + }]); tray.setContextMenu(trayContextMenu); - } + }; tray.on('click', tray.toggleWindowVisibility); diff --git a/app/user_config.js b/app/user_config.js index 4f77368b5..c0f0bb539 100644 --- a/app/user_config.js +++ b/app/user_config.js @@ -1,6 +1,6 @@ const path = require('path'); -const app = require('electron').app; +const { app } = require('electron'); const ElectronConfig = require('electron-config'); const config = require('./config'); @@ -10,13 +10,13 @@ const config = require('./config'); if (config.has('storageProfile')) { const userData = path.join( app.getPath('appData'), - 'Signal-' + config.get('storageProfile') + `Signal-${config.get('storageProfile')}` ); app.setPath('userData', userData); } -console.log('userData: ' + app.getPath('userData')); +console.log(`userData: ${app.getPath('userData')}`); // this needs to be below our update to the appData path const userConfig = new ElectronConfig(); diff --git a/app/window_state.js b/app/window_state.js index 6d264339c..0cd7dd024 100644 --- a/app/window_state.js +++ b/app/window_state.js @@ -10,5 +10,5 @@ function shouldQuit() { module.exports = { shouldQuit, - markShouldQuit + markShouldQuit, }; diff --git a/appveyor.yml b/appveyor.yml index 671182985..6aac7837e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,10 +8,12 @@ cache: install: - systeminfo | findstr /C:"OS" - set PATH=C:\Ruby23-x64\bin;%PATH% - - ps: Install-Product node 6 x64 + - ps: Install-Product node 7.9.0 x64 - yarn install build_script: + - yarn eslint + - yarn test-server - yarn run icon-gen - node build\grunt.js - type package.json | findstr /v certificateSubjectName > temp.json diff --git a/main.js b/main.js index c1e1c86cd..e164f42ef 100644 --- a/main.js +++ b/main.js @@ -6,19 +6,25 @@ const _ = require('lodash'); const electron = require('electron'); const semver = require('semver'); -const BrowserWindow = electron.BrowserWindow; -const app = electron.app; -const ipc = electron.ipcMain; -const Menu = electron.Menu; -const shell = electron.shell; +const { + BrowserWindow, + app, + Menu, + shell, + ipcMain: ipc, +} = electron; const packageJson = require('./package.json'); + +const createTrayIcon = require('./app/tray_icon'); +const createTemplate = require('./app/menu.js'); +const logging = require('./app/logging'); const autoUpdate = require('./app/auto_update'); const windowState = require('./app/window_state'); -const aumid = 'org.whispersystems.' + packageJson.name; -console.log('setting AUMID to ' + aumid); +const aumid = `org.whispersystems.${packageJson.name}`; +console.log(`setting AUMID to ${aumid}`); app.setAppUserModelId(aumid); // Keep a global reference of the window object, if you don't, the window will @@ -34,7 +40,7 @@ let tray = null; const startInTray = process.argv.find(arg => arg === '--start-in-tray'); const usingTrayIcon = startInTray || process.argv.find(arg => arg === '--use-tray-icon'); -const config = require("./app/config"); +const config = require('./app/config'); // Very important to put before the single instance check, since it is based on the // userData directory. @@ -63,7 +69,7 @@ function showWindow() { if (!process.mas) { console.log('making app single instance'); - var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { + const shouldQuit = app.makeSingleInstance(() => { // Someone tried to run a second instance, we should focus our window if (mainWindow) { if (mainWindow.isMinimized()) { @@ -78,19 +84,14 @@ if (!process.mas) { if (shouldQuit) { console.log('quitting; we are the second instance'); app.quit(); - return; } } -const logging = require('./app/logging'); - -// This must be after we set up appPath in user_config.js, so we know where logs go -logging.initialize(); -const logger = logging.getLogger(); - let windowConfig = userConfig.get('window'); const loadLocale = require('./app/locale').load; +// Both of these will be set after app fires the 'ready' event +let logger; let locale; const WINDOWS_8 = '8.0.0'; @@ -118,20 +119,20 @@ function prepareURL(pathSegments) { appInstance: process.env.NODE_APP_INSTANCE, polyfillNotifications: polyfillNotifications ? true : undefined, // for stringify() proxyUrl: process.env.HTTPS_PROXY || process.env.https_proxy, - } - }) + }, + }); } function handleUrl(event, target) { event.preventDefault(); - const protocol = url.parse(target).protocol; + const { protocol } = url.parse(target); if (protocol === 'http:' || protocol === 'https:') { shell.openExternal(target); } } function captureClicks(window) { - window.webContents.on('will-navigate', handleUrl) + window.webContents.on('will-navigate', handleUrl); window.webContents.on('new-window', handleUrl); } @@ -150,11 +151,11 @@ function isVisible(window, bounds) { // requiring BOUNDS_BUFFER pixels on the left or right side const rightSideClearOfLeftBound = (window.x + window.width >= boundsX + BOUNDS_BUFFER); - const leftSideClearOfRightBound = (window.x <= boundsX + boundsWidth - BOUNDS_BUFFER); + const leftSideClearOfRightBound = (window.x <= (boundsX + boundsWidth) - BOUNDS_BUFFER); // top can't be offscreen, and must show at least BOUNDS_BUFFER pixels at bottom const topClearOfUpperBound = window.y >= boundsY; - const topClearOfLowerBound = (window.y <= boundsY + boundsHeight - BOUNDS_BUFFER); + const topClearOfLowerBound = (window.y <= (boundsY + boundsHeight) - BOUNDS_BUFFER); return rightSideClearOfLeftBound && leftSideClearOfRightBound @@ -162,8 +163,8 @@ function isVisible(window, bounds) { && topClearOfLowerBound; } -function createWindow () { - const screen = electron.screen; +function createWindow() { + const { screen } = electron; const windowOptions = Object.assign({ show: !startInTray, // allow to start minimised in tray width: DEFAULT_WIDTH, @@ -173,8 +174,8 @@ function createWindow () { autoHideMenuBar: false, webPreferences: { nodeIntegration: false, - //sandbox: true, - preload: path.join(__dirname, 'preload.js') + // sandbox: true, + preload: path.join(__dirname, 'preload.js'), }, icon: path.join(__dirname, 'images', 'icon_256.png'), }, _.pick(windowConfig, ['maximized', 'autoHideMenuBar', 'width', 'height', 'x', 'y'])); @@ -192,7 +193,7 @@ function createWindow () { delete windowOptions.autoHideMenuBar; } - const visibleOnAnyScreen = _.some(screen.getAllDisplays(), function(display) { + const visibleOnAnyScreen = _.some(screen.getAllDisplays(), (display) => { if (!_.isNumber(windowOptions.x) || !_.isNumber(windowOptions.y)) { return false; } @@ -225,7 +226,7 @@ function createWindow () { width: size[0], height: size[1], x: position[0], - y: position[1] + y: position[1], }; if (mainWindow.isFullScreen()) { @@ -243,12 +244,13 @@ function createWindow () { mainWindow.on('move', debouncedCaptureStats); mainWindow.on('close', captureAndSaveWindowStats); - mainWindow.on('focus', function() { + mainWindow.on('focus', () => { mainWindow.flashFrame(false); }); // Ingested in preload.js via a sendSync call - ipc.on('locale-data', function(event, arg) { + ipc.on('locale-data', (event) => { + // eslint-disable-next-line no-param-reassign event.returnValue = locale.messages; }); @@ -262,23 +264,21 @@ function createWindow () { if (config.get('openDevTools')) { // Open the DevTools. - mainWindow.webContents.openDevTools() + mainWindow.webContents.openDevTools(); } captureClicks(mainWindow); - mainWindow.webContents.on('will-navigate', function(e) { + mainWindow.webContents.on('will-navigate', (e) => { logger.info('will-navigate'); e.preventDefault(); }); // Emitted when the window is about to be closed. - mainWindow.on('close', function (e) { - + mainWindow.on('close', (e) => { // If the application is terminating, just do the default if (windowState.shouldQuit() || config.environment === 'test' || config.environment === 'test-lib') { - return; } @@ -296,26 +296,26 @@ function createWindow () { }); // Emitted when the window is closed. - mainWindow.on('closed', function () { + mainWindow.on('closed', () => { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. - mainWindow = null + mainWindow = null; }); - ipc.on('show-window', function() { + ipc.on('show-window', () => { showWindow(); }); } function showDebugLog() { if (mainWindow) { - mainWindow.webContents.send('debug-log') + mainWindow.webContents.send('debug-log'); } } function openReleaseNotes() { - shell.openExternal('https://github.com/WhisperSystems/Signal-Desktop/releases/tag/v' + app.getVersion()); + shell.openExternal(`https://github.com/WhisperSystems/Signal-Desktop/releases/tag/v${app.getVersion()}`); } function openNewBugForm() { @@ -348,7 +348,7 @@ function showAbout() { show: false, webPreferences: { nodeIntegration: false, - preload: path.join(__dirname, 'preload.js') + preload: path.join(__dirname, 'preload.js'), }, parent: mainWindow, }; @@ -359,11 +359,11 @@ function showAbout() { aboutWindow.loadURL(prepareURL([__dirname, 'about.html'])); - aboutWindow.on('closed', function () { + aboutWindow.on('closed', () => { aboutWindow = null; }); - aboutWindow.once('ready-to-show', function() { + aboutWindow.once('ready-to-show', () => { aboutWindow.show(); }); } @@ -372,53 +372,64 @@ function showAbout() { // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. let ready = false; -app.on('ready', function() { - logger.info('app ready'); - ready = true; +app.on('ready', () => { + let loggingSetupError; + logging.initialize().catch((error) => { + loggingSetupError = error; + }).then(() => { + logger = logging.getLogger(); + logger.info('app ready'); - if (!locale) { - locale = loadLocale(); - } + if (loggingSetupError) { + logger.error('Problem setting up logging', loggingSetupError.stack); + } - autoUpdate.initialize(getMainWindow, locale.messages); + if (!locale) { + locale = loadLocale(); + } - createWindow(); + ready = true; - if (usingTrayIcon) { - const createTrayIcon = require("./app/tray_icon"); - tray = createTrayIcon(getMainWindow, locale.messages); - } + autoUpdate.initialize(getMainWindow, locale.messages); - const options = { - showDebugLog, - showWindow, - showAbout, - openReleaseNotes, - openNewBugForm, - openSupportPage, - openForums, - }; - const createTemplate = require('./app/menu.js'); - const template = createTemplate(options, locale.messages); + createWindow(); - const menu = Menu.buildFromTemplate(template); - Menu.setApplicationMenu(menu); -}) + if (usingTrayIcon) { + tray = createTrayIcon(getMainWindow, locale.messages); + } -app.on('before-quit', function() { + const options = { + showDebugLog, + showWindow, + showAbout, + openReleaseNotes, + openNewBugForm, + openSupportPage, + openForums, + }; + const template = createTemplate(options, locale.messages); + + const menu = Menu.buildFromTemplate(template); + Menu.setApplicationMenu(menu); + }); +}); + +app.on('before-quit', () => { windowState.markShouldQuit(); }); // Quit when all windows are closed. -app.on('window-all-closed', function () { +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' || config.environment === 'test' || config.environment === 'test-lib') { - app.quit() + if (process.platform !== 'darwin' + || config.environment === 'test' + || config.environment === 'test-lib') { + app.quit(); } -}) +}); -app.on('activate', function () { +app.on('activate', () => { if (!ready) { return; } @@ -430,46 +441,43 @@ app.on('activate', function () { } else { createWindow(); } -}) +}); -// In this file you can include the rest of your app's specific main process -// code. You can also put them in separate files and require them here. - -ipc.on('set-badge-count', function(event, count) { +ipc.on('set-badge-count', (event, count) => { app.setBadgeCount(count); }); -ipc.on('draw-attention', function(event, count) { +ipc.on('draw-attention', () => { if (process.platform === 'darwin') { app.dock.bounce(); - } else if (process.platform == 'win32') { + } else if (process.platform === 'win32') { mainWindow.flashFrame(true); - setTimeout(function() { + setTimeout(() => { mainWindow.flashFrame(false); }, 1000); - } else if (process.platform == 'linux') { + } else if (process.platform === 'linux') { mainWindow.flashFrame(true); } }); -ipc.on('restart', function(event) { +ipc.on('restart', () => { app.relaunch(); app.quit(); }); -ipc.on("set-auto-hide-menu-bar", function(event, autoHide) { +ipc.on('set-auto-hide-menu-bar', (event, autoHide) => { if (mainWindow) { mainWindow.setAutoHideMenuBar(autoHide); } }); -ipc.on("set-menu-bar-visibility", function(event, visibility) { +ipc.on('set-menu-bar-visibility', (event, visibility) => { if (mainWindow) { mainWindow.setMenuBarVisibility(visibility); } }); -ipc.on("close-about", function() { +ipc.on('close-about', () => { if (aboutWindow) { aboutWindow.close(); } diff --git a/package.json b/package.json index 5c31e215e..a1dd3bb4a 100644 --- a/package.json +++ b/package.json @@ -10,26 +10,6 @@ "email": "support@whispersystems.org" }, "main": "main.js", - "devDependencies": { - "asar": "^0.14.0", - "bower": "^1.8.2", - "electron": "1.7.10", - "electron-builder": "^19.49.2", - "electron-icon-maker": "^0.0.4", - "electron-publisher-s3": "^19.49.0", - "grunt": "^1.0.1", - "grunt-cli": "^1.2.0", - "grunt-contrib-concat": "^1.0.1", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-jshint": "^1.1.0", - "grunt-contrib-watch": "^1.0.0", - "grunt-exec": "^3.0.0", - "grunt-gitinfo": "^0.1.7", - "grunt-jscs": "^3.0.1", - "grunt-sass": "^2.0.0", - "node-sass-import-once": "^1.2.0", - "spectron": "^3.7.2" - }, "scripts": { "postinstall": "electron-builder install-app-deps && rimraf node_modules/dtrace-provider", "test": "grunt test", @@ -53,7 +33,62 @@ "release-mac": "npm run build-release -- -m --prepackaged release/mac/Signal*.app --publish=always", "release-win": "npm run build-release -- -w --prepackaged release/windows --publish=always", "release-lin": "npm run build-release -- -l --prepackaged release/linux && NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh", - "release": "npm run release-mac && npm run release-win && npm run release-lin" + "release": "npm run release-mac && npm run release-win && npm run release-lin", + "test-server": "mocha --recursive test/server", + "test-server-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/server", + "eslint": "eslint .", + "open-coverage": "open coverage/lcov-report/index.html" + }, + "dependencies": { + "bunyan": "^1.8.12", + "config": "^1.28.1", + "electron-config": "^1.0.0", + "electron-editor-context-menu": "^1.1.1", + "electron-updater": "^2.17.6", + "emoji-datasource": "4.0.0", + "emoji-datasource-apple": "4.0.0", + "emoji-js": "^3.4.0", + "emoji-panel": "https://github.com/scottnonnenberg/emoji-panel.git#v0.5.5", + "firstline": "^1.2.1", + "google-libphonenumber": "^3.0.7", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "node-fetch": "https://github.com/scottnonnenberg/node-fetch.git#3e5f51e08c647ee5f20c43b15cf2d352d61c36b4", + "node-notifier": "^5.1.2", + "os-locale": "^2.1.0", + "proxy-agent": "^2.1.0", + "read-last-lines": "^1.3.0", + "rimraf": "^2.6.2", + "semver": "^5.4.1", + "spellchecker": "^3.4.4", + "websocket": "^1.0.25" + }, + "devDependencies": { + "asar": "^0.14.0", + "bower": "^1.8.2", + "chai": "^4.1.2", + "electron": "1.7.10", + "electron-builder": "^19.49.2", + "electron-icon-maker": "^0.0.4", + "electron-publisher-s3": "^19.49.0", + "eslint": "^4.14.0", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-plugin-import": "^2.8.0", + "grunt": "^1.0.1", + "grunt-cli": "^1.2.0", + "grunt-contrib-concat": "^1.0.1", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-jshint": "^1.1.0", + "grunt-contrib-watch": "^1.0.0", + "grunt-exec": "^3.0.0", + "grunt-gitinfo": "^0.1.7", + "grunt-jscs": "^3.0.1", + "grunt-sass": "^2.0.0", + "mocha": "^4.1.0", + "node-sass-import-once": "^1.2.0", + "nyc": "^11.4.1", + "spectron": "^3.7.2", + "tmp": "^0.0.33" }, "build": { "appId": "org.whispersystems.signal-desktop", @@ -169,27 +204,5 @@ "node_modules/spellchecker/build/Release/*.node", "node_modules/websocket/build/Release/*.node" ] - }, - "dependencies": { - "bunyan": "^1.8.12", - "config": "^1.28.1", - "electron-config": "^1.0.0", - "electron-editor-context-menu": "^1.1.1", - "electron-updater": "^2.17.6", - "emoji-datasource": "4.0.0", - "emoji-datasource-apple": "4.0.0", - "emoji-js": "^3.4.0", - "emoji-panel": "https://github.com/scottnonnenberg/emoji-panel.git#v0.5.5", - "google-libphonenumber": "^3.0.7", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "node-fetch": "https://github.com/scottnonnenberg/node-fetch.git#3e5f51e08c647ee5f20c43b15cf2d352d61c36b4", - "node-notifier": "^5.1.2", - "os-locale": "^2.1.0", - "proxy-agent": "^2.1.0", - "rimraf": "^2.6.2", - "semver": "^5.4.1", - "spellchecker": "^3.4.4", - "websocket": "^1.0.25" } } diff --git a/prepare_build.js b/prepare_build.js index 06d894f65..47acc5d57 100644 --- a/prepare_build.js +++ b/prepare_build.js @@ -2,7 +2,9 @@ const fs = require('fs'); const _ = require('lodash'); const packageJson = require('./package.json'); -const version = packageJson.version; + + +const { version } = packageJson; const beta = /beta/; // You might be wondering why this file is necessary. It comes down to our desire to allow @@ -12,7 +14,7 @@ const beta = /beta/; // adding the ${channel} macro to these values, but Electron-Builder didn't like that. if (!beta.test(version)) { - return; + process.exit(); } console.log('prepare_build: updating package.json for beta build'); @@ -36,13 +38,12 @@ const PRODUCTION_STARTUP_WM_CLASS = 'Signal'; const BETA_STARTUP_WM_CLASS = 'Signal Beta'; - // ------- function checkValue(object, objectPath, expected) { - const actual = _.get(object, objectPath) + const actual = _.get(object, objectPath); if (actual !== expected) { - throw new Error(objectPath + ' was ' + actual + '; expected ' + expected); + throw new Error(`${objectPath} was ${actual}; expected ${expected}`); } } diff --git a/test/.eslintrc.js b/test/.eslintrc.js new file mode 100644 index 000000000..3a0872c30 --- /dev/null +++ b/test/.eslintrc.js @@ -0,0 +1,17 @@ +// For reference: https://github.com/airbnb/javascript + +module.exports = { + env: { + mocha: true, + }, + + rules: { + // We still get the value of this rule, it just allows for dev deps + 'import/no-extraneous-dependencies': ['error', { + devDependencies: true + }], + + // We want to keep each test structured the same, even if its contents are tiny + 'arrow-body-style': 'off', + } +}; diff --git a/test/server/app/logging_test.js b/test/server/app/logging_test.js new file mode 100644 index 000000000..865232bfc --- /dev/null +++ b/test/server/app/logging_test.js @@ -0,0 +1,271 @@ +const fs = require('fs'); +const path = require('path'); + +const tmp = require('tmp'); +const { expect } = require('chai'); + +const { + eliminateOutOfDateFiles, + eliminateOldEntries, + isLineAfterDate, + fetchLog, + fetch, +} = require('../../../app/logging'); + +describe('app/logging', () => { + let basePath; + let tmpDir; + + beforeEach(() => { + tmpDir = tmp.dirSync({ + unsafeCleanup: true, + }); + basePath = tmpDir.name; + }); + + afterEach((done) => { + // we need the unsafe option to recursively remove the directory + tmpDir.removeCallback(done); + }); + + describe('#isLineAfterDate', () => { + it('returns false if falsy', () => { + const actual = isLineAfterDate('', new Date()); + expect(actual).to.equal(false); + }); + it('returns false if invalid JSON', () => { + const actual = isLineAfterDate('{{}', new Date()); + expect(actual).to.equal(false); + }); + it('returns false if date is invalid', () => { + const line = JSON.stringify({ time: '2018-01-04T19:17:05.014Z' }); + const actual = isLineAfterDate(line, new Date('try6')); + expect(actual).to.equal(false); + }); + it('returns false if log time is invalid', () => { + const line = JSON.stringify({ time: 'try7' }); + const date = new Date('2018-01-04T19:17:00.000Z'); + const actual = isLineAfterDate(line, date); + expect(actual).to.equal(false); + }); + it('returns false if date before provided date', () => { + const line = JSON.stringify({ time: '2018-01-04T19:17:00.000Z' }); + const date = new Date('2018-01-04T19:17:05.014Z'); + const actual = isLineAfterDate(line, date); + expect(actual).to.equal(false); + }); + it('returns true if date is after provided date', () => { + const line = JSON.stringify({ time: '2018-01-04T19:17:05.014Z' }); + const date = new Date('2018-01-04T19:17:00.000Z'); + const actual = isLineAfterDate(line, date); + expect(actual).to.equal(true); + }); + }); + + describe('#eliminateOutOfDateFiles', () => { + it('deletes an empty file', () => { + const date = new Date(); + const log = '\n'; + const target = path.join(basePath, 'log.log'); + fs.writeFileSync(target, log); + + return eliminateOutOfDateFiles(basePath, date).then(() => { + expect(fs.existsSync(target)).to.equal(false); + }); + }); + it('deletes a file with invalid JSON lines', () => { + const date = new Date(); + const log = '{{}\n'; + const target = path.join(basePath, 'log.log'); + fs.writeFileSync(target, log); + + return eliminateOutOfDateFiles(basePath, date).then(() => { + expect(fs.existsSync(target)).to.equal(false); + }); + }); + it('deletes a file with all dates before provided date', () => { + const date = new Date('2018-01-04T19:17:05.014Z'); + const contents = [ + JSON.stringify({ time: '2018-01-04T19:17:00.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + const target = path.join(basePath, 'log.log'); + fs.writeFileSync(target, contents); + + return eliminateOutOfDateFiles(basePath, date).then(() => { + expect(fs.existsSync(target)).to.equal(false); + }); + }); + it('keeps a file with first line date before provided date', () => { + const date = new Date('2018-01-04T19:16:00.000Z'); + const contents = [ + JSON.stringify({ time: '2018-01-04T19:17:00.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + const target = path.join(basePath, 'log.log'); + fs.writeFileSync(target, contents); + + return eliminateOutOfDateFiles(basePath, date).then(() => { + expect(fs.existsSync(target)).to.equal(true); + }); + }); + it('keeps a file with last line date before provided date', () => { + const date = new Date('2018-01-04T19:17:01.000Z'); + const contents = [ + JSON.stringify({ time: '2018-01-04T19:17:00.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + const target = path.join(basePath, 'log.log'); + fs.writeFileSync(target, contents); + + return eliminateOutOfDateFiles(basePath, date).then(() => { + expect(fs.existsSync(target)).to.equal(true); + }); + }); + }); + + describe('#eliminateOldEntries', () => { + it('eliminates all non-parsing entries', () => { + const date = new Date('2018-01-04T19:17:01.000Z'); + const contents = [ + 'random line', + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + const expected = [ + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + + const target = path.join(basePath, 'log.log'); + const files = [{ + path: target, + }]; + + fs.writeFileSync(target, contents); + + return eliminateOldEntries(files, date).then(() => { + expect(fs.readFileSync(target, 'utf8')).to.equal(`${expected}\n`); + }); + }); + it('preserves all lines if before target date', () => { + const date = new Date('2018-01-04T19:17:03.000Z'); + const contents = [ + 'random line', + JSON.stringify({ time: '2018-01-04T19:17:01.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:02.014Z' }), + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + const expected = [ + JSON.stringify({ time: '2018-01-04T19:17:03.014Z' }), + ].join('\n'); + + const target = path.join(basePath, 'log.log'); + const files = [{ + path: target, + }]; + + fs.writeFileSync(target, contents); + + return eliminateOldEntries(files, date).then(() => { + expect(fs.readFileSync(target, 'utf8')).to.equal(`${expected}\n`); + }); + }); + }); + + describe('#fetchLog', () => { + it('returns error if file does not exist', () => { + const target = 'random_file'; + return fetchLog(target).then(() => { + throw new Error('Expected an error!'); + }, (error) => { + expect(error).to.have.property('message').that.match(/random_file/); + }); + }); + it('returns empty array if file has no valid JSON lines', () => { + const contents = 'line 1\nline2\n'; + const expected = []; + const target = path.join(basePath, 'test.log'); + + fs.writeFileSync(target, contents); + + return fetchLog(target).then((result) => { + expect(result).to.deep.equal(expected); + }); + }); + it('returns just three fields in each returned line', () => { + const contents = [ + JSON.stringify({ + one: 1, + two: 2, + level: 1, + time: 2, + msg: 3, + }), + JSON.stringify({ + one: 1, + two: 2, + level: 2, + time: 3, + msg: 4, + }), + '', + ].join('\n'); + const expected = [{ + level: 1, + time: 2, + msg: 3, + }, { + level: 2, + time: 3, + msg: 4, + }]; + + const target = path.join(basePath, 'test.log'); + + fs.writeFileSync(target, contents); + + return fetchLog(target).then((result) => { + expect(result).to.deep.equal(expected); + }); + }); + }); + + describe('#fetch', () => { + it('returns single entry if no files', () => { + return fetch(basePath).then((results) => { + expect(results).to.have.length(1); + expect(results[0].msg).to.match(/Loaded this list/); + }); + }); + it('returns sorted entries from all files', () => { + const first = [ + JSON.stringify({ msg: 2, time: '2018-01-04T19:17:05.014Z' }), + '', + ].join('\n'); + const second = [ + JSON.stringify({ msg: 1, time: '2018-01-04T19:17:00.014Z' }), + JSON.stringify({ msg: 3, time: '2018-01-04T19:18:00.014Z' }), + '', + ].join('\n'); + + fs.writeFileSync(path.join(basePath, 'first.log'), first); + fs.writeFileSync(path.join(basePath, 'second.log'), second); + + return fetch(basePath).then((results) => { + expect(results).to.have.length(4); + expect(results[0].msg).to.equal(1); + expect(results[1].msg).to.equal(2); + expect(results[2].msg).to.equal(3); + }); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index ed01f897e..4afc5b8c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,6 +34,20 @@ abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822" + agent-base@2, agent-base@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" @@ -47,7 +61,7 @@ agent-base@^4.1.0: dependencies: es6-promisify "^5.0.0" -ajv-keywords@^2.1.1: +ajv-keywords@^2.1.0, ajv-keywords@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" @@ -58,7 +72,7 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.1.0, ajv@^5.5.1: +ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0, ajv@^5.5.1: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -67,6 +81,14 @@ ajv@^5.1.0, ajv@^5.5.1: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -103,7 +125,7 @@ ansi-styles@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" -any-promise@^1.3.0: +any-promise@^1.0.0, any-promise@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -118,6 +140,12 @@ app-package-builder@2.0.1: int64-buffer "^0.1.10" rabin-bindings "~1.7.4" +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + aproba@^1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" @@ -146,6 +174,10 @@ archiver@~2.1.0: tar-stream "^1.5.0" zip-stream "^1.2.0" +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + are-we-there-yet@~1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" @@ -169,6 +201,16 @@ args@^2.3.0: pkginfo "0.4.0" string-similarity "1.1.0" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -183,7 +225,11 @@ array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" -arrify@^1.0.0: +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -219,6 +265,10 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + ast-types@0.x.x: version "0.10.1" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd" @@ -235,7 +285,7 @@ async@0.2.x, async@~0.2.9: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" -async@^1.5.0, async@~1.5.2: +async@^1.4.0, async@^1.5.0, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -284,7 +334,34 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-runtime@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-generator@^6.18.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: @@ -298,6 +375,43 @@ babel-runtime@^6.9.2: core-js "^2.4.0" regenerator-runtime "^0.10.0" +babel-template@^6.16.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.18.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + babylon@^6.8.1: version "6.17.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.0.tgz#37da948878488b9c4e3c4038893fa3314b3fc932" @@ -417,6 +531,18 @@ brace-expansion@^1.0.0, brace-expansion@^1.1.7: balanced-match "^0.4.1" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + buffer-crc32@^0.2.1: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -467,7 +593,7 @@ builder-util@3.4.4, builder-util@^3.4.4: temp-file "^3.0.0" tunnel-agent "^0.6.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -492,6 +618,24 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -503,6 +647,10 @@ camelcase@4.1.0, camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -519,13 +667,31 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chai@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^3.0.0" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" dependencies: traverse ">=0.3.0 <0.4" -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@~1.1.0, chalk@~1.1.1: +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0, chalk@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -535,7 +701,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@~1.1.0, chalk@~1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: @@ -555,6 +721,10 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +check-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + chownr@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" @@ -567,6 +737,10 @@ ci-info@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" @@ -594,6 +768,14 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -646,6 +828,10 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + commander@^2.9.0, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -658,6 +844,10 @@ comment-parser@^0.3.1: dependencies: readable-stream "^2.0.4" +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + compare-version@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" @@ -683,7 +873,7 @@ concat-stream@1.5.0: readable-stream "~2.0.0" typedarray "~0.0.5" -concat-stream@1.6.0: +concat-stream@1.6.0, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -728,10 +918,18 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + content-type@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" +convert-source-map@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -764,7 +962,14 @@ cross-spawn@^3.0.0: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.0.1: +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -854,6 +1059,10 @@ dateformat@~1.0.12: get-stdin "^4.0.1" meow "^3.3.0" +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + debug@0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" @@ -864,6 +1073,12 @@ debug@2, debug@2.6.9: dependencies: ms "2.0.0" +debug@3.1.0, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + debug@^2.1.3, debug@^2.2.0, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" @@ -876,19 +1091,13 @@ debug@^3.0.0: dependencies: ms "2.0.0" -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - debug@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: ms "0.7.1" -decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -904,6 +1113,12 @@ decompress-zip@0.3.0: readable-stream "^1.1.8" touch "0.0.3" +deep-eql@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + dependencies: + type-detect "^4.0.0" + deep-equal@*: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -920,6 +1135,12 @@ deepmerge@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.0.1.tgz#25c1c24f110fb914f80001b925264dd77f3f4312" +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + degenerator@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" @@ -928,7 +1149,7 @@ degenerator@^1.0.4: escodegen "1.x.x" esprima "3.x.x" -del@^2.2.2: +del@^2.0.2, del@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" dependencies: @@ -956,10 +1177,20 @@ depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + dev-null@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/dev-null/-/dev-null-0.1.1.tgz#5a205ce3c2b2ef77b6238d6ba179eb74c6a0e818" +diff@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + dmg-builder@2.1.9: version "2.1.9" resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-2.1.9.tgz#3c501b034436134bef464082212e380124a5df79" @@ -972,6 +1203,19 @@ dmg-builder@2.1.9: js-yaml "^3.10.0" parse-color "^1.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" + dependencies: + esutils "^2.0.2" + dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -1298,7 +1542,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1313,6 +1557,105 @@ escodegen@1.x.x: optionalDependencies: source-map "~0.5.6" +eslint-config-airbnb-base@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" + dependencies: + eslint-restricted-globals "^0.1.1" + +eslint-import-resolver-node@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" + dependencies: + debug "^2.6.8" + resolve "^1.2.0" + +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-import@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.0.2" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.2" + 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.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + 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.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "^4.0.1" + text-table "~0.2.0" + +espree@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" + dependencies: + acorn "^5.2.1" + acorn-jsx "^3.0.0" + esprima@3.x.x, esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -1325,7 +1668,20 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -estraverse@^4.1.0, estraverse@^4.2.0: +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1361,6 +1717,18 @@ exit@0.1.2, exit@0.1.x, exit@~0.1.1, exit@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + expand-template@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.0.tgz#e09efba977bf98f9ee0ed25abd0c692e02aec3fc" @@ -1381,6 +1749,12 @@ external-editor@^2.0.4: iconv-lite "^0.4.17" tmp "^0.0.33" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + extract-zip@^1.0.3: version "1.6.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.0.tgz#7f400c9607ea866ecab7aa6d54fb978eeb11621a" @@ -1437,6 +1811,13 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + file-sync-cmp@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b" @@ -1455,6 +1836,28 @@ file-url@^1.1.0: dependencies: meow "^3.7.0" +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -1462,7 +1865,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.1.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: @@ -1474,12 +1877,42 @@ findup-sync@~0.3.0: dependencies: glob "~5.0.0" +firstline@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/firstline/-/firstline-1.2.1.tgz#b88673c42009f8821fac2926e99720acee924fae" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + for-each@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" dependencies: is-function "~1.0.0" +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreground-child@^1.5.3, foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -1514,7 +1947,7 @@ fs-extra-p@^4.4.5, fs-extra-p@^4.5.0: bluebird-lst "^1.0.5" fs-extra "^5.0.0" -fs-extra@0.26.7: +fs-extra@0.26.7, fs-extra@^0.26.5: version "0.26.7" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" dependencies: @@ -1565,6 +1998,15 @@ fs-extra@^5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-promise@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-0.5.0.tgz#4347d6bf624655a7061a4319213c393276ad3ef3" + dependencies: + any-promise "^1.0.0" + fs-extra "^0.26.5" + mz "^2.3.1" + thenify-all "^1.6.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1585,6 +2027,14 @@ ftp@~0.3.10: readable-stream "1.1.x" xregexp "2.0.0" +function-bind@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + gauge@~2.7.1, gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1608,6 +2058,10 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -1641,6 +2095,30 @@ github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@7.1.2, glob@^7.0.6, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^5.0.1, glob@~5.0.0: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -1696,6 +2174,14 @@ global@~4.3.0: min-document "^2.19.0" process "~0.5.1" +globals@^11.0.1: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -1743,6 +2229,10 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -1870,6 +2360,16 @@ grunt@^1.0.1: path-is-absolute "~1.0.0" rimraf "~2.2.8" +handlebars@^4.0.3: + version "4.0.11" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" @@ -1910,6 +2410,12 @@ has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + hasha@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" @@ -1935,6 +2441,10 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -2039,6 +2549,10 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" +ignore@^3.3.3: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -2080,7 +2594,7 @@ ini@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inquirer@~3.3.0: +inquirer@^3.0.6, inquirer@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: @@ -2103,6 +2617,12 @@ int64-buffer@^0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.10.tgz#277b228a87d95ad777d07c13832022406a473423" +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -2119,6 +2639,10 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" @@ -2131,6 +2655,24 @@ is-ci@^1.0.10: dependencies: ci-info "^1.0.0" +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" @@ -2151,6 +2693,12 @@ is-function@^1.0.1, is-function@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -2162,6 +2710,18 @@ is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -2182,6 +2742,14 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -2190,6 +2758,10 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-resolvable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -2210,7 +2782,7 @@ isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -isarray@^1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2222,10 +2794,63 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-hook@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.1.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" + dependencies: + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" + dependencies: + handlebars "^4.0.3" + jimp@^0.2.27: version "0.2.27" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.27.tgz#41ef5082d8b63201d54747e04fe8bcacbaf25474" @@ -2264,7 +2889,11 @@ js-base64@^2.1.8: version "2.1.9" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" -js-yaml@^3.10.0, js-yaml@^3.2.7: +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.10.0, js-yaml@^3.2.7, js-yaml@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -2338,6 +2967,10 @@ jsdoctypeparser@~1.2.0: dependencies: lodash "^3.7.0" +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + jshint@~2.9.4: version "2.9.4" resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.4.tgz#5e3ba97848d5290273db514aee47fe24cf592934" @@ -2359,6 +2992,10 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -2413,6 +3050,18 @@ kew@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -2425,6 +3074,10 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + lazy-val@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.2.tgz#d9b07fb1fce54cbc99b3c611de431b83249369b6" @@ -2445,7 +3098,7 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -levn@~0.3.0: +levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" dependencies: @@ -2478,6 +3131,15 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -2493,6 +3155,10 @@ lodash.clonedeep@^4.3.0, lodash.clonedeep@^4.3.2: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + lodash.defaults@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -2549,6 +3215,16 @@ lodash@~4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.6.1.tgz#df00c1164ad236b183cfc3887a5e8d38cc63cbbc" +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -2581,6 +3257,16 @@ map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" +md5-hex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -2606,6 +3292,30 @@ meow@^3.1.0, meow@^3.3.0, meow@^3.7.0: redent "^1.0.0" trim-newlines "^1.0.0" +merge-source-map@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + dependencies: + source-map "^0.6.1" + +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" @@ -2670,7 +3380,7 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -2688,6 +3398,21 @@ mksnapshot@^0.3.0: fs-extra "0.26.7" request "^2.79.0" +mocha@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" + dependencies: + browser-stdout "1.3.0" + commander "2.11.0" + debug "3.1.0" + diff "3.3.1" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + mkdirp "0.5.1" + supports-color "4.4.0" + moment@^2.10.6: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" @@ -2712,6 +3437,14 @@ mv@~2: ncp "~2.0.0" rimraf "~2.4.0" +mz@^2.3.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nan@^2.0.0, nan@^2.3.2, nan@^2.3.3: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" @@ -2720,6 +3453,10 @@ nan@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + natural-compare@~1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.2.2.tgz#1f96d60e3141cac1b6d05653ce0daeac763af6aa" @@ -2843,7 +3580,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package- semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.0: +normalize-path@^2.0.0, normalize-path@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: @@ -2893,6 +3630,38 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" +nyc@^11.4.1: + version "11.4.1" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.4.1.tgz#13fdf7e7ef22d027c61d174758f6978a68f4f5e5" + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^1.0.0" + convert-source-map "^1.3.0" + debug-log "^1.0.1" + default-require-extensions "^1.0.0" + find-cache-dir "^0.1.1" + find-up "^2.1.0" + foreground-child "^1.5.3" + glob "^7.0.6" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.1.0" + istanbul-lib-instrument "^1.9.1" + istanbul-lib-report "^1.1.2" + istanbul-lib-source-maps "^1.2.2" + istanbul-reports "^1.1.3" + md5-hex "^1.2.0" + merge-source-map "^1.0.2" + micromatch "^2.3.11" + mkdirp "^0.5.0" + resolve-from "^2.0.0" + rimraf "^2.5.4" + signal-exit "^3.0.1" + spawn-wrap "^1.4.2" + test-exclude "^4.1.1" + yargs "^10.0.3" + yargs-parser "^8.0.0" + oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -2905,6 +3674,13 @@ object-keys@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -2927,14 +3703,14 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -optimist@~0.6.1: +optimist@^0.6.1, optimist@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" dependencies: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.1: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -3041,6 +3817,15 @@ parse-color@^1.0.0: dependencies: color-convert "~0.5.0" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-headers@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" @@ -3072,7 +3857,7 @@ path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -3080,6 +3865,10 @@ path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -3088,6 +3877,16 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + pathval@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-0.1.1.tgz#08f911cdca9cce5942880da7817bc0b723b66d82" @@ -3138,6 +3937,12 @@ pixelmatch@^4.0.0: dependencies: pngjs "^3.0.0" +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" @@ -3160,6 +3965,10 @@ plist@^2.1.0: xmlbuilder "8.2.2" xmldom "0.1.x" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + pn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.0.0.tgz#1cf5a30b0d806cd18f88fc41a6b5d4ad615b3ba9" @@ -3195,6 +4004,10 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + pretty-bytes@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" @@ -3221,6 +4034,10 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + prompt@~0.2.14: version "0.2.14" resolved "https://registry.yarnpkg.com/prompt/-/prompt-0.2.14.tgz#57754f64f543fd7b0845707c818ece618f05ffdc" @@ -3295,6 +4112,13 @@ rabin-bindings@~1.7.4: nan "^2.8.0" prebuild-install "^2.3.0" +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + raw-body@^2.2.0: version "2.3.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" @@ -3339,6 +4163,12 @@ read-config-file@1.2.1: json5 "^0.5.1" lazy-val "^1.0.2" +read-last-lines@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/read-last-lines/-/read-last-lines-1.3.0.tgz#0dd170188d46124a23eb1a87156baf46b315ac4b" + dependencies: + fs-promise "^0.5.0" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -3346,6 +4176,13 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -3354,6 +4191,14 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + read@1.0.x: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" @@ -3416,6 +4261,12 @@ regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + registry-auth-token@^3.0.1: version "3.2.0" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.2.0.tgz#5bf3bd4608a2dd9242542c44d66ad8a5f9cdd3b0" @@ -3432,6 +4283,14 @@ remove-trailing-separator@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" @@ -3506,10 +4365,25 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + reserved-words@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.1.tgz#6f7c15e5e5614c50da961630da46addc87c0cef2" +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + resolve-url@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -3518,6 +4392,12 @@ resolve@^1.1.6, resolve@~1.1.0: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" +resolve@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -3533,11 +4413,17 @@ rgb2hex@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.0.tgz#ccd55f860ae0c5c4ea37504b958e442d8d12325b" +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@~2.2.8: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" -rimraf@^2.6.2: +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -3655,7 +4541,7 @@ shellwords@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" -signal-exit@^3.0.0, signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -3673,6 +4559,12 @@ single-line-log@^1.1.2: dependencies: string-width "^1.0.1" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -3746,7 +4638,7 @@ source-map@^0.1.38: dependencies: amdefine ">=0.0.4" -source-map@^0.4.2: +source-map@^0.4.2, source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: @@ -3756,14 +4648,25 @@ source-map@^0.5.3, source-map@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -source-map@^0.6.0: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" -source-map@~0.5.6: +source-map@~0.5.1, source-map@~0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" @@ -3877,7 +4780,7 @@ string-width@^2.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^3.0.0" -string-width@^2.1.0: +string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -3920,6 +4823,10 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -3951,16 +4858,22 @@ sumchecker@^2.0.1, sumchecker@^2.0.2: dependencies: debug "^2.2.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^4.0.0: +supports-color@4.4.0, supports-color@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" dependencies: has-flag "^2.0.0" +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + supports-color@~5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.0.1.tgz#1c5331f22250c84202805b2f17adf16699f3a39a" @@ -3976,6 +4889,17 @@ svg2png@4.1.0: pn "^1.0.0" yargs "^5.0.0" +table@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + tar-fs@^1.13.0: version "1.16.0" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.0.tgz#e877a25acbcc51d8c790da1c57c9cf439817b896" @@ -4026,6 +4950,32 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +test-exclude@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +thenify-all@^1.0.0, thenify-all@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + dependencies: + any-promise "^1.0.0" + throttleit@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" @@ -4084,6 +5034,10 @@ to-double-quotes@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-double-quotes/-/to-double-quotes-2.0.0.tgz#aaf231d6fa948949f819301bbab4484d8588e4a7" +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + to-single-quotes@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/to-single-quotes/-/to-single-quotes-2.0.1.tgz#7cc29151f0f5f2c41946f119f5932fe554170125" @@ -4114,6 +5068,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" @@ -4140,6 +5098,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2" + type-is@~1.6.10: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" @@ -4157,6 +5119,19 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + underscore.string@~3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da" @@ -4366,7 +5341,7 @@ which@1, which@^1.2.9, which@~1.2.1: dependencies: isexe "^2.0.0" -which@^1.2.10, which@^1.2.12: +which@^1.2.10, which@^1.2.12, which@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -4384,6 +5359,10 @@ widest-line@^1.0.0: dependencies: string-width "^1.0.1" +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" @@ -4400,6 +5379,10 @@ winston@0.8.x: pkginfo "0.3.x" stack-trace "0.0.x" +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" @@ -4427,6 +5410,20 @@ write-file-atomic@^1.1.2: imurmurhash "^0.1.4" slide "^1.1.5" +write-file-atomic@^1.1.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -4570,6 +5567,15 @@ yargs@^6.6.0: y18n "^3.2.1" yargs-parser "^4.2.0" +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + yauzl@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"