diff --git a/.editorconfig b/.editorconfig index 8b7e1b3f4..e732a66da 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,2 @@ [**.ts] -indent_size = 4 +indent_size = 2 diff --git a/.prettierrc.toml b/.prettierrc.toml new file mode 100644 index 000000000..4d9410131 --- /dev/null +++ b/.prettierrc.toml @@ -0,0 +1,3 @@ +singleQuote = true +trailingComma = "es5" +arrowParens = "always" diff --git a/.travis.yml b/.travis.yml index dd297e245..35499b4f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ dist: trusty language: node_js node_js: - - "6.1" + - "7" diff --git a/karma.conf.js b/karma.conf.js index 35515414a..b8c94fac8 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,23 +1,23 @@ -const path = require("path"); -const webpack = require("webpack"); -const webpackConfig = require("./webpack.config")[0]; +const path = require('path'); +const webpack = require('webpack'); +const webpackConfig = require('./webpack.config')[0]; -process.env.CHROME_BIN = require("puppeteer").executablePath(); +process.env.CHROME_BIN = require('puppeteer').executablePath(); module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "", + basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["mocha", "sinon-chai"], + frameworks: ['mocha', 'sinon-chai'], // list of files / patterns to load in the browser - files: ["test/unit/**/*_test.ts"], + files: ['test/unit/**/*_test.ts'], mime: { - "text/x-typescript": ["ts", "tsx"] + 'text/x-typescript': ['ts', 'tsx'], }, // list of files to exclude @@ -26,7 +26,7 @@ module.exports = function(config) { // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - "**/*.ts": ["webpack", "sourcemap"] + '**/*.ts': ['webpack', 'sourcemap'], }, webpack: { @@ -34,27 +34,27 @@ module.exports = function(config) { module: webpackConfig.module, externals: webpackConfig.externals, - devtool: "inline-source-map", + devtool: 'inline-source-map', plugins: [ new webpack.DefinePlugin({ - VERSION: '"0.0.0"' + VERSION: '"0.0.0"', }), new webpack.SourceMapDevToolPlugin({ filename: null, - test: /\.ts$/ - }) - ] + test: /\.ts$/, + }), + ], }, webpackMiddleware: { - stats: "errors-only" + stats: 'errors-only', }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["spec"], + reporters: ['spec'], // web server port port: 9876, @@ -71,7 +71,7 @@ module.exports = function(config) { // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ["ChromeHeadless"], + browsers: ['ChromeHeadless'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits @@ -79,6 +79,6 @@ module.exports = function(config) { // Concurrency level // how many browser should be started simultaneous - concurrency: 1 + concurrency: 1, }); }; diff --git a/package.json b/package.json index 2668ca364..b90430a7d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/sinon": "5.0.7", "@types/sinon-chai": "3.2.1", "chai": "4.2.0", + "cross-fetch": "^2.2.3", "error-stack-parser": "2.0.2", "imports-loader": "0.8.0", "karma": "3.1.1", @@ -40,12 +41,12 @@ "sinon-chai": "3.3.0", "source-map-loader": "0.2.4", "ts-loader": "5.3.1", - "tslint": "5.11.0", - "tslint-loader": "3.6.0", - "typescript": "3.2.1", + "tslint": "^5.12.0", + "tslint-config-prettier": "^1.17.0", + "tslint-loader": "^3.5.4", + "typescript": "^3.2.2", "webpack": "4.26.1", - "webpack-cli": "3.1.2", - "cross-fetch": "^2.2.3" + "webpack-cli": "3.1.2" }, "main": "dist/client.js", "types": "dist/client.d.ts", diff --git a/src/client.ts b/src/client.ts index ac3ca12f4..283754a4c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,317 +1,331 @@ import 'promise-polyfill/src/polyfill'; -import Notice from './notice'; import FuncWrapper from './func_wrapper'; import jsonifyNotice from './jsonify_notice'; +import Notice from './notice'; import Processor from './processor/processor'; import stacktracejsProcessor from './processor/stacktracejs'; +import angularMessageFilter from './filter/angular_message'; +import makeDebounceFilter from './filter/debounce'; import Filter from './filter/filter'; import ignoreFilter from './filter/ignore'; -import makeDebounceFilter from './filter/debounce'; +import nodeFilter from './filter/node'; import uncaughtMessageFilter from './filter/uncaught_message'; -import angularMessageFilter from './filter/angular_message'; import windowFilter from './filter/window'; -import nodeFilter from './filter/node'; -import {Requester, makeRequester} from './http_req'; +import { makeRequester, Requester } from './http_req'; +import { Historian } from './historian'; import Options from './options'; -import {Historian} from './historian'; -import {Routes, RequestInfo} from './routes'; - +import { IRequestInfo, Routes } from './routes'; declare const VERSION: string; - -interface Todo { - err: any; - resolve: (Notice) => void; - reject: (Error) => void; +interface ITodo { + err: any; + resolve: (notice: Notice) => void; + reject: (err: Error) => void; } - class Client { - private opts: Options; - private url: string; - private historian: Historian; - - private processor: Processor; - private requester: Requester; - private filters: Filter[] = []; - - private offline = false; - private todo: Todo[] = []; - - private routes: Routes; + private opts: Options; + private url: string; + private historian: Historian; - private onClose: (() => void)[] = []; + private processor: Processor; + private requester: Requester; + private filters: Filter[] = []; - constructor(opts: Options = {} as Options) { - if (!opts.projectId || !opts.projectKey) { - throw new Error('airbrake: projectId and projectKey are required'); - } + private offline = false; + private todo: ITodo[] = []; - this.opts = opts; - this.opts.host = this.opts.host || 'https://api.airbrake.io'; - this.opts.timeout = this.opts.timeout || 10000; - this.opts.keysBlacklist = this.opts.keysBlacklist || [ - /password/, - /secret/, - ]; - this.url = `${this.opts.host}/api/v3/projects/${this.opts.projectId}/notices?key=${this.opts.projectKey}`; - - this.processor = this.opts.processor || stacktracejsProcessor; - this.requester = makeRequester(this.opts); - - this.addFilter(ignoreFilter); - this.addFilter(makeDebounceFilter()); - this.addFilter(uncaughtMessageFilter); - this.addFilter(angularMessageFilter); - - if (!this.opts.environment && - typeof process !== 'undefined' && - process.env.NODE_ENV) { - this.opts.environment = process.env.NODE_ENV; - } - if (this.opts.environment) { - this.addFilter((notice: Notice): Notice | null => { - notice.context.environment = this.opts.environment; - return notice; - }); - } + private routes: Routes; - if (typeof window === 'object') { - this.addFilter(windowFilter); - - if (window.addEventListener) { - this.onOnline = this.onOnline.bind(this); - window.addEventListener('online', this.onOnline); - this.onOffline = this.onOffline.bind(this); - window.addEventListener('offline', this.onOffline); - - this.onUnhandledrejection = this.onUnhandledrejection.bind(this); - window.addEventListener( - 'unhandledrejection', this.onUnhandledrejection); - - this.onClose.push(() => { - window.removeEventListener('online', this.onOnline); - window.removeEventListener('offline', this.onOffline); - window.removeEventListener( - 'unhandledrejection', this.onUnhandledrejection); - }); - } - } else { - this.addFilter(nodeFilter); - } + private onClose: Array<() => void> = []; - let historianOpts = opts.instrumentation || {}; - if (typeof historianOpts.console === undefined) { - historianOpts.console = !isDevEnv(opts.environment); - } - - this.historian = Historian.instance(historianOpts); - this.historian.registerNotifier(this); + constructor(opts: Options) { + if (!opts.projectId || !opts.projectKey) { + throw new Error('airbrake: projectId and projectKey are required'); } - close(): void { - for (let fn of this.onClose) { - fn(); + this.opts = opts; + this.opts.host = this.opts.host || 'https://api.airbrake.io'; + this.opts.timeout = this.opts.timeout || 10000; + this.opts.keysBlacklist = this.opts.keysBlacklist || [/password/, /secret/]; + this.url = `${this.opts.host}/api/v3/projects/${ + this.opts.projectId + }/notices?key=${this.opts.projectKey}`; + + this.processor = this.opts.processor || stacktracejsProcessor; + this.requester = makeRequester(this.opts); + + this.addFilter(ignoreFilter); + this.addFilter(makeDebounceFilter()); + this.addFilter(uncaughtMessageFilter); + this.addFilter(angularMessageFilter); + + if ( + !this.opts.environment && + typeof process !== 'undefined' && + process.env.NODE_ENV + ) { + this.opts.environment = process.env.NODE_ENV; + } + if (this.opts.environment) { + this.addFilter( + (notice: Notice): Notice | null => { + notice.context.environment = this.opts.environment; + return notice; } - this.historian.unregisterNotifier(this); + ); } - addFilter(filter: Filter): void { - this.filters.push(filter); + if (typeof window === 'object') { + this.addFilter(windowFilter); + + if (window.addEventListener) { + this.onOnline = this.onOnline.bind(this); + window.addEventListener('online', this.onOnline); + this.onOffline = this.onOffline.bind(this); + window.addEventListener('offline', this.onOffline); + + this.onUnhandledrejection = this.onUnhandledrejection.bind(this); + window.addEventListener( + 'unhandledrejection', + this.onUnhandledrejection + ); + + this.onClose.push(() => { + window.removeEventListener('online', this.onOnline); + window.removeEventListener('offline', this.onOffline); + window.removeEventListener( + 'unhandledrejection', + this.onUnhandledrejection + ); + }); + } + } else { + this.addFilter(nodeFilter); } - notify(err: any): Promise { - let notice: Notice = { - id: '', - errors: [], - context: Object.assign({ - severity: 'error' - }, err.context), - params: err.params || {}, - environment: err.environment || {}, - session: err.session || {}, - }; - - if (typeof err !== 'object' || err.error === undefined) { - err = {error: err}; - } - - if (!err.error) { - notice.error = new Error( - `airbrake: got err=${JSON.stringify(err.error)}, wanted an Error`); - return Promise.resolve(notice); - } - - if (this.opts.ignoreWindowError && err.context && err.context.windowError) { - notice.error = new Error('airbrake: window error is ignored'); - return Promise.resolve(notice); - } - - if (this.offline) { - return new Promise((resolve, reject) => { - this.todo.push({ - err: err, - resolve: resolve, - reject: reject, - }); - while (this.todo.length > 100) { - let j = this.todo.shift(); - if (j === undefined) { - break; - } - notice.error = new Error('airbrake: offline queue is too large'); - j.resolve(notice); - } - }); - } - - let history = this.historian.getHistory(); - if (history.length > 0) { - notice.context.history = history; - } - - let error = this.processor(err.error); - notice.errors.push(error); + let historianOpts = opts.instrumentation || {}; + if (typeof historianOpts.console === undefined) { + historianOpts.console = !isDevEnv(opts.environment); + } - for (let filter of this.filters) { - let r = filter(notice); - if (r === null) { - notice.error = new Error('airbrake: error is filtered'); - return Promise.resolve(notice); - } - notice = r; - } + this.historian = Historian.instance(historianOpts); + this.historian.registerNotifier(this); + } - if (!notice.context) { - notice.context = {}; - } - notice.context.language = 'JavaScript'; - notice.context.notifier = { - name: 'airbrake-js', - version: VERSION, - url: 'https://github.com/airbrake/airbrake-js' - }; - return this.sendNotice(notice); + public close(): void { + for (let fn of this.onClose) { + fn(); + } + this.historian.unregisterNotifier(this); + } + + public addFilter(filter: Filter): void { + this.filters.push(filter); + } + + public notify(err: any): Promise { + let notice: Notice = { + id: '', + errors: [], + context: { + severity: 'error', + ...err.context, + }, + params: err.params || {}, + environment: err.environment || {}, + session: err.session || {}, + }; + + if (typeof err !== 'object' || err.error === undefined) { + err = { error: err }; } - private sendNotice(notice: Notice): Promise { - let body = jsonifyNotice(notice, {keysBlacklist: this.opts.keysBlacklist}); - if (this.opts.reporter) { - return this.opts.reporter(notice); - } + if (!err.error) { + notice.error = new Error( + `airbrake: got err=${JSON.stringify(err.error)}, wanted an Error` + ); + return Promise.resolve(notice); + } - let req = { - method: 'POST', - url: this.url, - body: body, - }; - return this.requester(req).then((resp) => { - notice.id = resp.json.id; - return notice; - }).catch((err) => { - notice.error = err; - return notice; - }); + if (this.opts.ignoreWindowError && err.context && err.context.windowError) { + notice.error = new Error('airbrake: window error is ignored'); + return Promise.resolve(notice); } - // TODO: fix wrapping for multiple clients - wrap(fn, props: string[] = []): FuncWrapper { - if (fn._airbrake) { - return fn; + if (this.offline) { + return new Promise((resolve, reject) => { + this.todo.push({ + err, + resolve, + reject, + }); + while (this.todo.length > 100) { + let j = this.todo.shift(); + if (j === undefined) { + break; + } + notice.error = new Error('airbrake: offline queue is too large'); + j.resolve(notice); } + }); + } - let client = this; - let airbrakeWrapper = function () { - let fnArgs = Array.prototype.slice.call(arguments); - let wrappedArgs = client.wrapArguments(fnArgs); - try { - return fn.apply(this, wrappedArgs); - } catch (err) { - client.notify({error: err, params: {arguments: fnArgs}}); - this.historian.ignoreNextWindowError(); - throw err; - } - } as FuncWrapper; - - for (let prop in fn) { - if (fn.hasOwnProperty(prop)) { - airbrakeWrapper[prop] = fn[prop]; - } - } - for (let prop of props) { - if (fn.hasOwnProperty(prop)) { - airbrakeWrapper[prop] = fn[prop]; - } - } + let history = this.historian.getHistory(); + if (history.length > 0) { + notice.context.history = history; + } - airbrakeWrapper._airbrake = true; - airbrakeWrapper.inner = fn; + let error = this.processor(err.error); + notice.errors.push(error); - return airbrakeWrapper; + for (let filter of this.filters) { + let r = filter(notice); + if (r === null) { + notice.error = new Error('airbrake: error is filtered'); + return Promise.resolve(notice); + } + notice = r; } - private wrapArguments(args: any[]): any[] { - for (let i = 0; i < args.length; i++) { - let arg = args[i]; - if (typeof arg === 'function') { - args[i] = this.wrap(arg); - } - } - return args; + if (!notice.context) { + notice.context = {}; } - - call(fn, ..._args: any[]): any { - let wrapper = this.wrap(fn); - return wrapper.apply(this, Array.prototype.slice.call(arguments, 1)); + notice.context.language = 'JavaScript'; + notice.context.notifier = { + name: 'airbrake-js', + version: VERSION, + url: 'https://github.com/airbrake/airbrake-js', + }; + return this.sendNotice(notice); + } + + private sendNotice(notice: Notice): Promise { + let body = jsonifyNotice(notice, { + keysBlacklist: this.opts.keysBlacklist, + }); + if (this.opts.reporter) { + return this.opts.reporter(notice); } - onerror(): void { - this.historian.onerror.apply(this.historian, arguments); + let req = { + method: 'POST', + url: this.url, + body, + }; + return this.requester(req) + .then((resp) => { + notice.id = resp.json.id; + return notice; + }) + .catch((err) => { + notice.error = err; + return notice; + }); + } + + // TODO: fix wrapping for multiple clients + public wrap(fn, props: string[] = []): FuncWrapper { + if (fn._airbrake) { + return fn; } - notifyRequest(req: RequestInfo): void { - if (!this.routes) { - this.routes = new Routes(this.opts); - } - this.routes.notifyRequest(req); + // tslint:disable-next-line:no-this-assignment + let client = this; + let airbrakeWrapper = function() { + let fnArgs = Array.prototype.slice.call(arguments); + let wrappedArgs = client.wrapArguments(fnArgs); + try { + return fn.apply(this, wrappedArgs); + } catch (err) { + client.notify({ error: err, params: { arguments: fnArgs } }); + this.historian.ignoreNextWindowError(); + throw err; + } + } as FuncWrapper; + + for (let prop in fn) { + if (fn.hasOwnProperty(prop)) { + airbrakeWrapper[prop] = fn[prop]; + } + } + for (let prop of props) { + if (fn.hasOwnProperty(prop)) { + airbrakeWrapper[prop] = fn[prop]; + } } - private onOnline(): void { - this.offline = false; + airbrakeWrapper._airbrake = true; + airbrakeWrapper.inner = fn; - for (let j of this.todo) { - this.notify(j.err).then((notice) => { - j.resolve(notice); - }); - } - this.todo = []; + return airbrakeWrapper; + } + + private wrapArguments(args: any[]): any[] { + for (let i = 0; i < args.length; i++) { + let arg = args[i]; + if (typeof arg === 'function') { + args[i] = this.wrap(arg); + } } + return args; + } + + public call(fn, ..._args: any[]): any { + let wrapper = this.wrap(fn); + return wrapper.apply(this, Array.prototype.slice.call(arguments, 1)); + } + + public onerror(): void { + this.historian.onerror.apply(this.historian, arguments); + } - private onOffline(): void { - this.offline = true; + public notifyRequest(req: IRequestInfo): void { + if (!this.routes) { + this.routes = new Routes(this.opts); } + this.routes.notifyRequest(req); + } - private onUnhandledrejection(e: PromiseRejectionEvent | CustomEvent): void { - // Handle native or bluebird Promise rejections - // https://developer.mozilla.org/en-US/docs/Web/Events/unhandledrejection - // http://bluebirdjs.com/docs/api/error-management-configuration.html - let reason = (e).reason || (e).detail && (e).detail.reason || 'unhandled rejection with no reason given'; - let msg = reason.message || String(reason); - if (msg.indexOf && msg.indexOf('airbrake: ') === 0) { - return; - } - this.notify(reason); + private onOnline(): void { + this.offline = false; + + for (let j of this.todo) { + this.notify(j.err).then((notice) => { + j.resolve(notice); + }); + } + this.todo = []; + } + + private onOffline(): void { + this.offline = true; + } + + private onUnhandledrejection(e: PromiseRejectionEvent | CustomEvent): void { + // Handle native or bluebird Promise rejections + // https://developer.mozilla.org/en-US/docs/Web/Events/unhandledrejection + // http://bluebirdjs.com/docs/api/error-management-configuration.html + let reason = + (e as PromiseRejectionEvent).reason || + ((e as CustomEvent).detail && (e as CustomEvent).detail.reason) || + 'unhandled rejection with no reason given'; + let msg = reason.message || String(reason); + if (msg.indexOf && msg.indexOf('airbrake: ') === 0) { + return; } + this.notify(reason); + } } function isDevEnv(env: any): boolean { - return env && env.startsWith && env.startsWith('dev'); + return env && env.startsWith && env.startsWith('dev'); } export = Client; diff --git a/src/filter/angular_message.ts b/src/filter/angular_message.ts index d3bc12552..46cac34d1 100644 --- a/src/filter/angular_message.ts +++ b/src/filter/angular_message.ts @@ -1,26 +1,26 @@ import Notice from '../notice'; - -let re = new RegExp([ +let re = new RegExp( + [ '^', '\\[(\\$.+)\\]', // type '\\s', - '([\\s\\S]+)', // message + '([\\s\\S]+)', // message '$', -].join('')); - + ].join('') +); export default function filter(notice: Notice): Notice { - let err = notice.errors[0]; - if (err.type !== '' && err.type !== 'Error') { - return notice; - } + let err = notice.errors[0]; + if (err.type !== '' && err.type !== 'Error') { + return notice; + } - let m = err.message.match(re); - if (m !== null) { - err.type = m[1]; - err.message = m[2]; - } + let m = err.message.match(re); + if (m !== null) { + err.type = m[1]; + err.message = m[2]; + } - return notice; + return notice; } diff --git a/src/filter/debounce.ts b/src/filter/debounce.ts index d883fdddf..3b52a7ed9 100644 --- a/src/filter/debounce.ts +++ b/src/filter/debounce.ts @@ -1,25 +1,25 @@ -import Filter from './filter'; import Notice from '../notice'; +import Filter from './filter'; export default function makeFilter(): Filter { - let lastNoticeJSON: string; - let timeout; + let lastNoticeJSON: string; + let timeout; - return function(notice: Notice): Notice | null { - let s = JSON.stringify(notice.errors); - if (s === lastNoticeJSON) { - return null; - } + return (notice: Notice): Notice | null => { + let s = JSON.stringify(notice.errors); + if (s === lastNoticeJSON) { + return null; + } - if (timeout) { - clearTimeout(timeout); - } + if (timeout) { + clearTimeout(timeout); + } - lastNoticeJSON = s; - timeout = setTimeout(() => { - lastNoticeJSON = ''; - }, 1000); + lastNoticeJSON = s; + timeout = setTimeout(() => { + lastNoticeJSON = ''; + }, 1000); - return notice; - }; + return notice; + }; } diff --git a/src/filter/filter.ts b/src/filter/filter.ts index ba468d8c7..a82421fcf 100644 --- a/src/filter/filter.ts +++ b/src/filter/filter.ts @@ -1,5 +1,4 @@ import Notice from '../notice'; - export type Filter = (notice: Notice) => Notice | null; export default Filter; diff --git a/src/filter/ignore.ts b/src/filter/ignore.ts index 45e877c7f..eba9c8e55 100644 --- a/src/filter/ignore.ts +++ b/src/filter/ignore.ts @@ -1,24 +1,23 @@ import Notice from '../notice'; - const IGNORED_MESSAGES = [ - 'Script error', - 'Script error.', - 'InvalidAccessError', + 'Script error', + 'Script error.', + 'InvalidAccessError', ]; export default function filter(notice: Notice): Notice | null { - let err = notice.errors[0]; - if (err.type === '' && IGNORED_MESSAGES.indexOf(err.message) !== -1) { - return null; - } + let err = notice.errors[0]; + if (err.type === '' && IGNORED_MESSAGES.indexOf(err.message) !== -1) { + return null; + } - if (err.backtrace && err.backtrace.length > 0) { - let frame = err.backtrace[0]; - if (frame.file === '') { - return null; - } + if (err.backtrace && err.backtrace.length > 0) { + let frame = err.backtrace[0]; + if (frame.file === '') { + return null; } + } - return notice; + return notice; } diff --git a/src/filter/node.ts b/src/filter/node.ts index 6d5c6d49c..0415e7f30 100644 --- a/src/filter/node.ts +++ b/src/filter/node.ts @@ -1,44 +1,45 @@ import Notice from '../notice'; - export default function filter(notice: Notice): Notice { - let os; - try { - os = require('os'); - } catch (_) {} - - if (os) { - notice.context.os = `${os.type()}/${os.release()}`; - notice.context.architecture = os.arch(); - notice.context.hostname = os.hostname(); + let os; + try { + os = require('os'); + } catch (_) { + // ignore + } - notice.params.os = { - homedir: os.homedir(), - uptime: os.uptime(), - freemem: os.freemem(), - totalmem: os.totalmem(), - loadavg: os.loadavg(), - }; - } + if (os) { + notice.context.os = `${os.type()}/${os.release()}`; + notice.context.architecture = os.arch(); + notice.context.hostname = os.hostname(); - if (process) { - notice.context.platform = process.platform; - if (!notice.context.rootDirectory) { - notice.context.rootDirectory = process.cwd(); - } + notice.params.os = { + homedir: os.homedir(), + uptime: os.uptime(), + freemem: os.freemem(), + totalmem: os.totalmem(), + loadavg: os.loadavg(), + }; + } - notice.params.process = { - pid: process.pid, - cwd: process.cwd(), - execPath: process.execPath, - argv: process.argv, - }; - ['uptime', 'cpuUsage', 'memoryUsage'].map((name) => { - if (process[name]) { - notice.params.process[name] = process[name](); - } - }); + if (process) { + notice.context.platform = process.platform; + if (!notice.context.rootDirectory) { + notice.context.rootDirectory = process.cwd(); } - return notice; + notice.params.process = { + pid: process.pid, + cwd: process.cwd(), + execPath: process.execPath, + argv: process.argv, + }; + ['uptime', 'cpuUsage', 'memoryUsage'].map((name) => { + if (process[name]) { + notice.params.process[name] = process[name](); + } + }); + } + + return notice; } diff --git a/src/filter/uncaught_message.ts b/src/filter/uncaught_message.ts index 64614fc85..f91a15f43 100644 --- a/src/filter/uncaught_message.ts +++ b/src/filter/uncaught_message.ts @@ -1,27 +1,27 @@ import Notice from '../notice'; - -let re = new RegExp([ +let re = new RegExp( + [ '^', 'Uncaught\\s', - '(.+?)', // type + '(.+?)', // type ':\\s', - '(.+)', // message + '(.+)', // message '$', -].join('')); - + ].join('') +); export default function filter(notice: Notice): Notice { - let err = notice.errors[0]; - if (err.type !== '' && err.type !== 'Error') { - return notice; - } + let err = notice.errors[0]; + if (err.type !== '' && err.type !== 'Error') { + return notice; + } - let m = err.message.match(re); - if (m !== null) { - err.type = m[1]; - err.message = m[2]; - } + let m = err.message.match(re); + if (m !== null) { + err.type = m[1]; + err.message = m[2]; + } - return notice; + return notice; } diff --git a/src/filter/window.ts b/src/filter/window.ts index 64ba8f85b..5e36ea0ae 100644 --- a/src/filter/window.ts +++ b/src/filter/window.ts @@ -1,14 +1,14 @@ import Notice from '../notice'; - export default function filter(notice: Notice): Notice { - if (window.navigator && window.navigator.userAgent) { - notice.context.userAgent = window.navigator.userAgent; - } - if (window.location) { - notice.context.url = String(window.location); - // Set root directory to group errors on different subdomains together. - notice.context.rootDirectory = window.location.protocol + '//' + window.location.host; - } - return notice; + if (window.navigator && window.navigator.userAgent) { + notice.context.userAgent = window.navigator.userAgent; + } + if (window.location) { + notice.context.url = String(window.location); + // Set root directory to group errors on different subdomains together. + notice.context.rootDirectory = + window.location.protocol + '//' + window.location.host; + } + return notice; } diff --git a/src/func_wrapper.ts b/src/func_wrapper.ts index e44cbccbc..c6930b8f9 100644 --- a/src/func_wrapper.ts +++ b/src/func_wrapper.ts @@ -1,7 +1,7 @@ interface FuncWrapper { - (): any; - inner: () => any; - _airbrake?: boolean; + (): any; + inner: () => any; + _airbrake?: boolean; } export default FuncWrapper; diff --git a/src/historian.ts b/src/historian.ts index f7795e914..3310af19d 100644 --- a/src/historian.ts +++ b/src/historian.ts @@ -1,417 +1,419 @@ import FuncWrapper from './func_wrapper'; +import { makeEventHandler } from './instrumentation/dom'; import Notice from './notice'; import Notifier from './notifier'; -import {makeEventHandler} from './instrumentation/dom'; - const CONSOLE_METHODS = ['debug', 'log', 'info', 'warn', 'error']; - -interface XMLHttpRequestWithState extends XMLHttpRequest { - __state: any; +interface IXMLHttpRequestWithState extends XMLHttpRequest { + __state: any; } -export interface HistorianOptions { - onerror?: boolean; - fetch?: boolean; - history?: boolean; - console?: boolean; - xhr?: boolean; +export interface IHistorianOptions { + onerror?: boolean; + fetch?: boolean; + history?: boolean; + console?: boolean; + xhr?: boolean; } export class Historian { - private static _instance: Historian; + private static _instance: Historian; - private historyMaxLen = 20; + private historyMaxLen = 20; - private notifiers: Notifier[] = []; + private notifiers: Notifier[] = []; - private errors: any[] = []; - private ignoreWindowError = 0; + private errors: any[] = []; + private ignoreWindowError = 0; - private history: any[] = []; - private lastState: any; - private lastLocation: string | null; - private ignoreNextXHR = 0; + private history: any[] = []; + private lastState: any; + private lastLocation: string | null; + private ignoreNextXHR = 0; - private consoleError: (message?: any, ...optionalParams: any[]) => void; + private consoleError: (message?: any, ...optionalParams: any[]) => void; - constructor(opts: HistorianOptions = {} as HistorianOptions) { - if (enabled(opts.console) && typeof console === 'object' && console.error) { - this.consoleError = console.error; - } + constructor(opts: IHistorianOptions = {}) { + if (enabled(opts.console) && typeof console === 'object' && console.error) { + this.consoleError = console.error; + } - if (typeof window === 'object') { - if (enabled(opts.onerror)) { - let self = this; - let oldHandler = window.onerror; - window.onerror = function() { - if (oldHandler) { - oldHandler.apply(this, arguments); - } - self.onerror.apply(self, arguments); - }; - } - - this.domEvents(); - if (enabled(opts.fetch) && typeof fetch === 'function') { - this.fetch(); - } - if (enabled(opts.history) && typeof history === 'object') { - this.location(); - } - } + if (typeof window === 'object') { + if (enabled(opts.onerror)) { + // tslint:disable-next-line:no-this-assignment + let self = this; + let oldHandler = window.onerror; + window.onerror = function() { + if (oldHandler) { + oldHandler.apply(this, arguments); + } + self.onerror.apply(self, arguments); + }; + } + + this.domEvents(); + if (enabled(opts.fetch) && typeof fetch === 'function') { + this.fetch(); + } + if (enabled(opts.history) && typeof history === 'object') { + this.location(); + } + } - if (typeof process === 'object' && typeof process.on === 'function') { - process.on('uncaughtException', (err) => { - this.notify(err).then(() => { - if (process.listeners('uncaughtException').length !== 1) { - return; - } - if (this.consoleError) { - this.consoleError('uncaught exception', err); - } - process.exit(1); - }); - }); - process.on('unhandledRejection', (reason: Error, _p) => { - let msg = reason.message || String(reason); - if (msg.indexOf && msg.indexOf('airbrake: ') === 0) { - return; - } - - this.notify(reason).then(() => { - if (process.listeners('unhandledRejection').length !== 1) { - return; - } - if (this.consoleError) { - this.consoleError('unhandled rejection', reason); - } - process.exit(1); - }); - }); + if (typeof process === 'object' && typeof process.on === 'function') { + process.on('uncaughtException', (err) => { + this.notify(err).then(() => { + if (process.listeners('uncaughtException').length !== 1) { + return; + } + if (this.consoleError) { + this.consoleError('uncaught exception', err); + } + process.exit(1); + }); + }); + process.on('unhandledRejection', (reason: Error, _p) => { + let msg = reason.message || String(reason); + if (msg.indexOf && msg.indexOf('airbrake: ') === 0) { + return; } - if (enabled(opts.console) && typeof console === 'object') { - this.console(); - } - if (enabled(opts.xhr) && typeof XMLHttpRequest !== 'undefined') { - this.xhr(); - } + this.notify(reason).then(() => { + if (process.listeners('unhandledRejection').length !== 1) { + return; + } + if (this.consoleError) { + this.consoleError('unhandled rejection', reason); + } + process.exit(1); + }); + }); } - static instance(opts: HistorianOptions = {} as HistorianOptions): Historian { - if (!Historian._instance) { - Historian._instance = new Historian(opts); - } - return Historian._instance; + if (enabled(opts.console) && typeof console === 'object') { + this.console(); } - - registerNotifier(notifier: Notifier) { - this.notifiers.push(notifier); - - for (let err of this.errors) { - this.notifyNotifiers(err); - } - this.errors = []; + if (enabled(opts.xhr) && typeof XMLHttpRequest !== 'undefined') { + this.xhr(); } + } - unregisterNotifier(notifier: Notifier) { - let i = this.notifiers.indexOf(notifier); - if (i !== -1) { - this.notifiers.splice(i, 1); - } + public static instance(opts: IHistorianOptions = {}): Historian { + if (!Historian._instance) { + Historian._instance = new Historian(opts); } + return Historian._instance; + } - notify(err: any): Promise { - if (this.notifiers.length > 0) { - return this.notifyNotifiers(err); - } - - this.errors.push(err); - if (this.errors.length > this.historyMaxLen) { - this.errors = this.errors.slice(-this.historyMaxLen); - } + public registerNotifier(notifier: Notifier) { + this.notifiers.push(notifier); - return Promise.resolve({} as Notice); + for (let err of this.errors) { + this.notifyNotifiers(err); } + this.errors = []; + } - private notifyNotifiers(err: any): Promise { - let promises: Promise[] = []; - for (let notifier of this.notifiers) { - promises.push(notifier.notify(err)); - } - return Promise.all(promises).then((notices) => { - return notices[0]; - }); + public unregisterNotifier(notifier: Notifier) { + let i = this.notifiers.indexOf(notifier); + if (i !== -1) { + this.notifiers.splice(i, 1); } + } - onerror( - message: string, - filename?: string, - line?: number, - column?: number, - err?: Error - ): void { - if (this.ignoreWindowError > 0) { - return; - } + public notify(err: any): Promise { + if (this.notifiers.length > 0) { + return this.notifyNotifiers(err); + } - if (err) { - this.notify({ - error: err, - context: { - windowError: true, - }, - }); - return; - } + this.errors.push(err); + if (this.errors.length > this.historyMaxLen) { + this.errors = this.errors.slice(-this.historyMaxLen); + } - // Ignore errors without file or line. - if (!filename || !line) { - return; - } + return Promise.resolve(null); + } - this.notify({ - error: { - message: message, - fileName: filename, - lineNumber: line, - columnNumber: column, - noStack: true, - }, - context: { - windowError: true, - }, - }); + private notifyNotifiers(err: any): Promise { + let promises: Array> = []; + for (let notifier of this.notifiers) { + promises.push(notifier.notify(err)); } - - ignoreNextWindowError(): void { - this.ignoreWindowError++; - setTimeout(() => this.ignoreWindowError--); + return Promise.all(promises).then((notices) => { + return notices[0]; + }); + } + + public onerror( + message: string, + filename?: string, + line?: number, + column?: number, + err?: Error + ): void { + if (this.ignoreWindowError > 0) { + return; } - getHistory(): any[] { - return this.history; + if (err) { + this.notify({ + error: err, + context: { + windowError: true, + }, + }); + return; } - pushHistory(state: any): void { - if (this.isDupState(state)) { - if (this.lastState.num) { - this.lastState.num++; - } else { - this.lastState.num = 2; - } - return; - } - - if (!state.date) { - state.date = new Date(); - } - this.history.push(state); - this.lastState = state; - - if (this.history.length > this.historyMaxLen) { - this.history = this.history.slice(-this.historyMaxLen); - } + // Ignore errors without file or line. + if (!filename || !line) { + return; } - private isDupState(state): boolean { - if (!this.lastState) { - return false; - } - for (let key in state) { - if (!state.hasOwnProperty(key) || key === 'date') { - continue; - } - if (state[key] !== this.lastState[key]) { - return false; - } - } - return true; + this.notify({ + error: { + message, + fileName: filename, + lineNumber: line, + columnNumber: column, + noStack: true, + }, + context: { + windowError: true, + }, + }); + } + + public ignoreNextWindowError(): void { + this.ignoreWindowError++; + setTimeout(() => this.ignoreWindowError--); + } + + public getHistory(): any[] { + return this.history; + } + + public pushHistory(state: any): void { + if (this.isDupState(state)) { + if (this.lastState.num) { + this.lastState.num++; + } else { + this.lastState.num = 2; + } + return; } - domEvents(): void { - let handler = makeEventHandler(this); - - if (window.addEventListener) { - window.addEventListener('load', handler); - window.addEventListener('error', function(event: Event): void { - if ('error' in event) { - return; - } - handler(event); - }, true); - } - - if (typeof document === 'object' && document.addEventListener) { - document.addEventListener('DOMContentLoaded', handler); - document.addEventListener('click', handler); - document.addEventListener('keypress', handler); - } + if (!state.date) { + state.date = new Date(); } + this.history.push(state); + this.lastState = state; - console(): void { - let client = this; - for (let m of CONSOLE_METHODS) { - if (!(m in console)) { - continue; - } - - let oldFn = console[m]; - let newFn = function () { - oldFn.apply(console, arguments); - client.pushHistory({ - type: 'log', - severity: m, - arguments: Array.prototype.slice.call(arguments), - }); - } as FuncWrapper; - newFn.inner = oldFn; - console[m] = newFn; - } + if (this.history.length > this.historyMaxLen) { + this.history = this.history.slice(-this.historyMaxLen); } + } - unwrapConsole(): void { - for (let m of CONSOLE_METHODS) { - if (m in console && console[m].inner) { - console[m] = console[m].inner; - } - } + private isDupState(state): boolean { + if (!this.lastState) { + return false; } - - fetch(): void { - let client = this; - let oldFetch = window.fetch; - window.fetch = function(input: RequestInfo, init?: RequestInit): Promise { - let state: any = { - type: 'xhr', - date: new Date(), - }; - - if (typeof input === 'string') { - state.url = input; - } else { - state.url = input.url; - } - - if (init && init.method) { - state.method = init.method; - } else { - state.method = 'GET'; - } - - // Some platforms (e.g. react-native) implement fetch via XHR. - client.ignoreNextXHR++; - setTimeout(() => client.ignoreNextXHR--); - - return oldFetch.apply(this, arguments) - .then(function(resp: Response) { - state.statusCode = resp.status; - state.duration = new Date().getTime() - state.date.getTime(); - client.pushHistory(state); - return resp; - }) - .catch(function(err) { - state.error = err; - state.duration = new Date().getTime() - state.date.getTime(); - client.pushHistory(state); - throw err; - }); - }; + for (let key in state) { + if (!state.hasOwnProperty(key) || key === 'date') { + continue; + } + if (state[key] !== this.lastState[key]) { + return false; + } } - - xhr(): void { - let client = this; - - let oldOpen = XMLHttpRequest.prototype.open; - XMLHttpRequest.prototype.open = function( - method: string, - url: string, - _async?: boolean, - _user?: string, - _password?: string - ): void { - if (client.ignoreNextXHR === 0) { - this.__state = { - type: 'xhr', - method: method, - url: url, - }; - } - oldOpen.apply(this, arguments); - }; - - let oldSend = XMLHttpRequest.prototype.send; - XMLHttpRequest.prototype.send = function(_data?: any): void { - let oldFn = this.onreadystatechange; - this.onreadystatechange = function(_ev: Event): any { - if (this.readyState === 4 && this.__state) { - client.recordReq(this); - } - if (oldFn) { - return oldFn.apply(this, arguments); - } - }; - - if (this.__state) { - (this as XMLHttpRequestWithState).__state.date = new Date(); - } - return oldSend.apply(this, arguments); - }; + return true; + } + + public domEvents(): void { + let handler = makeEventHandler(this); + + if (window.addEventListener) { + window.addEventListener('load', handler); + window.addEventListener( + 'error', + (event: Event): void => { + if ('error' in event) { + return; + } + handler(event); + }, + true + ); } - private recordReq(req: XMLHttpRequestWithState): void { - let state = req.__state; - state.statusCode = req.status; - state.duration = new Date().getTime() - state.date.getTime(); - this.pushHistory(state); + if (typeof document === 'object' && document.addEventListener) { + document.addEventListener('DOMContentLoaded', handler); + document.addEventListener('click', handler); + document.addEventListener('keypress', handler); } - - location(): void { - this.lastLocation = document.location.pathname; - - let client = this; - let oldFn = window.onpopstate; - window.onpopstate = function(_event: PopStateEvent): any { - client.recordLocation(document.location.pathname); - if (oldFn) { - return oldFn.apply(this, arguments); - } - }; - - let oldPushState = history.pushState; - history.pushState = function(_state: any, _title: string, url?: string | null): void { - if (url) { - client.recordLocation(url.toString()); - } - oldPushState.apply(this, arguments); - }; + } + + public console(): void { + // tslint:disable-next-line:no-this-assignment + let client = this; + for (let m of CONSOLE_METHODS) { + if (!(m in console)) { + continue; + } + + let oldFn = console[m]; + let newFn = ((...args) => { + oldFn.apply(console, args); + client.pushHistory({ + type: 'log', + severity: m, + arguments: args, + }); + }) as FuncWrapper; + newFn.inner = oldFn; + console[m] = newFn; } + } - private recordLocation(url: string): void { - let index = url.indexOf('://'); - if (index >= 0) { - url = url.slice(index + 3); - index = url.indexOf('/'); - if (index >= 0) { - url = url.slice(index); - } else { - url = '/'; - } - } else if (url.charAt(0) !== '/') { - url = '/' + url; - } - - this.pushHistory({ - type: 'location', - from: this.lastLocation, - to: url, + public unwrapConsole(): void { + for (let m of CONSOLE_METHODS) { + if (m in console && console[m].inner) { + console[m] = console[m].inner; + } + } + } + + public fetch(): void { + // tslint:disable-next-line:no-this-assignment + let client = this; + let oldFetch = window.fetch; + window.fetch = function( + input: RequestInfo, + init?: RequestInit + ): Promise { + let state: any = { + type: 'xhr', + date: new Date(), + }; + + state.url = typeof input === 'string' ? input : input.url; + state.method = init && init.method ? init.method : 'GET'; + + // Some platforms (e.g. react-native) implement fetch via XHR. + client.ignoreNextXHR++; + setTimeout(() => client.ignoreNextXHR--); + + return oldFetch + .apply(this, arguments) + .then((resp: Response) => { + state.statusCode = resp.status; + state.duration = new Date().getTime() - state.date.getTime(); + client.pushHistory(state); + return resp; + }) + .catch((err) => { + state.error = err; + state.duration = new Date().getTime() - state.date.getTime(); + client.pushHistory(state); + throw err; }); - this.lastLocation = url; + }; + } + + public xhr(): void { + // tslint:disable-next-line:no-this-assignment + let client = this; + + let oldOpen = XMLHttpRequest.prototype.open; + XMLHttpRequest.prototype.open = function( + method: string, + url: string, + _async?: boolean, + _user?: string, + _password?: string + ): void { + if (client.ignoreNextXHR === 0) { + this.__state = { + type: 'xhr', + method, + url, + }; + } + oldOpen.apply(this, arguments); + }; + + let oldSend = XMLHttpRequest.prototype.send; + XMLHttpRequest.prototype.send = function(_data?: any): void { + let oldFn = this.onreadystatechange; + this.onreadystatechange = function(_ev: Event): any { + if (this.readyState === 4 && this.__state) { + client.recordReq(this); + } + if (oldFn) { + return oldFn.apply(this, arguments); + } + }; + + if (this.__state) { + (this as IXMLHttpRequestWithState).__state.date = new Date(); + } + return oldSend.apply(this, arguments); + }; + } + + private recordReq(req: IXMLHttpRequestWithState): void { + let state = req.__state; + state.statusCode = req.status; + state.duration = new Date().getTime() - state.date.getTime(); + this.pushHistory(state); + } + + public location(): void { + this.lastLocation = document.location.pathname; + + // tslint:disable-next-line:no-this-assignment + let client = this; + let oldFn = window.onpopstate; + window.onpopstate = function(_event: PopStateEvent): any { + client.recordLocation(document.location.pathname); + if (oldFn) { + return oldFn.apply(this, arguments); + } + }; + + let oldPushState = history.pushState; + history.pushState = function( + _state: any, + _title: string, + url?: string | null + ): void { + if (url) { + client.recordLocation(url.toString()); + } + oldPushState.apply(this, arguments); + }; + } + + private recordLocation(url: string): void { + let index = url.indexOf('://'); + if (index >= 0) { + url = url.slice(index + 3); + index = url.indexOf('/'); + url = index >= 0 ? url.slice(index) : '/'; + } else if (url.charAt(0) !== '/') { + url = '/' + url; } + + this.pushHistory({ + type: 'location', + from: this.lastLocation, + to: url, + }); + this.lastLocation = url; + } } -function enabled(v: undefined|boolean): boolean { - return v === undefined || v === true; +function enabled(v: undefined | boolean): boolean { + return v === undefined || v === true; } diff --git a/src/http_req/fetch.ts b/src/http_req/fetch.ts index fb5c02176..4d106a0e5 100644 --- a/src/http_req/fetch.ts +++ b/src/http_req/fetch.ts @@ -1,60 +1,62 @@ +// tslint:disable-next-line:no-var-requires let fetch = require('cross-fetch'); -import {HttpRequest, HttpResponse, errors} from './index'; - +import { errors, IHttpRequest, IHttpResponse } from './index'; let rateLimitReset = 0; +export function request(req: IHttpRequest): Promise { + let utime = Date.now() / 1000; + if (utime < rateLimitReset) { + return Promise.reject(errors.ipRateLimited); + } + + let opt = { + method: req.method, + body: req.body, + }; + return fetch(req.url, opt).then((resp: Response) => { + if (resp.status === 401) { + throw errors.unauthorized; + } + + if (resp.status === 429) { + let s = resp.headers.get('X-RateLimit-Delay'); + if (!s) { + throw errors.ipRateLimited; + } + + let n = parseInt(s, 10); + if (n > 0) { + rateLimitReset = Date.now() / 1000 + n; + } + + throw errors.ipRateLimited; + } + + if (resp.status === 204) { + return { json: null }; + } + if (resp.status >= 200 && resp.status < 300) { + return resp.json().then((json) => { + return { json }; + }); + } -export function request(req: HttpRequest): Promise { - let utime = Date.now() / 1000; - if (utime < rateLimitReset) { - return Promise.reject(errors.ipRateLimited); + if (resp.status >= 400 && resp.status < 500) { + return resp.json().then((json) => { + let err = new Error(json.message); + throw err; + }); } - let opt = { - method: req.method, - body: req.body, - }; - return fetch(req.url, opt).then((resp: Response) => { - if (resp.status === 401) { - throw errors.unauthorized; - } - - if (resp.status === 429) { - let s = resp.headers.get('X-RateLimit-Delay'); - if (!s) { - throw errors.ipRateLimited; - } - - let n = parseInt(s, 10); - if (n > 0) { - rateLimitReset = Date.now() / 1000 + n; - } - - throw errors.ipRateLimited; - } - - if (resp.status === 204) { - return {json: null}; - } - if (resp.status >= 200 && resp.status < 300) { - return resp.json().then((json) => { - return {json: json}; - }); - } - - if (resp.status >= 400 && resp.status < 500) { - return resp.json().then((json) => { - let err = new Error(json.message); - throw err; - }); - } - - return resp.text().then((body) => { - let err = new Error( - `airbrake: fetch: unexpected response: code=${resp.status} body='${body}'`); - throw err; - }); + return resp.text().then((body) => { + let err = new Error( + `airbrake: fetch: unexpected response: code=${ + resp.status + } body='${body}'` + ); + throw err; }); + }); } diff --git a/src/http_req/index.ts b/src/http_req/index.ts index 3feb640e4..7de544038 100644 --- a/src/http_req/index.ts +++ b/src/http_req/index.ts @@ -1,28 +1,30 @@ import Options from '../options'; -import {request as fetchRequest} from './fetch'; -import {makeRequester as makeNodeRequester} from './node'; +import { request as fetchRequest } from './fetch'; +import { makeRequester as makeNodeRequester } from './node'; -export interface HttpRequest { - method: string; - url: string; - body: string; - timeout?: number; +export interface IHttpRequest { + method: string; + url: string; + body: string; + timeout?: number; } -export interface HttpResponse { - json: any; +export interface IHttpResponse { + json: any; } -export type Requester = (req: HttpRequest) => Promise; +export type Requester = (req: IHttpRequest) => Promise; export function makeRequester(opts: Options): Requester { - if (opts.request) { - return makeNodeRequester(opts.request); - } - return fetchRequest; + if (opts.request) { + return makeNodeRequester(opts.request); + } + return fetchRequest; } export let errors = { - unauthorized: new Error('airbrake: unauthorized: project id or key are wrong'), - ipRateLimited: new Error('airbrake: IP is rate limited'), + unauthorized: new Error( + 'airbrake: unauthorized: project id or key are wrong' + ), + ipRateLimited: new Error('airbrake: IP is rate limited'), }; diff --git a/src/http_req/node.ts b/src/http_req/node.ts index 20e803d71..71057fc9a 100644 --- a/src/http_req/node.ts +++ b/src/http_req/node.ts @@ -1,111 +1,120 @@ import * as request_lib from 'request'; -import {Requester, HttpRequest, HttpResponse, errors} from './index'; +import { errors, IHttpRequest, IHttpResponse, Requester } from './index'; - -type requestAPI = request_lib.RequestAPI; +type requestAPI = request_lib.RequestAPI< + request_lib.Request, + request_lib.CoreOptions, + request_lib.RequiredUriUrl +>; export function makeRequester(api: requestAPI): Requester { - return (req: HttpRequest): Promise => { - return request(req, api); - }; + return (req: IHttpRequest): Promise => { + return request(req, api); + }; } - let rateLimitReset = 0; -function request(req: HttpRequest, api: requestAPI): Promise { - let utime = Date.now() / 1000; - if (utime < rateLimitReset) { - return Promise.reject(errors.ipRateLimited); - } - - return new Promise((resolve, reject) => { - api({ - url: req.url, - method: req.method, - body: req.body, - headers: { - 'content-type': 'application/json' - }, - timeout: req.timeout - }, function (error: any, resp: request_lib.RequestResponse, body: any): void { - if (error) { - reject(error); - return; - } - - if (!resp.statusCode) { - let err = new Error( - `airbrake: request: response statusCode is ${resp.statusCode}`); - reject(err); - return; - } - - if (resp.statusCode === 401) { - reject(errors.unauthorized); - return; - } - - if (resp.statusCode === 429) { - reject(errors.ipRateLimited); - - let h = resp.headers['x-ratelimit-delay']; - if (!h) { - return; - } - - let s: string; - if (typeof h === 'string') { - s = h; - } else if (h instanceof Array) { - s = h[0]; - } else { - return; - } - - let n = parseInt(s, 10); - if (n > 0) { - rateLimitReset = Date.now() / 1000 + n; - } - - return; - } - - if (resp.statusCode === 204) { - resolve({json: null}); - return; - } - - if (resp.statusCode >= 200 && resp.statusCode < 300) { - let json; - try { - json = JSON.parse(body); - } catch (err) { - reject(err); - return; - } - resolve(json); - return; - } - - if (resp.statusCode >= 400 && resp.statusCode < 500) { - let json; - try { - json = JSON.parse(body); - } catch (err) { - reject(err); - return; - } - let err = new Error(json.message); - reject(err); - return; - } - - body = body.trim(); - let err = new Error( - `airbrake: node: unexpected response: code=${resp.statusCode} body='${body}'`); +function request(req: IHttpRequest, api: requestAPI): Promise { + let utime = Date.now() / 1000; + if (utime < rateLimitReset) { + return Promise.reject(errors.ipRateLimited); + } + + return new Promise((resolve, reject) => { + api( + { + url: req.url, + method: req.method, + body: req.body, + headers: { + 'content-type': 'application/json', + }, + timeout: req.timeout, + }, + (error: any, resp: request_lib.RequestResponse, body: any): void => { + if (error) { + reject(error); + return; + } + + if (!resp.statusCode) { + error = new Error( + `airbrake: request: response statusCode is ${resp.statusCode}` + ); + reject(error); + return; + } + + if (resp.statusCode === 401) { + reject(errors.unauthorized); + return; + } + + if (resp.statusCode === 429) { + reject(errors.ipRateLimited); + + let h = resp.headers['x-ratelimit-delay']; + if (!h) { + return; + } + + let s: string; + if (typeof h === 'string') { + s = h; + } else if (h instanceof Array) { + s = h[0]; + } else { + return; + } + + let n = parseInt(s, 10); + if (n > 0) { + rateLimitReset = Date.now() / 1000 + n; + } + + return; + } + + if (resp.statusCode === 204) { + resolve({ json: null }); + return; + } + + if (resp.statusCode >= 200 && resp.statusCode < 300) { + let json; + try { + json = JSON.parse(body); + } catch (err) { + reject(err); + return; + } + resolve(json); + return; + } + + if (resp.statusCode >= 400 && resp.statusCode < 500) { + let json; + try { + json = JSON.parse(body); + } catch (err) { reject(err); - }); - }); + return; + } + error = new Error(json.message); + reject(error); + return; + } + + body = body.trim(); + error = new Error( + `airbrake: node: unexpected response: code=${ + resp.statusCode + } body='${body}'` + ); + reject(error); + } + ); + }); } diff --git a/src/instrumentation/dom.ts b/src/instrumentation/dom.ts index ca75752d7..54d2148ab 100644 --- a/src/instrumentation/dom.ts +++ b/src/instrumentation/dom.ts @@ -1,104 +1,102 @@ -import {Historian} from '../historian'; - +import { Historian } from '../historian'; const elemAttrs = ['type', 'name', 'src']; - function elemName(elem: HTMLElement): string { - if (!elem) { - return ''; - } - - let s: string[] = []; - - if (elem.tagName) { - s.push(elem.tagName.toLowerCase()); - } - - if (elem.id) { - s.push('#'); - s.push(elem.id); - } - - if (elem.classList) { - s.push('.'); - s.push(Array.from(elem.classList).join('.')); - } else if (elem.className) { - let str = classNameString(elem.className); - if (str !== '') { - s.push('.'); - s.push(str); - } + if (!elem) { + return ''; + } + + let s: string[] = []; + + if (elem.tagName) { + s.push(elem.tagName.toLowerCase()); + } + + if (elem.id) { + s.push('#'); + s.push(elem.id); + } + + if (elem.classList) { + s.push('.'); + s.push(Array.from(elem.classList).join('.')); + } else if (elem.className) { + let str = classNameString(elem.className); + if (str !== '') { + s.push('.'); + s.push(str); } - - if (elem.getAttribute) { - for (let attr of elemAttrs) { - let value = elem.getAttribute(attr); - if (value) { - s.push(`[${attr}="${value}"]`); - } - } + } + + if (elem.getAttribute) { + for (let attr of elemAttrs) { + let value = elem.getAttribute(attr); + if (value) { + s.push(`[${attr}="${value}"]`); + } } + } - return s.join(''); + return s.join(''); } function classNameString(name: any): string { - if (name.split) { - return name.split(' ').join('.'); - } - if (name.baseVal && name.baseVal.split) { // SVGAnimatedString - return name.baseVal.split(' ').join('.'); - } - console.log('unsupported HTMLElement.className type', - typeof(name)); - return ''; + if (name.split) { + return name.split(' ').join('.'); + } + if (name.baseVal && name.baseVal.split) { + // SVGAnimatedString + return name.baseVal.split(' ').join('.'); + } + console.error('unsupported HTMLElement.className type', typeof name); + return ''; } function elemPath(elem: HTMLElement): string { - const maxLen = 10; - - let path: string[] = []; - - let parent = elem; - while (parent) { - let name = elemName(parent); - if (name !== '') { - path.push(name); - if (path.length > maxLen) { - break; - } - } - parent = parent.parentNode as HTMLElement; + const maxLen = 10; + + let path: string[] = []; + + let parent = elem; + while (parent) { + let name = elemName(parent); + if (name !== '') { + path.push(name); + if (path.length > maxLen) { + break; + } } + parent = parent.parentNode as HTMLElement; + } - if (path.length === 0) { - return String(elem); - } + if (path.length === 0) { + return String(elem); + } - return path.reverse().join(' > '); + return path.reverse().join(' > '); } export function makeEventHandler(client: Historian): EventListener { - return function(event: Event): void { - let target: HTMLElement; - try { - target = event.target as HTMLElement; - } catch (_) { - return; - } - if (!target) { - return; - } - - let state: any = {type: event.type}; - - try { - state.target = elemPath(target); - } catch (err) { - state.target = `<${err.toString()}>`; - } - - client.pushHistory(state); - }; + return (event: Event): void => { + let target: HTMLElement; + try { + target = event.target as HTMLElement; + } catch (_) { + return; + } + if (!target) { + return; + } + + let state: any = { type: event.type }; + + try { + state.target = elemPath(target); + } catch (err) { + state.target = `<${err.toString()}>`; + } + + client.pushHistory(state); + }; } diff --git a/src/instrumentation/express.ts b/src/instrumentation/express.ts index 5488db2bc..00cd38257 100644 --- a/src/instrumentation/express.ts +++ b/src/instrumentation/express.ts @@ -1,52 +1,52 @@ import Client from '../client'; function now() { - if (process && process.hrtime) { - return process.hrtime(); - } - return Date.now(); + if (process && process.hrtime) { + return process.hrtime(); + } + return Date.now(); } function makeMiddleware(client: Client) { - return function airbrakeMiddleware(req, res, next): void { - let start = now(); - next(); - let end = now(); - let route = req.route ? req.route.path : req.url; - client.notifyRequest({ - method: req.method, - route: route, - statusCode: res.statusCode, - start: start, - end: end, - }); - }; + return function airbrakeMiddleware(req, res, next): void { + let start = now(); + next(); + let end = now(); + let route = req.route ? req.route.path : req.url; + client.notifyRequest({ + method: req.method, + route, + statusCode: res.statusCode, + start, + end, + }); + }; } function makeErrorHandler(client: Client) { - return function airbrakeErrorHandler(err: Error, req, _res, next): void { - let url = req.protocol + '://' + req.headers['host'] + req.path; - let action = req.route ? req.route.stack[0].name : ''; - let notice: any = { - error: err, - context: { - userAddr: req.ip, - userAgent: req.headers['user-agent'], - url: url, - route: req.route.path, - httpMethod: req.method, - component: 'express', - action: action, - }, - }; - let referer = req.headers['referer']; - if (referer) { - notice.context.referer = referer; - } - - client.notify(notice); - next(err); + return function airbrakeErrorHandler(err: Error, req, _res, next): void { + let url = req.protocol + '://' + req.headers.host + req.path; + let action = req.route ? req.route.stack[0].name : ''; + let notice: any = { + error: err, + context: { + userAddr: req.ip, + userAgent: req.headers['user-agent'], + url, + route: req.route.path, + httpMethod: req.method, + component: 'express', + action, + }, }; + let referer = req.headers.referer; + if (referer) { + notice.context.referer = referer; + } + + client.notify(notice); + next(err); + }; } // Hack to preserve backwards compatibility. diff --git a/src/instrumentation/hapi.ts b/src/instrumentation/hapi.ts index e0964dd9e..d2445f356 100644 --- a/src/instrumentation/hapi.ts +++ b/src/instrumentation/hapi.ts @@ -1,38 +1,39 @@ import Notifier from '../notifier'; - function makeHandler(client: Notifier) { - let fn: any = function (server, _options, next): void { - server.on('request-error', function(req, err: Error): void { - let url = req.connection.info.protocol + '://' + - req.headers['host'] + - req.path; - let notice: any = { - error: err, - context: { - userAddr: req.info.remoteAddress, - userAgent: req.headers['user-agent'], - url: url, - route: req.route.path, - httpMethod: req.method, - component: 'hapi', - action: req.route.settings.handler.name, - }, - }; - let referer = req.headers['referer']; - if (referer) { - notice.context.referer = referer; - } + let fn: any = (server, _options, next): void => { + server.on( + 'request-error', + (req, err: Error): void => { + let url = + req.connection.info.protocol + '://' + req.headers.host + req.path; + let notice: any = { + error: err, + context: { + userAddr: req.info.remoteAddress, + userAgent: req.headers['user-agent'], + url, + route: req.route.path, + httpMethod: req.method, + component: 'hapi', + action: req.route.settings.handler.name, + }, + }; + let referer = req.headers.referer; + if (referer) { + notice.context.referer = referer; + } - client.notify(notice); - }); - next(); - }; - fn.attributes = { - name: 'airbrake-js', - version: '1.0.0', - }; - return fn; + client.notify(notice); + } + ); + next(); + }; + fn.attributes = { + name: 'airbrake-js', + version: '1.0.0', + }; + return fn; } export = makeHandler; diff --git a/src/jsonify_notice.ts b/src/jsonify_notice.ts index d648aa2ab..89d7aa47f 100644 --- a/src/jsonify_notice.ts +++ b/src/jsonify_notice.ts @@ -1,244 +1,247 @@ import Notice from './notice'; - const FILTERED = '[Filtered]'; const MAX_OBJ_LENGTH = 128; // jsonifyNotice serializes notice to JSON and truncates params, // environment and session keys. export default function jsonifyNotice( - notice: Notice, {maxLength = 64000, keysBlacklist = []} = {}): string { - - if (notice.errors) { - for (let i = 0; i < notice.errors.length; i++) { - let t = new Truncator({keysBlacklist: keysBlacklist}); - notice.errors[i] = t.truncate(notice.errors[i]); - } - } - - let s = ''; - let keys = ['context', 'params', 'environment', 'session']; - for (let level = 0; level < 8; level++) { - let opts = {level: level, keysBlacklist: keysBlacklist}; - for (let key of keys) { - let obj = notice[key]; - if (obj) { - notice[key] = truncate(obj, opts); - } - } - - s = JSON.stringify(notice); - if (s.length < maxLength) { - return s; - } - } - - let params = { - json: s.slice(0, Math.floor(maxLength / 2)) + '...', - }; - keys.push('errors'); + notice: Notice, + { maxLength = 64000, keysBlacklist = [] } = {} +): string { + if (notice.errors) { + for (let i = 0; i < notice.errors.length; i++) { + let t = new Truncator({ keysBlacklist }); + notice.errors[i] = t.truncate(notice.errors[i]); + } + } + + let s = ''; + let keys = ['context', 'params', 'environment', 'session']; + for (let level = 0; level < 8; level++) { + let opts = { level, keysBlacklist }; for (let key of keys) { - let obj = notice[key]; - if (!obj) { - continue; - } + let obj = notice[key]; + if (obj) { + notice[key] = truncate(obj, opts); + } + } - s = JSON.stringify(obj); - params[key] = s.length; + s = JSON.stringify(notice); + if (s.length < maxLength) { + return s; + } + } + + let params = { + json: s.slice(0, Math.floor(maxLength / 2)) + '...', + }; + keys.push('errors'); + for (let key of keys) { + let obj = notice[key]; + if (!obj) { + continue; } - let err = new Error( - `airbrake: notice exceeds max length and can't be truncated`); - (err as any).params = params; - throw err; + s = JSON.stringify(obj); + params[key] = s.length; + } + + let err = new Error( + `airbrake: notice exceeds max length and can't be truncated` + ); + (err as any).params = params; + throw err; } function scale(num: number, level: number): number { - return (num >> level) || 1; + return num >> level || 1; } -interface TruncatorOptions { - level?: number; - keysBlacklist?: any[]; +interface ITruncatorOptions { + level?: number; + keysBlacklist?: any[]; } class Truncator { - private maxStringLength = 1024; - private maxObjectLength = MAX_OBJ_LENGTH; - private maxArrayLength = MAX_OBJ_LENGTH; - private maxDepth = 8; - - private keys: string[] = []; - private keysBlacklist: any[] = []; - private seen: any[] = []; - - constructor(opts: TruncatorOptions) { - let level = opts.level || 0; - this.keysBlacklist = opts.keysBlacklist || []; - - this.maxStringLength = scale(this.maxStringLength, level); - this.maxObjectLength = scale(this.maxObjectLength, level); - this.maxArrayLength = scale(this.maxArrayLength, level); - this.maxDepth = scale(this.maxDepth, level); - } - - truncate(value: any, key = '', depth = 0): any { - if (value === null || value === undefined) { - return value; - } - - switch (typeof value) { - case 'boolean': - case 'number': - case 'function': - return value; - case 'string': - return this.truncateString(value); - case 'object': - break; - default: - return this.truncateString(String(value)); - } - - if (value instanceof String) { - return this.truncateString(value.toString()); - } - - if (value instanceof Boolean || - value instanceof Number || - value instanceof Date || - value instanceof RegExp) { - return value; - } - - if (value instanceof Error) { - return this.truncateString(value.toString()); - } - - if (this.seen.indexOf(value) >= 0) { - return `[Circular ${this.getPath(value)}]`; - } - - let type = objectType(value); - - depth++; - if (depth > this.maxDepth) { - return `[Truncated ${type}]`; - } - - this.keys.push(key); - this.seen.push(value); - - switch (type) { - case 'Array': - return this.truncateArray(value, depth); - case 'Object': - return this.truncateObject(value, depth); - default: - let saved = this.maxDepth; - this.maxDepth = 0; - - let obj = this.truncateObject(value, depth); - obj.__type = type; - - this.maxDepth = saved; - - return obj; - } - } - - private getPath(value): string { - let index = this.seen.indexOf(value); - let path = [this.keys[index]]; - for (let i = index; i >= 0; i--) { - let sub = this.seen[i]; - if (sub && getAttr(sub, path[0]) === value) { - value = sub; - path.unshift(this.keys[i]); - } - } - return '~' + path.join('.'); - } - - private truncateString(s: string): string { - if (s.length > this.maxStringLength) { - return s.slice(0, this.maxStringLength) + '...'; - } - return s; - } - - private truncateArray(arr: any[], depth = 0): any[] { - let length = 0; - let dst: any = []; - for (let i = 0; i < arr.length; i++) { - let el = arr[i]; - dst.push(this.truncate(el, i.toString(), depth)); - - length++; - if (length >= this.maxArrayLength) { - break; - } - } - return dst; - } - - private truncateObject(obj: any, depth = 0): any { - let length = 0; - let dst = {}; - for (let key in obj) { - if (!Object.prototype.hasOwnProperty.call(obj, key)) { - continue; - } - if (isBlacklisted(key, this.keysBlacklist)) { - dst[key] = FILTERED; - continue; - } - - let value = getAttr(obj, key); - - if (value === undefined || typeof value === 'function') { - continue; - } - dst[key] = this.truncate(value, key, depth); - - length++; - if (length >= this.maxObjectLength) { - break; - } - } - return dst; + private maxStringLength = 1024; + private maxObjectLength = MAX_OBJ_LENGTH; + private maxArrayLength = MAX_OBJ_LENGTH; + private maxDepth = 8; + + private keys: string[] = []; + private keysBlacklist: any[] = []; + private seen: any[] = []; + + constructor(opts: ITruncatorOptions) { + let level = opts.level || 0; + this.keysBlacklist = opts.keysBlacklist || []; + + this.maxStringLength = scale(this.maxStringLength, level); + this.maxObjectLength = scale(this.maxObjectLength, level); + this.maxArrayLength = scale(this.maxArrayLength, level); + this.maxDepth = scale(this.maxDepth, level); + } + + public truncate(value: any, key = '', depth = 0): any { + if (value === null || value === undefined) { + return value; + } + + switch (typeof value) { + case 'boolean': + case 'number': + case 'function': + return value; + case 'string': + return this.truncateString(value); + case 'object': + break; + default: + return this.truncateString(String(value)); } + + if (value instanceof String) { + return this.truncateString(value.toString()); + } + + if ( + value instanceof Boolean || + value instanceof Number || + value instanceof Date || + value instanceof RegExp + ) { + return value; + } + + if (value instanceof Error) { + return this.truncateString(value.toString()); + } + + if (this.seen.indexOf(value) >= 0) { + return `[Circular ${this.getPath(value)}]`; + } + + let type = objectType(value); + + depth++; + if (depth > this.maxDepth) { + return `[Truncated ${type}]`; + } + + this.keys.push(key); + this.seen.push(value); + + switch (type) { + case 'Array': + return this.truncateArray(value, depth); + case 'Object': + return this.truncateObject(value, depth); + default: + let saved = this.maxDepth; + this.maxDepth = 0; + + let obj = this.truncateObject(value, depth); + obj.__type = type; + + this.maxDepth = saved; + + return obj; + } + } + + private getPath(value): string { + let index = this.seen.indexOf(value); + let path = [this.keys[index]]; + for (let i = index; i >= 0; i--) { + let sub = this.seen[i]; + if (sub && getAttr(sub, path[0]) === value) { + value = sub; + path.unshift(this.keys[i]); + } + } + return '~' + path.join('.'); + } + + private truncateString(s: string): string { + if (s.length > this.maxStringLength) { + return s.slice(0, this.maxStringLength) + '...'; + } + return s; + } + + private truncateArray(arr: any[], depth = 0): any[] { + let length = 0; + let dst: any = []; + for (let i = 0; i < arr.length; i++) { + let el = arr[i]; + dst.push(this.truncate(el, i.toString(), depth)); + + length++; + if (length >= this.maxArrayLength) { + break; + } + } + return dst; + } + + private truncateObject(obj: any, depth = 0): any { + let length = 0; + let dst = {}; + for (let key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue; + } + if (isBlacklisted(key, this.keysBlacklist)) { + dst[key] = FILTERED; + continue; + } + + let value = getAttr(obj, key); + + if (value === undefined || typeof value === 'function') { + continue; + } + dst[key] = this.truncate(value, key, depth); + + length++; + if (length >= this.maxObjectLength) { + break; + } + } + return dst; + } } -export function truncate(value: any, opts: TruncatorOptions = {}): any { - let t = new Truncator(opts); - return t.truncate(value); +export function truncate(value: any, opts: ITruncatorOptions = {}): any { + let t = new Truncator(opts); + return t.truncate(value); } function getAttr(obj: any, attr: string): any { - // Ignore browser specific exception trying to read an attribute (#79). - try { - return obj[attr]; - } catch (_) { - return; - } + // Ignore browser specific exception trying to read an attribute (#79). + try { + return obj[attr]; + } catch (_) { + return; + } } function objectType(obj: any): string { - let s = Object.prototype.toString.apply(obj); - return s.slice('[object '.length, -1); + let s = Object.prototype.toString.apply(obj); + return s.slice('[object '.length, -1); } function isBlacklisted(key: string, keysBlacklist: any[]): boolean { - for (let v of keysBlacklist) { - if (v === key) { - return true; - } - if (v instanceof RegExp) { - if (key.match(v)) { - return true; - } - } - } - return false; + for (let v of keysBlacklist) { + if (v === key) { + return true; + } + if (v instanceof RegExp) { + if (key.match(v)) { + return true; + } + } + } + return false; } diff --git a/src/notice.ts b/src/notice.ts index b5961c389..14b431739 100644 --- a/src/notice.ts +++ b/src/notice.ts @@ -1,25 +1,25 @@ export interface NoticeFrame { - function: string; - file: string; - line: number; - column: number; + function: string; + file: string; + line: number; + column: number; } export interface NoticeError { - type: string; - message: string; - backtrace: NoticeFrame[]; + type: string; + message: string; + backtrace: NoticeFrame[]; } export interface Notice { - id?: string; - error?: Error; + id?: string; + error?: Error; - errors: NoticeError[]; - context?: any; - params?: any; - session?: any; - environment?: any; + errors: NoticeError[]; + context?: any; + params?: any; + session?: any; + environment?: any; } export default Notice; diff --git a/src/notifier.ts b/src/notifier.ts index fb44798c0..5de859c0d 100644 --- a/src/notifier.ts +++ b/src/notifier.ts @@ -1,7 +1,6 @@ import Notice from './notice'; - export interface Notifier { - notify(err: any): Promise; + notify(err: any): Promise; } export default Notifier; diff --git a/src/options.ts b/src/options.ts index 75b6e9b99..c32547f50 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,24 +1,28 @@ import * as request from 'request'; +import { IHistorianOptions } from './historian'; import Notice from './notice'; -import {HistorianOptions} from './historian'; import Processor from './processor/processor'; -import {TDigestConstructor} from './routes'; +import { ITDigestConstructor } from './routes'; type Reporter = (notice: Notice) => Promise; export default interface Options { - projectId: number; - projectKey: string; - environment?: string; - host?: string; - timeout?: number; - keysBlacklist?: any[]; - ignoreWindowError?: boolean; - processor?: Processor; - reporter?: Reporter; - instrumentation?: HistorianOptions; + projectId: number; + projectKey: string; + environment?: string; + host?: string; + timeout?: number; + keysBlacklist?: any[]; + ignoreWindowError?: boolean; + processor?: Processor; + reporter?: Reporter; + instrumentation?: IHistorianOptions; - request?: request.RequestAPI; - TDigest?: TDigestConstructor; + request?: request.RequestAPI< + request.Request, + request.CoreOptions, + request.RequiredUriUrl + >; + TDigest?: ITDigestConstructor; } diff --git a/src/processor/processor.ts b/src/processor/processor.ts index c27a82a73..4f519f7a0 100644 --- a/src/processor/processor.ts +++ b/src/processor/processor.ts @@ -1,5 +1,4 @@ -import {NoticeError} from '../notice'; - +import { NoticeError } from '../notice'; export type Processor = (err: Error) => NoticeError; export default Processor; diff --git a/src/processor/stacktracejs.ts b/src/processor/stacktracejs.ts index 1d7ce22cc..5c7d23b68 100644 --- a/src/processor/stacktracejs.ts +++ b/src/processor/stacktracejs.ts @@ -1,79 +1,67 @@ -import {NoticeError, NoticeFrame} from '../notice'; +import { NoticeError, NoticeFrame } from '../notice'; import ErrorStackParser = require('error-stack-parser'); - const hasConsole = typeof console === 'object' && console.warn; -export interface StackFrame { - functionName?: string; - fileName?: string; - lineNumber?: number; - columnNumber?: number; +export interface IStackFrame { + functionName?: string; + fileName?: string; + lineNumber?: number; + columnNumber?: number; } -export interface MyError extends Error, StackFrame { - noStack?: boolean; +export interface IError extends Error, IStackFrame { + noStack?: boolean; } -function parse(err: MyError): StackFrame[] { - try { - return ErrorStackParser.parse(err); - } catch (parseErr) { - if (hasConsole && err.stack) { - console.warn('ErrorStackParser:', parseErr.toString(), err.stack); - } +function parse(err: IError): IStackFrame[] { + try { + return ErrorStackParser.parse(err); + } catch (parseErr) { + if (hasConsole && err.stack) { + console.warn('ErrorStackParser:', parseErr.toString(), err.stack); } + } - if (err.fileName) { - return [err]; - } + if (err.fileName) { + return [err]; + } - return []; + return []; } -export default function processor(err: MyError): NoticeError { - let backtrace: NoticeFrame[] = []; +export default function processor(err: IError): NoticeError { + let backtrace: NoticeFrame[] = []; - if (!err.noStack) { - let frames = parse(err); - if (frames.length === 0) { - try { - throw new Error('fake'); - } catch (fakeErr) { - frames = parse(fakeErr); - frames.shift(); - frames.shift(); - } - } - - for (let frame of frames) { - backtrace.push({ - function: frame.functionName || '', - file: frame.fileName || '', - line: frame.lineNumber || 0, - column: frame.columnNumber || 0, - }); - } + if (!err.noStack) { + let frames = parse(err); + if (frames.length === 0) { + try { + throw new Error('fake'); + } catch (fakeErr) { + frames = parse(fakeErr); + frames.shift(); + frames.shift(); + } } - let type: string; - if (err.name) { - type = err.name; - } else { - type = ''; + for (let frame of frames) { + backtrace.push({ + function: frame.functionName || '', + file: frame.fileName || '', + line: frame.lineNumber || 0, + column: frame.columnNumber || 0, + }); } + } - let msg: string; - if (err.message) { - msg = String(err.message); - } else { - msg = String(err); - } + let type: string = err.name ? err.name : ''; + let msg: string = err.message ? String(err.message) : String(err); - return { - type: type, - message: msg, - backtrace: backtrace, - }; + return { + type, + message: msg, + backtrace, + }; } diff --git a/src/routes.ts b/src/routes.ts index 80fef9138..aa544a896 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,195 +1,198 @@ +import { makeRequester, Requester } from './http_req'; import Options from './options'; -import {Requester, makeRequester} from './http_req'; - const FLUSH_INTERVAL = 15000; // 15 seconds - -interface Centroid { - mean: number; - n: number; +interface ICentroid { + mean: number; + n: number; } -interface Centroids { - each(fn: (c: Centroid) => void): void; +interface ICentroids { + each(fn: (c: ICentroid) => void): void; } -interface TDigest { - centroids: Centroids; +interface ITDigest { + centroids: ICentroids; - push(x: number); - compress(); + push(x: number); + compress(); } -export interface TDigestConstructor { - new(): TDigest; -} +export type ITDigestConstructor = new () => ITDigest; -interface TDigestCentroids { - mean: number[]; - count: number[]; +interface ITDigestCentroids { + mean: number[]; + count: number[]; } -interface RouteKey { - method: string; - route: string; - statusCode: number; - time: Date; +interface IRouteKey { + method: string; + route: string; + statusCode: number; + time: Date; } -interface RouteStat { - count: number; - sum: number; - sumsq: number; - tdigest?: TDigest; - tdigestCentroids?: TDigestCentroids; +interface IRouteStat { + count: number; + sum: number; + sumsq: number; + tdigest?: ITDigest; + tdigestCentroids?: ITDigestCentroids; } type time = Date | number | [number, number]; -export interface RequestInfo { - method: string; - route: string; - statusCode: number; - start: time; - end: time; +export interface IRequestInfo { + method: string; + route: string; + statusCode: number; + start: time; + end: time; } export class Routes { - private opts: Options; - private url: string; - // TODO: use RouteKey as map key - private m: {[key: string]: RouteStat} = {}; - private timer; - - private requester: Requester; - - constructor(opts: Options) { - this.opts = opts; - this.url = `${this.opts.host}/api/v5/projects/${this.opts.projectId}/routes-stats?key=${this.opts.projectKey}`; - this.requester = makeRequester(this.opts); + private opts: Options; + private url: string; + // TODO: use RouteKey as map key + private m: { [key: string]: IRouteStat } = {}; + private timer; + + private requester: Requester; + + constructor(opts: Options) { + this.opts = opts; + this.url = `${this.opts.host}/api/v5/projects/${ + this.opts.projectId + }/routes-stats?key=${this.opts.projectKey}`; + this.requester = makeRequester(this.opts); + } + + public notifyRequest(req: IRequestInfo): void { + let ms = durationMs(req.start, req.end); + if (ms === 0) { + ms = 0.1; } - notifyRequest(req: RequestInfo): void { - let ms = durationMs(req.start, req.end); - if (ms === 0) { - ms = 0.1; - } - - const minute = 60 * 1000; - req.start = new Date(Math.floor(toTime(req.start) / minute) * minute); - - let key: RouteKey = { - method: req.method, - route: req.route, - statusCode: req.statusCode, - time: req.start - }; - let keyStr = JSON.stringify(key); - - let stat: RouteStat; - if (keyStr in this.m) { - stat = this.m[keyStr]; - } else { - stat = { - count: 0, - sum: 0, - sumsq: 0 - }; - if (this.opts.TDigest) { - stat.tdigest = new this.opts.TDigest(); - } - - this.m[keyStr] = stat; - } - - stat.count++; - stat.sum += ms; - stat.sumsq += ms * ms; - if (stat.tdigest) { - stat.tdigest.push(ms); - } - - if (this.timer) { - return; - } - this.timer = setTimeout(() => { this.flush(); }, FLUSH_INTERVAL); + const minute = 60 * 1000; + req.start = new Date(Math.floor(toTime(req.start) / minute) * minute); + + let key: IRouteKey = { + method: req.method, + route: req.route, + statusCode: req.statusCode, + time: req.start, + }; + let keyStr = JSON.stringify(key); + + let stat: IRouteStat; + if (keyStr in this.m) { + stat = this.m[keyStr]; + } else { + stat = { + count: 0, + sum: 0, + sumsq: 0, + }; + if (this.opts.TDigest) { + stat.tdigest = new this.opts.TDigest(); + } + + this.m[keyStr] = stat; } - private flush(): void { - let routes = []; - for (let keyStr in this.m) { - if (!this.m.hasOwnProperty(keyStr)) { - continue; - } - let key: RouteKey = JSON.parse(keyStr); - let v = { - ...key, - ...this.m[keyStr] - }; - if (v.tdigest) { - v.tdigestCentroids = this.tdigestCentroids(v.tdigest); - delete v.tdigest; - } - routes.push(v); - } - - this.m = {}; - this.timer = null; - - let req = { - method: 'POST', - url: this.url, - body: JSON.stringify({routes: routes}), - }; - this.requester(req).then((_resp) => { - // nothing - }).catch((err) => { - if (console.error) { - console.error('can not report routes stats', err); - } - }); + stat.count++; + stat.sum += ms; + stat.sumsq += ms * ms; + if (stat.tdigest) { + stat.tdigest.push(ms); } - private tdigestCentroids(td: TDigest): TDigestCentroids { - let means: number[] = [], counts: number[] = []; - td.centroids.each((c: Centroid) => { - means.push(c.mean); - counts.push(c.n); - }); - return { - mean: means, - count: counts, - }; + if (this.timer) { + return; + } + this.timer = setTimeout(() => { + this.flush(); + }, FLUSH_INTERVAL); + } + + private flush(): void { + let routes = []; + for (let keyStr in this.m) { + if (!this.m.hasOwnProperty(keyStr)) { + continue; + } + let key: IRouteKey = JSON.parse(keyStr); + let v = { + ...key, + ...this.m[keyStr], + }; + if (v.tdigest) { + v.tdigestCentroids = this.tdigestCentroids(v.tdigest); + delete v.tdigest; + } + routes.push(v); } + + this.m = {}; + this.timer = null; + + let req = { + method: 'POST', + url: this.url, + body: JSON.stringify({ routes }), + }; + this.requester(req) + .then((_resp) => { + // nothing + }) + .catch((err) => { + if (console.error) { + console.error('can not report routes stats', err); + } + }); + } + + private tdigestCentroids(td: ITDigest): ITDigestCentroids { + let means: number[] = []; + let counts: number[] = []; + td.centroids.each((c: ICentroid) => { + means.push(c.mean); + counts.push(c.n); + }); + return { + mean: means, + count: counts, + }; + } } const NS_PER_MS = 1e6; -function toTime(time: time): number { - if (time instanceof Date) { - return time.getTime(); - } - if (typeof time === 'number') { - return time; - } - if (time instanceof Array) { - return time[0] + (time[1] / NS_PER_MS); - } - throw new Error(`unsupported type: ${typeof time}`); +function toTime(tm: time): number { + if (tm instanceof Date) { + return tm.getTime(); + } + if (typeof tm === 'number') { + return tm; + } + if (tm instanceof Array) { + return tm[0] + tm[1] / NS_PER_MS; + } + throw new Error(`unsupported type: ${typeof tm}`); } function durationMs(start: time, end: time): number { - if (start instanceof Date && end instanceof Date) { - return end.getTime() - start.getTime(); - } - if (typeof start === 'number' && typeof end === 'number') { - return end - start; - } - if (start instanceof Array && end instanceof Array) { - let ms = end[0] - start[0]; - ms += (end[1] - start[1]) / NS_PER_MS; - return ms; - } - throw new Error(`unsupported type: ${typeof start}`); + if (start instanceof Date && end instanceof Date) { + return end.getTime() - start.getTime(); + } + if (typeof start === 'number' && typeof end === 'number') { + return end - start; + } + if (start instanceof Array && end instanceof Array) { + let ms = end[0] - start[0]; + ms += (end[1] - start[1]) / NS_PER_MS; + return ms; + } + throw new Error(`unsupported type: ${typeof start}`); } diff --git a/test/unit/client_test.ts b/test/unit/client_test.ts index f41850f64..0f3f9677a 100644 --- a/test/unit/client_test.ts +++ b/test/unit/client_test.ts @@ -1,659 +1,675 @@ import Client from '../../src/client'; +import Options from '../../src/options'; import * as sinon from 'sinon'; import { expect } from './sinon_chai'; - describe('Client config', () => { - let reporter, client: Client; - let err = new Error('test'); + let reporter, client: Client; + let err = new Error('test'); - beforeEach(() => { - reporter = sinon.spy(() => { - return Promise.resolve({id: 1}); - }); + beforeEach(() => { + reporter = sinon.spy(() => { + return Promise.resolve({ id: 1 }); + }); + }); + + afterEach(() => { + if (client) { + client.close(); + } + }); + + it('throws when projectId or projectKey are missing', () => { + expect(() => { + new Client({} as Options); + }).to.throw('airbrake: projectId and projectKey are required'); + }); + + it('calls a reporter', () => { + client = new Client({ + projectId: 1, + projectKey: 'abc', + reporter, }); + client.notify(err); - afterEach(() => { - if (client) { - client.close(); - } + expect(reporter).to.have.been.called; + }); + + it('supports ignoreWindowError', (done) => { + client = new Client({ + projectId: 1, + projectKey: 'abc', + reporter, + ignoreWindowError: true, + }); + let promise = client.notify({ + error: err, + context: { + windowError: true, + }, }); - it('throws when projectId or projectKey are missing', () => { - expect(() => { - new Client(); - }).to.throw('airbrake: projectId and projectKey are required'); + expect(reporter).to.not.have.been.called; + promise.then((notice: any) => { + expect(notice.error.toString()).to.equal( + 'Error: airbrake: window error is ignored' + ); + done(); + }); + }); + + it('supports environment', () => { + client = new Client({ + projectId: 1, + projectKey: 'abc', + reporter, + environment: 'production', }); - it('calls a reporter', () => { - client = new Client({ - projectId: 1, - projectKey: 'abc', - reporter: reporter, - }); - client.notify(err); + client.notify(err); + + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + expect(notice.context.environment).to.equal('production'); + }); + + describe('keysBlacklist', () => { + function test(keysBlacklist: any[]) { + client = new Client({ + projectId: 1, + projectKey: 'abc', + reporter, + keysBlacklist, + }); + + client.notify({ + error: err, + params: { + key1: 'value1', + key2: 'value2', + key3: { key1: 'value1' }, + }, + }); + + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + expect(notice.params).to.deep.equal({ + key1: '[Filtered]', + key2: 'value2', + key3: { key1: '[Filtered]' }, + }); + } + + it('support exact match', () => { + test(['key1']); + }); - expect(reporter).to.have.been.called; + it('support regexp match', () => { + test([/key1/]); }); + }); +}); - it('supports ignoreWindowError', (done) => { - client = new Client({ - projectId: 1, - projectKey: 'abc', - reporter: reporter, - ignoreWindowError: true, - }); - let promise = client.notify({ - error: err, - context: { - windowError: true, - }, - }); +describe('Client', () => { + let reporter, client: Client; + let err = new Error('test'); - expect(reporter).to.not.have.been.called; - promise.then((notice: any) => { - expect(notice.error.toString()).to.equal( - 'Error: airbrake: window error is ignored'); - done(); - }); + beforeEach(() => { + reporter = sinon.spy(() => { + return Promise.resolve({ id: 1 }); }); + client = new Client({ + projectId: 1, + projectKey: 'abc', + reporter, + }); + }); - it('supports environment', () => { - client = new Client({ - projectId: 1, - projectKey: 'abc', - reporter: reporter, - environment: 'production', - }); + afterEach(() => { + client.close(); + }); - client.notify(err); + describe('filter', () => { + it('returns null to ignore notice', () => { + let filter = sinon.spy((_) => null); + client.addFilter(filter); - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - expect(notice.context.environment).to.equal('production'); - }); - - describe('keysBlacklist', () => { - function test(keysBlacklist: any[]) { - client = new Client({ - projectId: 1, - projectKey: 'abc', - reporter: reporter, - keysBlacklist: keysBlacklist, - }); - - client.notify({ - error: err, - params: { - key1: 'value1', - key2: 'value2', - key3: {'key1': 'value1'}, - }, - }); - - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - expect(notice.params).to.deep.equal({ - key1: '[Filtered]', - key2: 'value2', - key3: {key1: '[Filtered]'}, - }); - }; - - it('support exact match', () => { - test(['key1']); - }); + client.notify({}); - it('support regexp match', () => { - test([/key1/]); - }); + expect(filter).to.have.been.called; + expect(reporter).not.to.have.been.called; }); -}); + it('returns notice to keep it', () => { + let filter = sinon.spy((notice) => notice); + client.addFilter(filter); -describe('Client', () => { - let reporter, client: Client; - let err = new Error('test'); + client.notify({}); - beforeEach(() => { - reporter = sinon.spy(() => { - return Promise.resolve({id: 1}); - }); - client = new Client({ - projectId: 1, - projectKey: 'abc', - reporter: reporter, - }); + expect(filter).to.have.been.called; + expect(reporter).to.have.been.called; }); - afterEach(() => { - client.close(); + it('returns notice to change payload', () => { + let filter = sinon.spy((notice) => { + notice.context.environment = 'production'; + return notice; + }); + client.addFilter(filter); + + client.notify({}); + + expect(filter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + expect(notice.context.environment).to.equal('production'); }); - describe('filter', () => { - it('returns null to ignore notice', () => { - let filter = sinon.spy((_) => null); - client.addFilter(filter); + it('returns new notice to change payload', () => { + let newNotice = { errors: [] }; + let filter = sinon.spy((_) => { + return newNotice; + }); + client.addFilter(filter); - client.notify({}); + client.notify({}); - expect(filter).to.have.been.called; - expect(reporter).not.to.have.been.called; - }); + expect(filter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + expect(notice).to.equal(newNotice); + }); + }); - it('returns notice to keep it', () => { - let filter = sinon.spy((notice) => notice); - client.addFilter(filter); + context('"Uncaught ..." error message', () => { + beforeEach(() => { + let msg = + 'Uncaught SecurityError: Blocked a frame with origin "https://airbrake.io" from accessing a cross-origin frame.'; + client.notify({ type: '', message: msg }); + }); - client.notify({}); + it('splitted into type and message', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let err = notice.errors[0]; + expect(err.type).to.equal('SecurityError'); + expect(err.message).to.equal( + 'Blocked a frame with origin "https://airbrake.io" from accessing a cross-origin frame.' + ); + }); + }); - expect(filter).to.have.been.called; - expect(reporter).to.have.been.called; - }); + describe('Angular error message', () => { + beforeEach(() => { + let msg = `[$injector:undef] Provider '$exceptionHandler' must return a value from $get factory method.\nhttp://errors.angularjs.org/1.4.3/$injector/undef?p0=%24exceptionHandler`; + client.notify({ type: 'Error', message: msg }); + }); - it('returns notice to change payload', () => { - let filter = sinon.spy((notice) => { - notice.context.environment = 'production'; - return notice; - }); - client.addFilter(filter); + it('splitted into type and message', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let err = notice.errors[0]; + expect(err.type).to.equal('$injector:undef'); + expect(err.message).to.equal( + `Provider '$exceptionHandler' must return a value from $get factory method.\nhttp://errors.angularjs.org/1.4.3/$injector/undef?p0=%24exceptionHandler` + ); + }); + }); - client.notify({}); + describe('severity', () => { + it('defaults to "error"', () => { + client.notify(err); + let reported = reporter.lastCall.args[0]; + expect(reported.context.severity).to.equal('error'); + }); - expect(filter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - expect(notice.context.environment).to.equal('production'); - }); + it('can be overriden', () => { + let customSeverity = 'emergency'; - it('returns new notice to change payload', () => { - let newNotice = {errors: []}; - let filter = sinon.spy((_) => { - return newNotice; - }); - client.addFilter(filter); + client.addFilter((n) => { + n.context.severity = customSeverity; + return n; + }); - client.notify({}); + client.notify(err); + let reported = reporter.lastCall.args[0]; + expect(reported.context.severity).to.equal(customSeverity); + }); + }); - expect(filter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - expect(notice).to.equal(newNotice); - }); + describe('notify', () => { + it('calls reporter', () => { + client.notify(err); + expect(reporter).to.have.been.called; }); - context('"Uncaught ..." error message', () => { - beforeEach(() => { - let msg = 'Uncaught SecurityError: Blocked a frame with origin "https://airbrake.io" from accessing a cross-origin frame.'; - client.notify({type: '', message: msg}); - }); + it('returns promise and resolves it', (done) => { + let promise = client.notify(err); + let onResolved = sinon.spy(); + promise.then(onResolved); + setTimeout(() => { + expect(onResolved).to.have.been.called; + done(); + }, 0); + }); - it('splitted into type and message', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let err = notice.errors[0]; - expect(err.type).to.equal('SecurityError'); - expect(err.message).to.equal('Blocked a frame with origin "https://airbrake.io" from accessing a cross-origin frame.'); - }); + it('does not report same error twice', (done) => { + client.notify(err); + expect(reporter).to.have.been.calledOnce; + + let promise = client.notify(err); + promise.then((notice: any) => { + expect(notice.error.toString()).to.equal( + 'Error: airbrake: error is filtered' + ); + done(); + }); }); - describe('Angular error message', () => { - beforeEach(() => { - let msg = `[$injector:undef] Provider '$exceptionHandler' must return a value from $get factory method.\nhttp://errors.angularjs.org/1.4.3/$injector/undef?p0=%24exceptionHandler`; - client.notify({type: 'Error', message: msg}); - }); + it('ignores falsey error', (done) => { + let promise = client.notify(''); + expect(reporter).not.to.have.been.called; - it('splitted into type and message', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let err = notice.errors[0]; - expect(err.type).to.equal('$injector:undef'); - expect(err.message).to.equal(`Provider '$exceptionHandler' must return a value from $get factory method.\nhttp://errors.angularjs.org/1.4.3/$injector/undef?p0=%24exceptionHandler`); - }); + promise.then((notice: any) => { + expect(notice.error.toString()).to.equal( + 'Error: airbrake: got err="", wanted an Error' + ); + done(); + }); }); - describe('severity', () => { - it('defaults to "error"', () => { - client.notify(err); - let reported = reporter.lastCall.args[0]; - expect(reported.context.severity).to.equal('error'); - }); + it('reports severity', () => { + client.notify({ error: err, context: { severity: 'warning' } }); - it('can be overriden', () => { - let customSeverity = 'emergency'; + let notice = reporter.lastCall.args[0]; + expect(notice.context.severity).to.equal('warning'); + }); - client.addFilter((n) => { - n.context.severity = customSeverity; - return n; - }); + it('reports userAgent', () => { + client.notify(err); - client.notify(err); - let reported = reporter.lastCall.args[0]; - expect(reported.context.severity).to.equal(customSeverity); - }); + let notice = reporter.lastCall.args[0]; + expect(notice.context.userAgent).to.contain('HeadlessChrome'); }); - describe('notify', () => { - it('calls reporter', () => { - client.notify(err); - expect(reporter).to.have.been.called; - }); + it('reports text error', () => { + client.notify('hello'); - it('returns promise and resolves it', (done) => { - let promise = client.notify(err); - let onResolved = sinon.spy(); - promise.then(onResolved); - setTimeout(() => { - expect(onResolved).to.have.been.called; - done(); - }, 0); - }); + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let err = notice.errors[0]; + expect(err.message).to.equal('hello'); + expect(err.backtrace.length).to.not.equal(0); + }); - it('does not report same error twice', (done) => { - client.notify(err); - expect(reporter).to.have.been.calledOnce; + it('ignores "Script error" message', () => { + client.notify('Script error'); - let promise = client.notify(err); - promise.then((notice: any) => { - expect(notice.error.toString()).to.equal( - 'Error: airbrake: error is filtered'); - done(); - }); - }); + expect(reporter).not.to.have.been.called; + }); - it('ignores falsey error', (done) => { - let promise = client.notify(''); - expect(reporter).not.to.have.been.called; + it('ignores "InvalidAccessError" message', () => { + client.notify('InvalidAccessError'); - promise.then((notice: any) => { - expect(notice.error.toString()).to.equal( - 'Error: airbrake: got err="", wanted an Error'); - done(); - }); - }); + expect(reporter).not.to.have.been.called; + }); + + it('ignores errors occurred in file', () => { + client.notify({ message: 'test', fileName: '' }); - it('reports severity', () => { - client.notify({error: err, context: {severity: 'warning'}}); + expect(reporter).not.to.have.been.called; + }); - let notice = reporter.lastCall.args[0]; - expect(notice.context.severity).to.equal('warning'); + describe('custom data in the filter', () => { + it('reports context', () => { + client.addFilter((n) => { + n.context.context_key = '[custom_context]'; + return n; }); + client.notify(err); - it('reports userAgent', () => { - client.notify(err); + let reported = reporter.lastCall.args[0]; + expect(reported.context.context_key).to.equal('[custom_context]'); + }); - let notice = reporter.lastCall.args[0]; - expect(notice.context.userAgent).to.contain('HeadlessChrome'); + it('reports environment', () => { + client.addFilter((n) => { + n.environment.env_key = '[custom_env]'; + return n; }); + client.notify(err); - it('reports text error', () => { - client.notify('hello'); + let reported = reporter.lastCall.args[0]; + expect(reported.environment.env_key).to.equal('[custom_env]'); + }); - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let err = notice.errors[0]; - expect(err.message).to.equal('hello'); - expect(err.backtrace.length).to.not.equal(0); + it('reports params', () => { + client.addFilter((n) => { + n.params.params_key = '[custom_params]'; + return n; }); + client.notify(err); - it('ignores "Script error" message', () => { - client.notify('Script error'); + let reported = reporter.lastCall.args[0]; + expect(reported.params.params_key).to.equal('[custom_params]'); + }); - expect(reporter).not.to.have.been.called; + it('reports session', () => { + client.addFilter((n) => { + n.session.session_key = '[custom_session]'; + return n; }); + client.notify(err); - it('ignores "InvalidAccessError" message', () => { - client.notify('InvalidAccessError'); + let reported = reporter.lastCall.args[0]; + expect(reported.session.session_key).to.equal('[custom_session]'); + }); + }); - expect(reporter).not.to.have.been.called; - }); + describe('wrapped error', () => { + it('unwraps and processes error', () => { + client.notify({ error: err }); + expect(reporter).to.have.been.called; + }); + + it('ignores falsey error', (done) => { + let promise = client.notify({ error: null, params: { foo: 'bar' } }); - it('ignores errors occurred in file', () => { - client.notify({message: 'test', fileName: ''}); + expect(reporter).not.to.have.been.called; - expect(reporter).not.to.have.been.called; + promise.then((notice: any) => { + expect(notice.error.toString()).to.equal( + 'Error: airbrake: got err=null, wanted an Error' + ); + done(); }); + }); - describe('custom data in the filter', () => { - it('reports context', () => { - client.addFilter((n) => { - n.context.context_key = '[custom_context]'; - return n; - }); - client.notify(err); - - let reported = reporter.lastCall.args[0]; - expect(reported.context.context_key).to.equal('[custom_context]'); - }); - - it('reports environment', () => { - client.addFilter((n) => { - n.environment.env_key = '[custom_env]'; - return n; - }); - client.notify(err); - - let reported = reporter.lastCall.args[0]; - expect(reported.environment.env_key).to.equal('[custom_env]'); - }); - - it('reports params', () => { - client.addFilter((n) => { - n.params.params_key = '[custom_params]'; - return n; - }); - client.notify(err); - - let reported = reporter.lastCall.args[0]; - expect(reported.params.params_key).to.equal('[custom_params]'); - }); - - it('reports session', () => { - client.addFilter((n) => { - n.session.session_key = '[custom_session]'; - return n; - }); - client.notify(err); - - let reported = reporter.lastCall.args[0]; - expect(reported.session.session_key).to.equal('[custom_session]'); - }); + it('reports custom context', () => { + client.addFilter((n) => { + n.context.context1 = 'value1'; + n.context.context2 = 'value2'; + return n; }); - describe('wrapped error', () => { - it('unwraps and processes error', () => { - client.notify({error: err}); - expect(reporter).to.have.been.called; - }); - - it('ignores falsey error', (done) => { - let promise = client.notify({error: null, params: {foo: 'bar'}}); - - expect(reporter).not.to.have.been.called; - - promise.then((notice: any) => { - expect(notice.error.toString()).to.equal( - 'Error: airbrake: got err=null, wanted an Error'); - done(); - }); - }); - - it('reports custom context', () => { - client.addFilter((n) => { - n.context.context1 = 'value1'; - n.context.context2 = 'value2'; - return n; - }); - - client.notify({ - error: err, - context: { - context1: 'notify_value1', - context3: 'notify_value3', - }, - }); - - let reported = reporter.lastCall.args[0]; - expect(reported.context.context1).to.equal('value1'); - expect(reported.context.context2).to.equal('value2'); - expect(reported.context.context3).to.equal('notify_value3'); - }); - - it('reports custom environment', () => { - client.addFilter((n) => { - n.environment.env1 = 'value1'; - n.environment.env2 = 'value2'; - return n; - }); - - client.notify({ - error: err, - environment: { - env1: 'notify_value1', - env3: 'notify_value3', - }, - }); - - let reported = reporter.lastCall.args[0]; - expect(reported.environment).to.deep.equal({ - env1: 'value1', - env2: 'value2', - env3: 'notify_value3', - }); - }); - - it('reports custom params', () => { - client.addFilter((n) => { - n.params.param1 = 'value1'; - n.params.param2 = 'value2'; - return n; - }); - - client.notify({ - error: err, - params: { - param1: 'notify_value1', - param3: 'notify_value3', - }, - }); - - let params = reporter.lastCall.args[0].params; - expect(params.param1).to.equal('value1'); - expect(params.param2).to.equal('value2'); - expect(params.param3).to.equal('notify_value3'); - }); - - it('reports custom session', () => { - client.addFilter((n) => { - n.session.session1 = 'value1'; - n.session.session2 = 'value2'; - return n; - }); - - client.notify({ - error: err, - session: { - session1: 'notify_value1', - session3: 'notify_value3', - }, - }); - - let reported = reporter.lastCall.args[0]; - expect(reported.session).to.deep.equal({ - session1: 'value1', - session2: 'value2', - session3: 'notify_value3', - }); - }); + client.notify({ + error: err, + context: { + context1: 'notify_value1', + context3: 'notify_value3', + }, }); - }); - describe('location', () => { - let notice; + let reported = reporter.lastCall.args[0]; + expect(reported.context.context1).to.equal('value1'); + expect(reported.context.context2).to.equal('value2'); + expect(reported.context.context3).to.equal('notify_value3'); + }); - beforeEach(() => { - client.notify(err); - expect(reporter).to.have.been.called; - notice = reporter.lastCall.args[0]; + it('reports custom environment', () => { + client.addFilter((n) => { + n.environment.env1 = 'value1'; + n.environment.env2 = 'value2'; + return n; }); - it('reports context.url', () => { - expect(notice.context.url).to.equal('http://localhost:9876/context.html'); + client.notify({ + error: err, + environment: { + env1: 'notify_value1', + env3: 'notify_value3', + }, }); - it('reports context.rootDirectory', () => { - expect(notice.context.rootDirectory).to.equal('http://localhost:9876'); + let reported = reporter.lastCall.args[0]; + expect(reported.environment).to.deep.equal({ + env1: 'value1', + env2: 'value2', + env3: 'notify_value3', }); - }); + }); - describe('wrap', () => { - it('does not invoke function immediately', () => { - let fn = sinon.spy(); - client.wrap(fn); - expect(fn).not.to.have.been.called; + it('reports custom params', () => { + client.addFilter((n) => { + n.params.param1 = 'value1'; + n.params.param2 = 'value2'; + return n; }); - it('creates wrapper that invokes function with passed args', () => { - let fn = sinon.spy(); - let wrapper: any = client.wrap(fn); - wrapper('hello', 'world'); - expect(fn).to.have.been.called; - expect(fn.lastCall.args).to.deep.equal(['hello', 'world']); + client.notify({ + error: err, + params: { + param1: 'notify_value1', + param3: 'notify_value3', + }, }); - it('sets _airbrake and inner properties', () => { - let fn = sinon.spy(); - let wrapper = client.wrap(fn); - expect(wrapper._airbrake).to.equal(true); - expect(wrapper.inner).to.equal(fn); + let params = reporter.lastCall.args[0].params; + expect(params.param1).to.equal('value1'); + expect(params.param2).to.equal('value2'); + expect(params.param3).to.equal('notify_value3'); + }); + + it('reports custom session', () => { + client.addFilter((n) => { + n.session.session1 = 'value1'; + n.session.session2 = 'value2'; + return n; }); - it('copies function properties', () => { - let fn = sinon.spy(); - (fn as any).prop = 'hello'; - let wrapper: any = client.wrap(fn); - expect(wrapper.prop).to.equal('hello'); + client.notify({ + error: err, + session: { + session1: 'notify_value1', + session3: 'notify_value3', + }, }); - it('reports throwed exception', () => { - let spy = sinon.spy(); - client.notify = spy; - let fn = () => { throw err; }; - let wrapper: any = client.wrap(fn); - try { - wrapper('hello', 'world'); - } catch (err) {} - - expect(spy).to.have.been.called; - expect(spy.lastCall.args).to.deep.equal([{ - error: err, - params: {arguments: ['hello', 'world']}, - }]); + let reported = reporter.lastCall.args[0]; + expect(reported.session).to.deep.equal({ + session1: 'value1', + session2: 'value2', + session3: 'notify_value3', }); + }); + }); + }); - it('wraps arguments', () => { - let fn = sinon.spy(); - let wrapper: any = client.wrap(fn); - let arg1 = () => null; - wrapper(arg1); + describe('location', () => { + let notice; - expect(fn).to.have.been.called; - let arg1Wrapper = fn.lastCall.args[0]; - expect(arg1Wrapper._airbrake).to.equal(true); - expect(arg1Wrapper.inner).to.equal(arg1); - }); + beforeEach(() => { + client.notify(err); + expect(reporter).to.have.been.called; + notice = reporter.lastCall.args[0]; }); - describe('call', () => { - it('reports throwed exception', () => { - let spy = sinon.spy(); - client.notify = spy; - let fn = () => { throw err; }; - try { - client.call(fn, 'hello', 'world'); - } catch (_) {} - - expect(spy).to.have.been.called; - expect(spy.lastCall.args).to.deep.equal([{ - error: err, - params: {arguments: ['hello', 'world']}, - }]); - }); + it('reports context.url', () => { + expect(notice.context.url).to.equal('http://localhost:9876/context.html'); }); - describe('offline', () => { - let spy; + it('reports context.rootDirectory', () => { + expect(notice.context.rootDirectory).to.equal('http://localhost:9876'); + }); + }); - beforeEach(() => { - let event = new Event('offline'); - window.dispatchEvent(event); + describe('wrap', () => { + it('does not invoke function immediately', () => { + let fn = sinon.spy(); + client.wrap(fn); + expect(fn).not.to.have.been.called; + }); - let promise = client.notify(err); - spy = sinon.spy(); - promise.then(spy); - }); + it('creates wrapper that invokes function with passed args', () => { + let fn = sinon.spy(); + let wrapper: any = client.wrap(fn); + wrapper('hello', 'world'); + expect(fn).to.have.been.called; + expect(fn.lastCall.args).to.deep.equal(['hello', 'world']); + }); - it('causes client to not report errors', () => { - expect(reporter).not.to.have.been.called; - }); + it('sets _airbrake and inner properties', () => { + let fn = sinon.spy(); + let wrapper = client.wrap(fn); + expect(wrapper._airbrake).to.equal(true); + expect(wrapper.inner).to.equal(fn); + }); - describe('online', () => { - beforeEach(() => { - let event = new Event('online'); - window.dispatchEvent(event); - }); - - it('causes client to report queued errors', () => { - expect(reporter).to.have.been.called; - }); - - it('resolves promise', (done) => { - setTimeout(() => { - expect(spy).to.have.been.called; - done(); - }, 0); - }); - }); + it('copies function properties', () => { + let fn = sinon.spy(); + (fn as any).prop = 'hello'; + let wrapper: any = client.wrap(fn); + expect(wrapper.prop).to.equal('hello'); }); - describe('unhandledrejection event', () => { - it('notifies about unhandled rejection', (done) => { - new Promise((_resolve, reject) => { - reject(err); - }); + it('reports throwed exception', () => { + let spy = sinon.spy(); + client.notify = spy; + let fn = () => { + throw err; + }; + let wrapper: any = client.wrap(fn); + try { + wrapper('hello', 'world'); + } catch (err) {} + + expect(spy).to.have.been.called; + expect(spy.lastCall.args).to.deep.equal([ + { + error: err, + params: { arguments: ['hello', 'world'] }, + }, + ]); + }); - setTimeout(() => { - expect(reporter).to.have.been.called; - done(); - }, 0); - }); + it('wraps arguments', () => { + let fn = sinon.spy(); + let wrapper: any = client.wrap(fn); + let arg1 = () => null; + wrapper(arg1); - it('does not notify about airbrake rejections', (done) => { - new Promise((_resolve, reject) => { - reject(new Error('airbrake: test')); - }); + expect(fn).to.have.been.called; + let arg1Wrapper = fn.lastCall.args[0]; + expect(arg1Wrapper._airbrake).to.equal(true); + expect(arg1Wrapper.inner).to.equal(arg1); + }); + }); + + describe('call', () => { + it('reports throwed exception', () => { + let spy = sinon.spy(); + client.notify = spy; + let fn = () => { + throw err; + }; + try { + client.call(fn, 'hello', 'world'); + } catch (_) {} + + expect(spy).to.have.been.called; + expect(spy.lastCall.args).to.deep.equal([ + { + error: err, + params: { arguments: ['hello', 'world'] }, + }, + ]); + }); + }); - setTimeout(() => { - expect(reporter).not.to.have.been.called; - done(); - }, 0); - }); + describe('offline', () => { + let spy; - it('notifies about errors thrown in Promise.then', (done) => { - Promise.resolve(null).then(() => { - throw err; - }); + beforeEach(() => { + let event = new Event('offline'); + window.dispatchEvent(event); - setTimeout(() => { - expect(reporter).to.have.been.called; - done(); - }, 0); - }); + let promise = client.notify(err); + spy = sinon.spy(); + promise.then(spy); + }); + + it('causes client to not report errors', () => { + expect(reporter).not.to.have.been.called; + }); - it('notifies about rejections with no reason', (done) => { - new Promise((_resolve, reject) => { - reject(); - }); + describe('online', () => { + beforeEach(() => { + let event = new Event('online'); + window.dispatchEvent(event); + }); - setTimeout(() => { - expect(reporter).to.have.been.called; - done(); - }, 0); - }); + it('causes client to report queued errors', () => { + expect(reporter).to.have.been.called; + }); + + it('resolves promise', (done) => { + setTimeout(() => { + expect(spy).to.have.been.called; + done(); + }, 0); + }); + }); + }); - it('notifies about errors thrown in Promise.catch', (done) => { - let p = new Promise((_, reject) => { - setTimeout(() => { - reject(null); - }, 0); - }); - p.catch(() => { - throw err; - }); - - setTimeout(() => { - expect(reporter).to.have.been.called; - done(); - }, 50); - }); + describe('unhandledrejection event', () => { + it('notifies about unhandled rejection', (done) => { + new Promise((_resolve, reject) => { + reject(err); + }); + + setTimeout(() => { + expect(reporter).to.have.been.called; + done(); + }, 0); + }); + + it('does not notify about airbrake rejections', (done) => { + new Promise((_resolve, reject) => { + reject(new Error('airbrake: test')); + }); + + setTimeout(() => { + expect(reporter).not.to.have.been.called; + done(); + }, 0); + }); + + it('notifies about errors thrown in Promise.then', (done) => { + Promise.resolve(null).then(() => { + throw err; + }); + + setTimeout(() => { + expect(reporter).to.have.been.called; + done(); + }, 0); + }); + + it('notifies about rejections with no reason', (done) => { + new Promise((_resolve, reject) => { + reject(); + }); + + setTimeout(() => { + expect(reporter).to.have.been.called; + done(); + }, 0); + }); + + it('notifies about errors thrown in Promise.catch', (done) => { + let p = new Promise((_, reject) => { + setTimeout(() => { + reject(null); + }, 0); + }); + p.catch(() => { + throw err; + }); + + setTimeout(() => { + expect(reporter).to.have.been.called; + done(); + }, 50); }); + }); }); diff --git a/test/unit/historian_test.ts b/test/unit/historian_test.ts index b66797528..bf51fa9f4 100644 --- a/test/unit/historian_test.ts +++ b/test/unit/historian_test.ts @@ -1,151 +1,145 @@ -import Client from '../../src/client'; import * as sinon from 'sinon'; +import Client from '../../src/client'; import { expect } from './sinon_chai'; - class Location { - private s: string; + private s: string; - constructor(s: string) { - this.s = s; - } + constructor(s: string) { + this.s = s; + } - toString(): string { - return this.s; - } + public toString(): string { + return this.s; + } } describe('instrumentation', () => { - let processor, reporter, client; + let processor, reporter, client; + + beforeEach(() => { + processor = sinon.spy((data) => { + return data; + }); + reporter = sinon.spy(() => { + return Promise.resolve({ id: 1 }); + }); + client = new Client({ + projectId: 1, + projectKey: 'abc', + processor, + reporter, + }); + }); + + describe('location', () => { + beforeEach(() => { + let locations = ['', 'http://hello/world', 'foo', new Location('/')]; + for (let loc of locations) { + try { + window.history.pushState(null, '', loc as string); + } catch (_) {} + } + client.notify(new Error('test')); + }); + + it('records browser history', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let history = notice.context.history; + + let state = history[history.length - 3]; + delete state.date; + expect(state).to.deep.equal({ + type: 'location', + from: '/context.html', + to: '/world', + }); + + state = history[history.length - 2]; + delete state.date; + expect(state).to.deep.equal({ + type: 'location', + from: '/world', + to: '/foo', + }); + + state = history[history.length - 1]; + delete state.date; + expect(state).to.deep.equal({ + type: 'location', + from: '/foo', + to: '/', + }); + }); + }); + describe('XHR', () => { beforeEach(() => { - processor = sinon.spy((data) => { - return data; - }); - reporter = sinon.spy(() => { - return Promise.resolve({id: 1}); - }); - client = new Client({ - projectId: 1, - projectKey: 'abc', - processor: processor, - reporter: reporter, - }); + let req = new XMLHttpRequest(); + req.open('GET', 'http://ip2c.org/self', false); + req.send(); + client.notify(new Error('test')); }); - describe('location', () => { - beforeEach(() => { - let locations = [ - '', - 'http://hello/world', - 'foo', - new Location('/'), - ]; - for (let loc of locations) { - try { - window.history.pushState(null, '', loc as string); - } catch (_) {} - } - client.notify(new Error('test')); - }); - - it('records browser history', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let history = notice.context.history; - - let state = history[history.length - 3]; - delete state.date; - expect(state).to.deep.equal({ - type: 'location', - from: '/context.html', - to: '/world', - }); - - state = history[history.length - 2]; - delete state.date; - expect(state).to.deep.equal({ - type: 'location', - from: '/world', - to: '/foo', - }); - - state = history[history.length - 1]; - delete state.date; - expect(state).to.deep.equal({ - type: 'location', - from: '/foo', - to: '/', - }); - }); + it('records request', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let history = notice.context.history; + + let state = history[history.length - 1]; + expect(state.type).to.equal('xhr'); + expect(state.method).to.equal('GET'); + expect(state.url).to.equal('http://ip2c.org/self'); + expect(state.statusCode).to.equal(200); + expect(state.duration).to.be.a('number'); }); + }); - describe('XHR', () => { - beforeEach(() => { - let req = new XMLHttpRequest(); - req.open('GET', 'http://ip2c.org/self', false); - req.send(); - client.notify(new Error('test')); - }); - - it('records request', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let history = notice.context.history; - - let state = history[history.length - 1]; - expect(state.type).to.equal('xhr'); - expect(state.method).to.equal('GET'); - expect(state.url).to.equal('http://ip2c.org/self'); - expect(state.statusCode).to.equal(200); - expect(state.duration).to.be.a('number'); - }); + describe('fetch', () => { + beforeEach(() => { + let promise = fetch('http://ip2c.org/4.4.4.4'); + promise.then(() => { + client.notify(new Error('test')); + }); + return promise; + }); + + it('records request', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let history = notice.context.history; + + let state = history[history.length - 1]; + expect(state.type).to.equal('xhr'); + expect(state.method).to.equal('GET'); + expect(state.url).to.equal('http://ip2c.org/4.4.4.4'); + expect(state.statusCode).to.equal(200); + expect(state.duration).to.be.a('number'); }); + }); - describe('fetch', () => { - beforeEach(() => { - let promise = fetch('http://ip2c.org/4.4.4.4'); - promise.then(() => { - client.notify(new Error('test')); - }); - return promise; - }); - - it('records request', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let history = notice.context.history; - - let state = history[history.length - 1]; - expect(state.type).to.equal('xhr'); - expect(state.method).to.equal('GET'); - expect(state.url).to.equal('http://ip2c.org/4.4.4.4'); - expect(state.statusCode).to.equal(200); - expect(state.duration).to.be.a('number'); - }); + describe('console', () => { + beforeEach(() => { + for (let i = 0; i < 25; i++) { + console.log(i); + } + client.notify(new Error('test')); }); - describe('console', () => { - beforeEach(() => { - for (let i = 0; i < 25; i++) { - console.log(i); - } - client.notify(new Error('test')); - }); - - it('records log message', () => { - expect(reporter).to.have.been.called; - let notice = reporter.lastCall.args[0]; - let history = notice.context.history; - expect(history).to.have.length(20); - - for (let i in history) { - let state = history[i]; - expect(state.type).to.equal('log'); - expect(state.severity).to.equal('log'); - expect(state.arguments).to.deep.equal([+i + 5]); - expect(state.date).to.exist; - } - }); + it('records log message', () => { + expect(reporter).to.have.been.called; + let notice = reporter.lastCall.args[0]; + let history = notice.context.history; + expect(history).to.have.length(20); + + for (let i in history) { + let state = history[i]; + expect(state.type).to.equal('log'); + expect(state.severity).to.equal('log'); + expect(state.arguments).to.deep.equal([+i + 5]); + expect(state.date).to.exist; + } }); + }); }); diff --git a/test/unit/jsonify_notice_test.ts b/test/unit/jsonify_notice_test.ts index 6e62ae4e9..b5dfeeb7e 100644 --- a/test/unit/jsonify_notice_test.ts +++ b/test/unit/jsonify_notice_test.ts @@ -1,91 +1,92 @@ -import Notice from '../../src/notice'; import jsonifyNotice from '../../src/jsonify_notice'; +import Notice from '../../src/notice'; import { expect } from './sinon_chai'; - describe('jsonify_notice', () => { - const maxLength = 30000; - - context('when called with notice', () => { - let notice = { - params: {arguments: []}, - environment: {env1: 'value1'}, - session: {session1: 'value1'}, - }; - let json; - - beforeEach(() => { - json = jsonifyNotice(notice as Notice); - }); - - it('produces valid JSON', () => { - expect(JSON.parse(json)).to.deep.equal(notice); - }); + const maxLength = 30000; + + context('when called with notice', () => { + let notice = { + params: { arguments: [] }, + environment: { env1: 'value1' }, + session: { session1: 'value1' }, + }; + let json; + + beforeEach(() => { + json = jsonifyNotice(notice as Notice); + }); + + it('produces valid JSON', () => { + expect(JSON.parse(json)).to.deep.equal(notice); + }); + }); + + context('when called with huge notice', () => { + let json; + + beforeEach(() => { + let notice = { + params: { arr: [] }, + }; + for (let i = 0; i < 100; i++) { + notice.params.arr.push(Array(100).join('x')); + } + json = jsonifyNotice(notice as Notice, { maxLength }); }); - context('when called with huge notice', () => { - let json; - - beforeEach(() => { - let notice = { - params: {arr: []}, - }; - for (let i = 0; i < 100; i++) { - notice.params.arr.push(Array(100).join('x')); - } - json = jsonifyNotice(notice as Notice, {maxLength}); - }); - - it('limits json size', () => { - expect(json.length).to.be.below(maxLength); - }); + it('limits json size', () => { + expect(json.length).to.be.below(maxLength); }); + }); - context('when called with one huge string', () => { - let json; + context('when called with one huge string', () => { + let json; - beforeEach(() => { - let notice = { - params: {str: Array(100000).join('x')}, - }; - json = jsonifyNotice(notice as Notice, {maxLength}); - }); + beforeEach(() => { + let notice = { + params: { str: Array(100000).join('x') }, + }; + json = jsonifyNotice(notice as Notice, { maxLength }); + }); - it('limits json size', () => { - expect(json.length).to.be.below(maxLength); - }); + it('limits json size', () => { + expect(json.length).to.be.below(maxLength); + }); + }); + + context('when called with huge error message', () => { + let json; + + beforeEach(() => { + let notice = { + errors: [ + { + type: Array(100000).join('x'), + message: Array(100000).join('x'), + }, + ], + }; + json = jsonifyNotice(notice as Notice, { maxLength }); }); - context('when called with huge error message', () => { - let json; - - beforeEach(() => { - let notice = { - errors: [{ - type: Array(100000).join('x'), - message: Array(100000).join('x'), - }], - }; - json = jsonifyNotice(notice as Notice, {maxLength}); - }); - - it('limits json size', () => { - expect(json.length).to.be.below(maxLength); - }); + it('limits json size', () => { + expect(json.length).to.be.below(maxLength); }); + }); - context('when called with huger array', () => { - let json; + context('when called with huger array', () => { + let json; - beforeEach(() => { - let notice = { - params: {param1: Array(100000)}, - }; - json = jsonifyNotice(notice as Notice, {maxLength}); - }); + beforeEach(() => { + let notice = { + params: { param1: Array(100000) }, + }; + json = jsonifyNotice(notice as Notice, { maxLength }); + }); - it('limits json size', () => { - expect(json.length).to.be.below(maxLength); - }); - }) + it('limits json size', () => { + expect(json.length).to.be.below(maxLength); + }); + }); }); diff --git a/test/unit/processor/stacktracejs_test.ts b/test/unit/processor/stacktracejs_test.ts index 8e917666c..12312bdf8 100644 --- a/test/unit/processor/stacktracejs_test.ts +++ b/test/unit/processor/stacktracejs_test.ts @@ -1,54 +1,53 @@ -import {NoticeError} from '../../../src/notice'; +import { NoticeError } from '../../../src/notice'; import processor from '../../../src/processor/stacktracejs'; import { expect } from '../sinon_chai'; - describe('stacktracejs processor', () => { - let error: NoticeError; - - describe('Error', () => { - beforeEach(() => { - try { - throw new Error('BOOM'); - } catch (err) { - error = processor(err); - } - }); - - it('provides type and message', () => { - expect(error.type).to.equal('Error'); - expect(error.message).to.equal('BOOM'); - }); - - it('provides backtrace', () => { - let backtrace = error.backtrace; - expect(backtrace.length).to.equal(6); - - let frame = backtrace[0]; - expect(frame.file).to.contain('test/unit/processor/stacktracejs_test'); - expect(frame.function).to.equal('Context.'); - expect(frame.line).to.be.a('number'); - expect(frame.column).to.be.a('number'); - }); + let error: NoticeError; + + describe('Error', () => { + beforeEach(() => { + try { + throw new Error('BOOM'); + } catch (err) { + error = processor(err); + } + }); + + it('provides type and message', () => { + expect(error.type).to.equal('Error'); + expect(error.message).to.equal('BOOM'); + }); + + it('provides backtrace', () => { + let backtrace = error.backtrace; + expect(backtrace.length).to.equal(6); + + let frame = backtrace[0]; + expect(frame.file).to.contain('test/unit/processor/stacktracejs_test'); + expect(frame.function).to.equal('Context.'); + expect(frame.line).to.be.a('number'); + expect(frame.column).to.be.a('number'); }); + }); - describe('text', () => { - beforeEach(() => { - let err: any; - err = 'BOOM'; + describe('text', () => { + beforeEach(() => { + let err: any; + err = 'BOOM'; - error = processor(err as Error); - }); + error = processor(err as Error); + }); - it('uses text as error message', () => { - expect(error.type).to.equal(''); - expect(error.message).to.equal('BOOM'); - }); + it('uses text as error message', () => { + expect(error.type).to.equal(''); + expect(error.message).to.equal('BOOM'); + }); - it('provides backtrace', () => { - let backtrace = error.backtrace; - expect(backtrace.length).to.equal(5); - }); + it('provides backtrace', () => { + let backtrace = error.backtrace; + expect(backtrace.length).to.equal(5); }); + }); }); diff --git a/test/unit/sinon_chai.ts b/test/unit/sinon_chai.ts index 95f79c3d8..c12e06c42 100644 --- a/test/unit/sinon_chai.ts +++ b/test/unit/sinon_chai.ts @@ -2,5 +2,4 @@ import chai from 'chai'; import sinonChai from 'sinon-chai'; chai.use(sinonChai); - export = chai; diff --git a/test/unit/truncate_test.ts b/test/unit/truncate_test.ts index f072a7b02..099773a38 100644 --- a/test/unit/truncate_test.ts +++ b/test/unit/truncate_test.ts @@ -1,171 +1,171 @@ import { truncate } from '../../src/jsonify_notice'; import { expect } from './sinon_chai'; - describe('truncate', () => { - it('works', () => { - let tests = [ - [undefined], - [null], - [true], - [false], - [new Boolean(true)], - [1], - [3.14], - [new Number(1)], - [Infinity], - [NaN], - [Math.LN2], - ['hello'], - [new String('hello'), 'hello'], - [['foo', 'bar']], - [{'foo': 'bar'}], - [new Date()], - [/a/], - [new RegExp('a')], - [new Error('hello'), 'Error: hello'], - ]; - for (let test of tests) { - let wanted = test.length >= 2 ? test[1] : test[0]; - if (isNaN(wanted as any)) { - continue; - } - expect(truncate(test[0])).to.equal(wanted); - } + it('works', () => { + let tests = [ + [undefined], + [null], + [true], + [false], + [new Boolean(true)], + [1], + [3.14], + [new Number(1)], + [Infinity], + [NaN], + [Math.LN2], + ['hello'], + [new String('hello'), 'hello'], + [['foo', 'bar']], + [{ foo: 'bar' }], + [new Date()], + [/a/], + [new RegExp('a')], + [new Error('hello'), 'Error: hello'], + ]; + for (let test of tests) { + let wanted = test.length >= 2 ? test[1] : test[0]; + if (isNaN(wanted as any)) { + continue; + } + expect(truncate(test[0])).to.equal(wanted); + } + }); + + it('omits functions in object', () => { + let obj = { + foo: 'bar', + fn1: Math.sin, + fn2: () => null, + fn3: new Function('x', 'y', 'return x * y'), + }; + + expect(truncate(obj)).to.deep.equal({ foo: 'bar' }); + }); + + it('sets object type', () => { + let e = new Event('load'); + + let got = truncate(e); + expect(got.__type).to.equal('Event'); + }); + + context('when called with object with circular references', () => { + let obj: any = { foo: 'bar' }; + obj.circularRef = obj; + obj.circularList = [obj, obj]; + let truncated; + + beforeEach(() => { + truncated = truncate(obj); }); - it('omits functions in object', () => { - let obj = { - foo: 'bar', - fn1: Math.sin, - fn2: () => null, - fn3: new Function('x', 'y', 'return x * y'), - }; - - expect(truncate(obj)).to.deep.equal({foo: 'bar'}); + it('produces object with resolved circular references', () => { + expect(truncated).to.deep.equal({ + foo: 'bar', + circularRef: '[Circular ~]', + circularList: ['[Circular ~]', '[Circular ~]'], + }); }); + }); - it('sets object type', () => { - let e = new Event('load'); + context('when called with object with complex circular references', () => { + let a: any = { x: 1 }; + a.a = a; + let b: any = { x: 2 }; + b.a = a; + let c = { a, b }; - let got = truncate(e); - expect(got.__type).to.equal('Event'); - }); + let obj: any = { list: [a, b, c] }; + obj.obj = obj; + + let truncated; - context('when called with object with circular references', () => { - let obj: any = {foo: 'bar'}; - obj.circularRef = obj; - obj.circularList = [obj, obj]; - let truncated; - - beforeEach(() => { - truncated = truncate(obj); - }); - - it('produces object with resolved circular references', () => { - expect(truncated).to.deep.equal({ - 'foo': 'bar', - 'circularRef': '[Circular ~]', - 'circularList': ['[Circular ~]', '[Circular ~]'], - }); - }); + beforeEach(() => { + truncated = truncate(obj); }); - context('when called with object with complex circular references', () => { - let a: any = {x: 1}; - a.a = a; - let b: any = {x: 2}; - b.a = a; - let c = {a: a, b: b}; - - let obj: any = {list: [a, b, c]}; - obj.obj = obj; - - let truncated; - - beforeEach(() => { - truncated = truncate(obj); - }); - - it('produces object with resolved circular references', () => { - expect(truncated).to.deep.equal({ - 'list': [{ - 'x': 1, - 'a': '[Circular ~.list.0]' - }, { - 'x': 2, - 'a': '[Circular ~.list.0]' - }, { - 'a': '[Circular ~.list.0]', - 'b': '[Circular ~.list.1]' - }], - 'obj': '[Circular ~]' - }); - }); + it('produces object with resolved circular references', () => { + expect(truncated).to.deep.equal({ + list: [ + { + x: 1, + a: '[Circular ~.list.0]', + }, + { + x: 2, + a: '[Circular ~.list.0]', + }, + { + a: '[Circular ~.list.0]', + b: '[Circular ~.list.1]', + }, + ], + obj: '[Circular ~]', + }); }); + }); - context('when called with deeply nested objects', () => { - let obj = {}; - let tmp: any = obj; - for (let i = 0; i < 100; i++) { - tmp.value = i; - tmp.obj = {}; - tmp = tmp.obj; - } - - let truncated; - - beforeEach(() => { - truncated = truncate(obj, {level: 1}); - }); - - it('produces truncated object', () => { - expect(truncated).to.deep.equal({ - 'value': 0, - 'obj': { - 'value': 1, - 'obj': { - 'value': 2, - 'obj': { - 'value': 3, - 'obj': '[Truncated Object]', - }, - }, - }, - }); - }); + context('when called with deeply nested objects', () => { + let obj = {}; + let tmp: any = obj; + for (let i = 0; i < 100; i++) { + tmp.value = i; + tmp.obj = {}; + tmp = tmp.obj; + } + + let truncated; + + beforeEach(() => { + truncated = truncate(obj, { level: 1 }); }); - context('when called with object created with Object.create(null)', () => { - it('works', () => { - let obj: any = Object.create(null); - obj.foo = 'bar'; - expect(truncate(obj)).to.deep.equal({ foo: 'bar' }); - }); + it('produces truncated object', () => { + expect(truncated).to.deep.equal({ + value: 0, + obj: { + value: 1, + obj: { + value: 2, + obj: { + value: 3, + obj: '[Truncated Object]', + }, + }, + }, + }); }); + }); - describe('keysBlacklist', () => { - it('filters blacklisted keys', () => { - let obj = { - params: { - password: '123', - sub: { - secret: '123', - }, - }, - }; - let keysBlacklist = [ - /password/, - /secret/, - ]; - let truncated = truncate(obj, {keysBlacklist}); - - expect(truncated).to.deep.equal({ - 'params': { - 'password': '[Filtered]', - 'sub': {'secret': '[Filtered]'}, - }, - }); - }); + context('when called with object created with Object.create(null)', () => { + it('works', () => { + let obj: any = Object.create(null); + obj.foo = 'bar'; + expect(truncate(obj)).to.deep.equal({ foo: 'bar' }); + }); + }); + + describe('keysBlacklist', () => { + it('filters blacklisted keys', () => { + let obj = { + params: { + password: '123', + sub: { + secret: '123', + }, + }, + }; + let keysBlacklist = [/password/, /secret/]; + let truncated = truncate(obj, { keysBlacklist }); + + expect(truncated).to.deep.equal({ + params: { + password: '[Filtered]', + sub: { secret: '[Filtered]' }, + }, + }); }); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 7eaff2099..7da73ded7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,14 @@ { - "compilerOptions": { - "lib": ["ES2015", "DOM"], - "target": "ES5", - "moduleResolution": "node", - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "preserveConstEnums": true, - "sourceMap": true, - "skipLibCheck": true, - "esModuleInterop": true - } + "compilerOptions": { + "lib": ["ES2015", "DOM"], + "target": "ES5", + "moduleResolution": "node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "preserveConstEnums": true, + "sourceMap": true, + "skipLibCheck": true, + "esModuleInterop": true + } } diff --git a/tslint.json b/tslint.json index 370598cc2..481b0657b 100644 --- a/tslint.json +++ b/tslint.json @@ -1,101 +1,13 @@ { - "jsRules": { - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "indent": [ - true, - "spaces" - ], - "no-duplicate-variable": true, - "no-eval": true, - "no-trailing-whitespace": true, - "no-unsafe-finally": true, - "one-line": [ - true, - "check-open-brace", - "check-whitespace" - ], - "quotemark": [ - true, - "single" - ], - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "variable-name": [ - true, - "ban-keywords" - ], - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - }, - "rules": { - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "indent": [ - true, - "spaces" - ], - "no-eval": false, - "no-internal-module": true, - "no-trailing-whitespace": true, - "no-unsafe-finally": true, - "no-var-keyword": true, - "one-line": [ - true, - "check-open-brace", - "check-whitespace" - ], - "quotemark": [ - true, - "single" - ], - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "variable-name": [ - true, - "ban-keywords" - ], - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - } + "extends": ["tslint:latest", "tslint-config-prettier"], + "rules": { + "prefer-const": false, + "object-literal-sort-keys": false, + "variable-name": [true, "allow-leading-underscore"], + "no-console": [true, "log"], + "no-bitwise": false, + "no-implicit-dependencies": false, + "no-submodule-imports": [true, "promise-polyfill/src/polyfill"], + "member-ordering": false + } } diff --git a/webpack.config.js b/webpack.config.js index f25225d53..4a865c121 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,7 @@ -const path = require('path') -const webpack = require('webpack') -const glob = require('glob') -const pkg = require('./package.json') +const path = require('path'); +const webpack = require('webpack'); +const glob = require('glob'); +const pkg = require('./package.json'); function newConfig() { return { @@ -68,32 +68,32 @@ function newConfig() { }), new webpack.BannerPlugin({ banner: 'airbrake-js v' + pkg.version }), ], - } + }; } -var client = newConfig() -var clientFiles = ['./src/client.ts'] +var client = newConfig(); +var clientFiles = ['./src/client.ts']; client.entry = { client: clientFiles, -} -client.output.library = ['airbrakeJs', 'Client'] +}; +client.output.library = ['airbrakeJs', 'Client']; -var clientMin = Object.assign({}, client) -clientMin.mode = 'production' +var clientMin = Object.assign({}, client); +clientMin.mode = 'production'; clientMin.entry = { 'client.min': clientFiles, -} +}; -var express = newConfig() +var express = newConfig(); express.entry = { 'instrumentation/express': './src/instrumentation/express.ts', -} -express.output.library = ['airbrakeJs', 'instrumentation', 'express'] +}; +express.output.library = ['airbrakeJs', 'instrumentation', 'express']; -var hapi = newConfig() +var hapi = newConfig(); hapi.entry = { 'instrumentation/hapi': './src/instrumentation/hapi.ts', -} -express.output.library = ['airbrakeJs', 'instrumentation', 'hapi'] +}; +express.output.library = ['airbrakeJs', 'instrumentation', 'hapi']; -module.exports = [client, clientMin, express, hapi] +module.exports = [client, clientMin, express, hapi]; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..92f6ce6c5 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4249 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@sinonjs/commons@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849" + integrity sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@3.0.0", "@sinonjs/formatio@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.0.0.tgz#9d282d81030a03a03fa0c5ce31fd8786a4da311a" + integrity sha512-vdjoYLDptCgvtJs57ULshak3iJe4NW3sJ3g36xVDGff5AE8P30S6A093EIEPjdi2noGhfuNOEkbxt3J3awFW1w== + dependencies: + "@sinonjs/samsam" "2.1.0" + +"@sinonjs/samsam@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.0.tgz#b8b8f5b819605bd63601a6ede459156880f38ea3" + integrity sha512-5x2kFgJYupaF1ns/RmharQ90lQkd2ELS8A9X0ymkAAdemYHGtI2KiUHG8nX2WU0T1qgnOU5YMqnBM2V7NUanNw== + dependencies: + array-from "^2.1.1" + +"@sinonjs/samsam@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.2.tgz#16947fce5f57258d01f1688fdc32723093c55d3f" + integrity sha512-ZwTHAlC9akprWDinwEPD4kOuwaYZlyMwVJIANsKNC3QVp0AHB04m7RnB4eqeWfgmxw8MGTzS9uMaw93Z3QcZbw== + +"@types/caseless@*": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a" + integrity sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A== + +"@types/chai@*", "@types/chai@4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" + integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== + +"@types/form-data@*": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" + integrity sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ== + dependencies: + "@types/node" "*" + +"@types/mocha@5.2.5": + version "5.2.5" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073" + integrity sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww== + +"@types/node@*": + version "10.12.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.2.tgz#d77f9faa027cadad9c912cd47f4f8b07b0fb0864" + integrity sha512-53ElVDSnZeFUUFIYzI8WLQ25IhWzb6vbddNp8UHlXQyU0ET2RhV5zg0NfubzU7iNMh5bBXb0htCzfvrSVNgzaQ== + +"@types/request@2.48.1": + version "2.48.1" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.1.tgz#e402d691aa6670fbbff1957b15f1270230ab42fa" + integrity sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg== + dependencies: + "@types/caseless" "*" + "@types/form-data" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + +"@types/sinon-chai@3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.1.tgz#731e0e277a30d41f0c6a25548d10fe22db501c22" + integrity sha512-6iO999tZP+1cixtz4jGaVS/aKRq2GYvFUhJzHWejYVUfTP0O98mGb0WrCaC9ARZVKfkm2FZrn3c0p3iaHfK+6A== + dependencies: + "@types/chai" "*" + "@types/sinon" "*" + +"@types/sinon@*": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-5.0.5.tgz#de600fa07eb1ec9d5f55669d5bac46a75fc88115" + integrity sha512-Wnuv66VhvAD2LEJfZkq8jowXGxe+gjVibeLCYcVBp7QLdw0BFx2sRkKzoiiDkYEPGg5VyqO805Rcj0stVjQwCQ== + +"@types/sinon@5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-5.0.7.tgz#0d9f89dd0c9988c4f1505a92a3a324ee7bdb18a6" + integrity sha512-opwMHufhUwkn/UUDk35LDbKJpA2VBsZT8WLU8NjayvRLGPxQkN+8XmfC2Xl35MAscBE8469koLLBjaI3XLEIww== + +"@types/tough-cookie@*": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.4.tgz#821878b81bfab971b93a265a561d54ea61f9059f" + integrity sha512-Set5ZdrAaKI/qHdFlVMgm/GsAv/wkXhSTuZFkJ+JI7HK+wIkIlOaUXSXieIvJ0+OvGIqtREFoE+NHJtEq0gtEw== + +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== + +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== + +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== + +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== + +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== + +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== + +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== + +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.6.2: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + +ajv@^6.1.0: + version "6.5.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" + integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +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" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async@^2.0.0, async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-runtime@^6.0.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + integrity sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +bluebird@^3.3.0, bluebird@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@^1.16.1: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^0.1.2: + version "0.1.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" + integrity sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY= + dependencies: + expand-range "^0.1.0" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^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" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +cacache@^11.0.2: + version "11.3.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" + integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== + dependencies: + bluebird "^3.5.3" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.3" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +chai@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@^2.0.2, chokidar@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.5.5: + version "0.5.9" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" + integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +colors@^1.1.0, colors@^1.1.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" + integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ== + +combine-lists@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" + integrity sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y= + dependencies: + lodash "^4.5.0" + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@^2.12.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1, component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@1.6.2, concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect@^3.6.0: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +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" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^2.2.0, core-js@^2.4.0: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-fetch@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" + integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +date-format@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8" + integrity sha1-YV6CjiM90aubua4JUODOzPpuytg= + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.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" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" + integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg== + dependencies: + xregexp "4.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@3.5.0, diff@^3.2.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" + integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +encodeurl@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" + integrity sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.1.1" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" + integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.2.1.tgz#b60281c35484a70ee0351ea0ebff83ec8c9522a2" + integrity sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w== + dependencies: + accepts "~1.3.4" + base64id "1.0.0" + cookie "0.3.1" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-stack-parser@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d" + integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw== + dependencies: + stackframe "^1.0.4" + +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.46" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" + integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +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" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +eventemitter3@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-braces@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" + integrity sha1-SIsdHSRRyz06axks/AMPRMWFX+o= + dependencies: + array-slice "^0.2.3" + array-unique "^0.2.1" + braces "^0.1.2" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" + integrity sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ= + dependencies: + is-number "^0.1.1" + repeat-string "^0.2.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extract-zip@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= + dependencies: + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +follow-redirects@^1.0.0: + version "1.5.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.9.tgz#c9ed9d748b814a39535716e531b9196a845d89c6" + integrity sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w== + dependencies: + debug "=3.1.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + integrity sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o= + dependencies: + null-check "^1.0.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +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" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + 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@^7.0.5, glob@^7.1.1, glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + 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" + +global-modules-path@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" + integrity sha512-HchvMJNYh9dGSCy8pOQ2O8u/hoXaL+0XhnrwH0RyLiSXMMTl9W3N6KUU73+JFOg5PGjtzl6VZzUQsnrpm7Szag== + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +http-errors@1.6.3, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy@^1.13.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imports-loader@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.8.0.tgz#030ea51b8ca05977c40a3abfd9b4088fe0be9a69" + integrity sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ== + dependencies: + loader-utils "^1.0.2" + source-map "^0.6.1" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-number@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" + integrity sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY= + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +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" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.7.0: + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +just-extend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-3.0.0.tgz#cee004031eaabf6406da03a7b84e4fe9d78ef288" + integrity sha512-Fu3T6pKBuxjWT/p4DkqGHFRsysc8OauWr4ZRTY9dIx07Y9O0RkoR5jcv28aeD1vuAwhm3nLkDurwLXoALp4DpQ== + +karma-chrome-launcher@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + integrity sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w== + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-mocha@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" + integrity sha1-7qrH/8DiAetjxGdEDStpx883eL8= + dependencies: + minimist "1.2.0" + +karma-sinon-chai@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/karma-sinon-chai/-/karma-sinon-chai-2.0.2.tgz#e28c109b989973abafc28a7c9f09ef24a05e07c2" + integrity sha512-SDgh6V0CUd+7ruL1d3yG6lFzmJNGRNQuEuCYXLaorruNP9nwQfA7hpsp4clx4CbOo5Gsajh3qUOT7CrVStUKMw== + +karma-sourcemap-loader@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + integrity sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg= + dependencies: + graceful-fs "^4.1.2" + +karma-spec-reporter@0.0.32: + version "0.0.32" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz#2e9c7207ea726771260259f82becb543209e440a" + integrity sha1-LpxyB+pyZ3EmAln4K+y1QyCeRAo= + dependencies: + colors "^1.1.2" + +karma-webpack@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-3.0.5.tgz#1ff1e3a690fb73ae95ee95f9ab58f341cfc7b40f" + integrity sha512-nRudGJWstvVuA6Tbju9tyGUfXTtI1UXMXoRHVmM2/78D0q6s/Ye2IC157PKNDC15PWFGR0mVIRtWLAdcfsRJoA== + dependencies: + async "^2.0.0" + babel-runtime "^6.0.0" + loader-utils "^1.0.0" + lodash "^4.0.0" + source-map "^0.5.6" + webpack-dev-middleware "^2.0.6" + +karma@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma/-/karma-3.1.1.tgz#94c8edd20fb9597ccde343326da009737fb0423a" + integrity sha512-NetT3wPCQMNB36uiL9LLyhrOt8SQwrEKt0xD3+KpTCfm0VxVyUJdPL5oTq2Ic5ouemgL/Iz4wqXEbF3zea9kQQ== + dependencies: + bluebird "^3.3.0" + body-parser "^1.16.1" + chokidar "^2.0.3" + colors "^1.1.0" + combine-lists "^1.0.0" + connect "^3.6.0" + core-js "^2.2.0" + di "^0.0.1" + dom-serialize "^2.2.0" + expand-braces "^0.1.1" + glob "^7.1.1" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^4.17.4" + log4js "^3.0.0" + mime "^2.3.1" + minimatch "^3.0.2" + optimist "^0.6.1" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "2.1.1" + source-map "^0.6.1" + tmp "0.0.33" + useragent "2.2.1" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + 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" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +loader-runner@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" + integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== + +loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.5.0: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log4js@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-3.0.6.tgz#e6caced94967eeeb9ce399f9f8682a4b2b28c8ff" + integrity sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ== + dependencies: + circular-json "^0.5.5" + date-format "^1.2.0" + debug "^3.1.0" + rfdc "^1.1.2" + streamroller "0.7.0" + +loglevelnext@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" + integrity sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A== + dependencies: + es6-symbol "^3.1.1" + object.assign "^4.1.0" + +lolex@^2.3.2: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-3.0.0.tgz#f04ee1a8aa13f60f1abd7b0e8f4213ec72ec193e" + integrity sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ== + +loud-rejection@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@2.2.x: + version "2.2.4" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" + integrity sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0= + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +map-age-cleaner@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz#098fb15538fd3dbe461f12745b0ca8568d4e3f74" + integrity sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== + +mime-types@~2.1.18: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + dependencies: + mime-db "~1.37.0" + +mime@^2.0.3, mime@^2.1.0, mime@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" + integrity sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@1.2.0, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" + integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nise@^1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.6.tgz#76cc3915925056ae6c405dd8ad5d12bde570c19f" + integrity sha512-1GedetLKzmqmgwabuMSqPsT7oumdR77SBpDfNNJhADRIeA3LN/2RVqR4fFqwvzhAqcTef6PPCzQwITE/YQ8S8A== + dependencies: + "@sinonjs/formatio" "3.0.0" + just-extend "^3.0.0" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + text-encoding "^0.6.4" + +node-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + +npm-packlist@^1.1.6: + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= + +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" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +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" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-polyfill@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.0.tgz#30059da54d1358ce905ac581f287e184aedf995d" + integrity sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA== + +proxy-from-env@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +puppeteer@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.11.0.tgz#63cdbe12b07275cd6e0b94bce41f3fcb20305770" + integrity sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ== + dependencies: + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^2.2.1" + mime "^2.0.3" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + +qjobs@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" + integrity sha1-x6jTI2BoNiBZp+RlH8aITosftK4= + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +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" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.3.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== + dependencies: + path-parse "^1.0.6" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rfdc@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.2.tgz#e6e72d74f5dc39de8f538f65e00c36c18018e349" + integrity sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA== + +rimraf@^2.4.4: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.4.4: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +semver@^5.0.1, semver@^5.3.0, semver@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +sinon-chai@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.3.0.tgz#8084ff99451064910fbe2c2cb8ab540c00b740ea" + integrity sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA== + +sinon@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.1.1.tgz#1202f317aa14d93cb9b69ff50b6bd49c0e05ffc9" + integrity sha512-iYagtjLVt1vN3zZY7D8oH7dkjNJEjLjyuzy8daX5+3bbQl8gaohrheB9VfH1O3L6LKuue5WTJvFluHiuZ9y3nQ== + dependencies: + "@sinonjs/commons" "^1.2.0" + "@sinonjs/formatio" "^3.0.0" + "@sinonjs/samsam" "^2.1.2" + diff "^3.5.0" + lodash.get "^4.4.2" + lolex "^3.0.0" + nise "^1.4.6" + supports-color "^5.5.0" + type-detect "^4.0.8" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" + integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs= + +socket.io-client@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.1.1.tgz#dcb38103436ab4578ddb026638ae2f21b623671f" + integrity sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~3.1.0" + engine.io-client "~3.2.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.2.0" + to-array "0.1.4" + +socket.io-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" + integrity sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" + integrity sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA== + dependencies: + debug "~3.1.0" + engine.io "~3.2.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.1.1" + socket.io-parser "~3.2.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-loader@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.4.tgz#c18b0dc6e23bf66f6792437557c569a11e072271" + integrity sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ== + dependencies: + async "^2.5.0" + loader-utils "^1.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stackframe@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" + integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamroller@0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b" + integrity sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ== + dependencies: + date-format "^1.2.0" + debug "^3.1.0" + mkdirp "^0.5.1" + readable-stream "^2.3.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.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" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" + integrity sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA== + +tar@^4: + version "4.4.7" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.7.tgz#14df45023ffdcd0c233befa2fc01ebb76ee39e7c" + integrity sha512-mR3MzsCdN0IEWjZRuF/J9gaWHnTwOvzjqPTcvi1xXgfKTDQRp39gRETPQEfPByAdEOGmZfx1HrRsn8estaEvtA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +terser-webpack-plugin@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz#7545da9ae5f4f9ae6a0ac961eb46f5e7c845cc26" + integrity sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.8.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.14.1.tgz#cc4764014af570bc79c79742358bd46926018a32" + integrity sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + +text-encoding@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk= + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +tmp@0.0.33, tmp@0.0.x: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +ts-loader@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.3.1.tgz#70614c8ec4354a9c8b89c9f97b2becb7a98a3980" + integrity sha512-fDDgpBH3SR8xlt2MasLdz3Yy611PQ/UY/KGyo7TgXhTRU/6sS8uGG0nJYnU1OdFBNKcoYbId1UTNaAOUn+i41g== + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tslint-config-prettier@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz#946ed6117f98f3659a65848279156d87628c33dc" + integrity sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw== + +tslint-loader@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/tslint-loader/-/tslint-loader-3.5.4.tgz#052af7f0772434451ea1b247bb55407f878a4c40" + integrity sha512-jBHNNppXut6SgZ7CsTBh+6oMwVum9n8azbmcYSeMlsABhWWoHwjq631vIFXef3VSd75cCdX3rc6kstsB7rSVVw== + dependencies: + loader-utils "^1.0.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + rimraf "^2.4.4" + semver "^5.3.0" + +tslint@^5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.0.tgz#47f2dba291ed3d580752d109866fb640768fca36" + integrity sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ== + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@^2.27.2: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" + integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-join@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" + integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +useragent@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e" + integrity sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4= + dependencies: + lru-cache "2.2.x" + tmp "0.0.x" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.1.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +v8-compile-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" + integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webpack-cli@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" + integrity sha512-Cnqo7CeqeSvC6PTdts+dywNi5CRlIPbLx1AoUPK2T6vC1YAugMG3IOoO9DmEscd+Dghw7uRlnzV1KwOe5IrtgQ== + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + global-modules-path "^2.3.0" + import-local "^2.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.2" + +webpack-dev-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz#a51692801e8310844ef3e3790e1eacfe52326fd4" + integrity sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw== + dependencies: + loud-rejection "^1.6.0" + memory-fs "~0.4.1" + mime "^2.1.0" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + url-join "^2.0.2" + webpack-log "^1.0.1" + +webpack-log@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" + integrity sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA== + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + loglevelnext "^1.0.1" + uuid "^3.1.0" + +webpack-sources@^1.1.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@4.26.1: + version "4.26.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.26.1.tgz#ff3a9283d363c07b3494dfa702d08f4f2ef6cb39" + integrity sha512-i2oOvEvuvLLSuSCkdVrknaxAhtUZ9g+nLSoHCWV0gDzqGX2DXaCrMmMUpbRsTSSLrUqAI56PoEiyMUZIZ1msug== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.1, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xregexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" + integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= + +yargs-parser@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs@^12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" + integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== + dependencies: + cliui "^4.0.0" + decamelize "^2.0.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^10.1.0" + +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= + dependencies: + fd-slicer "~1.0.1" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=