├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── docs └── failing-test.png ├── lib ├── index.js ├── result.js └── testConstantHeapSize.js ├── package-lock.json ├── package.json └── test ├── heap-footprint.test.js ├── integration.test.js └── usability.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | yarn-error.log 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | addons: 3 | apt: 4 | sources: 5 | - ubuntu-toolchain-r-test 6 | packages: 7 | - g++-4.8 8 | node_js: 9 | # - node # Latest 10 | - 10 11 | - 8 # LTS 12 | - 7.0 13 | before_install: 14 | - if [[ $TRAVIS_OS_NAME == "linux" ]]; then export CXX=g++-4.8; fi 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Leakage - Changelog 2 | 3 | ## v0.4.0 4 | 5 | - Make compatible with node 10: Use @airbnb/node-memwatch (see #27 by @alvis) 6 | 7 | ## v0.3.0 8 | 9 | - Support for asynchronous tests: `iterate.async(iterator: Function, options: ?Object): Promise` ([#7](https://github.com/andywer/leakage/issues/7)) 10 | - Changed API: `iterate(iterations: number, iterator: Function) => iterate(iterator: Function, options: ?Object)` 11 | - Pretty much a complete rewrite of the library 12 | - Added heap footprint tests checking the library's own footprint 13 | - Requires node 6+ 14 | 15 | ## v0.2.0 16 | 17 | - Added simple integration test and Travis CI config 18 | - Renamed `iteration()` method to `iterate` as described in the docs (kept `iteration` for b/c, though) 19 | - Supporting node 4+ (was node 6+ before) 20 | - Faster installation, since only `lib/` is published 21 | 22 | ## v0.1.0 23 | 24 | Initial release. Working `iterate()` method, detailed error, but no support for async functions and no unit tests yet. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Leakage - Memory Leak Testing for Node 2 | 3 | [![Build Status](https://travis-ci.org/andywer/leakage.svg?branch=master)](https://travis-ci.org/andywer/leakage) [![NPM Version](https://img.shields.io/npm/v/leakage.svg)](https://www.npmjs.com/package/leakage) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) 4 | 5 | Write leakage tests using Mocha or another test runner of your choice. 6 | 7 | Does not only support spotting and fixing memory leaks, but writing tests also enables you to prevent regressions and show that the code does not leak. 8 | 9 |

10 | Screencast 11 |

12 | 13 | 14 | ## Table of Contents 15 | 16 | - [Installation](#installation) 17 | - [Usage](#usage) 18 | - [Memory Management in JS?](#memory-management-in-js) 19 | - [API](#api) 20 | - [Under the Hood](#under-the-hood) 21 | - [Travis CI](#travis-ci) 22 | - [FAQ](#faq) 23 | - [Contribute](#contribute) 24 | - [License](#license) 25 | 26 | 27 | ## Installation 28 | 29 | ```sh 30 | npm install --save-dev leakage 31 | # or 32 | yarn --dev leakage 33 | ``` 34 | 35 | 36 | ## Usage 37 | 38 | In theory you could use any testing framework to run leakage tests. In practice, though, you want to use one that generates a minimal memory overhead itself. We suggest using Mocha or Tape, since they are quite simple and don't produce much noise in the captured data. 39 | 40 | ### Usage with Mocha 41 | 42 | ```js 43 | import myLib from 'my-lib' 44 | import { iterate } from 'leakage' 45 | 46 | describe('myLib', () => { 47 | it('does not leak when doing stuff', () => { 48 | iterate(() => { 49 | const instance = myLib.createInstance() 50 | instance.doStuff('foo', 'bar') 51 | }) 52 | }) 53 | }) 54 | ``` 55 | 56 | `iterate()` will run the function several times, create a heap snapshot and repeat that process until there is a set of heap diffs. If a memory leak has been detected an error with some debugging information will be thrown. 57 | 58 | **Make sure you run all tests serially** in order to get clean heap diffs. Mocha should run them sequentially by default. 59 | 60 | Use `iterate.async()` for asynchronous test code. See [Asynchronous Tests](#asynchronous-tests) and [API](#api) for details. 61 | 62 | 63 | ### Usage with tape 64 | 65 | ```js 66 | import test from 'tape' 67 | import myLib from 'my-lib' 68 | import { iterate } from 'leakage' 69 | 70 | test('myLib does not leak when doing stuff', () => { 71 | iterate(() => { 72 | const instance = myLib.createInstance() 73 | instance.doStuff('foo', 'bar') 74 | }) 75 | }) 76 | ``` 77 | 78 | 79 | ### Asynchronous Tests 80 | 81 | Use `iterate.async()` to test asynchronous code. The iterator function is supposed to return a promise and `iterate.async()` will return a promise itself. In case of a memory leak that returned promise will be rejected instead of `iterate` failing synchronously. 82 | 83 | *Do not forget to return the promise in your test or use async functions and `await iterate.async()`.* 84 | 85 | ```js 86 | import fetch from 'isomorphic-fetch' 87 | import { iterate } from 'leakage' 88 | 89 | describe('isomorphic-fetch', () => { 90 | it('does not leak when requesting data and parsing JSON', async () => { 91 | await iterate.async(async () => { 92 | const response = await fetch() 93 | await response.json() 94 | }) 95 | }) 96 | }) 97 | ``` 98 | 99 | 100 | ## Memory Management in JS? 101 | 102 | Since every JavaScript runtime comes with a garbage collector you should not have to care about memory allocation / freeing memory at all, right? **Sadly not.** 103 | 104 | Memory leaks are a common problem in most programming languages. Memory gets allocated, but is not freed again, leading to a steadily increasing usage of memory. Since the memory you use is finite your application will eventually crash or become so slow it is rendered useless. 105 | 106 | As soon as you still have a reference to an object, array, arrow function, ... you do not use anymore you might have already created a memory leak. Creating an object (incl. arrays and closures) means allocating heap memory that will be freed by the next automatic garbage collection only if all references to this object have vanished. 107 | 108 | 109 | ## API 110 | 111 | ### iterate(syncIterator: Function, options: ?Object): Result 112 | 113 | Test for memory leaks. Will throw an error when a leak is recognized. 114 | 115 | `syncIterator` can be any synchronous function. Let it perform your operations you want to test for memory leaks. 116 | 117 | `options.iterations` is the number the iterator function is run for each heap diff / garbage collection. Defaults to `30`. 118 | 119 | `options.gcollections` is the number of heap snapshots to create. Defaults to `60`. 120 | 121 | ### iterate.async(asyncIterator: Function, options: ?Object): Promise 122 | 123 | Test for memory leaks. Will return a rejecting promise when a leak is recognized. 124 | 125 | `asyncIterator` can be any asynchronous function. Let it perform your operations you want to test for memory leaks. 126 | 127 | `options.iterations` is the number the iterator function is run for each heap diff / garbage collection. Defaults to `30`. 128 | 129 | `options.gcollections` is the number of heap snapshots to create. Defaults to `60`. 130 | 131 | ### Result object 132 | 133 | Properties: 134 | * `heapDiffs` - An array of heap diffs as created by `node-memwatch` 135 | * `iterations` - The number of iterator runs per heap diff 136 | * `gcollections` - The number of garbage collections / heap diffs performed 137 | 138 | Methods: 139 | * `printSummary(title: ?String, log: ?Function)` - Prints a short summary. Can pass a title to print. `log` is the function used to output the summary line by line. Defaults to `console.log`. 140 | 141 | ### MemoryLeakError 142 | 143 | Memory leak errors are instances of this custom error. You can use it to check if an error is really a memory leak error or just a generic kind of problem (like a broken reference). 144 | 145 | Import it as `const { MemoryLeakError } = require('leakage')`. 146 | 147 | 148 | ### CLI Parameters 149 | 150 | You can pass special CLI parameters for `leakage` to your test runner: 151 | 152 | ```sh 153 | mocha test/sample.test.js --heap-file heap-diff.json 154 | ``` 155 | 156 | #### --heap-file 157 | 158 | Will make the library write a detailed heap diff JSON to the file system. Make sure you only run a single test using `it.only`. Otherwise you will only find the heap diff of the last test in the file. Useful for debugging. 159 | 160 | 161 | ## Under the Hood 162 | 163 | Leakage uses `node-memwatch` to trigger the garbage collector and create heap diffs. 164 | 165 | You just specify an iterator function. It will be run 30 times by default then a garbage collection will be performed and a heap snapshot will be made. This process is iterated 6 times by default to collect several heap diffs, since especially in async tests there is always a bit of background noise. 166 | 167 | If the heap size increased over more than `[heapDiffCount * 2 / 3]` subsequent garbage collections an error is thrown. 168 | 169 | 170 | ## Travis CI 171 | 172 | You might want your leakage tests to be run by your CI service. There is an issue with Travis CI's linux containers, `g++` and a transitive dependency of `node-memwatch` ([nan](https://www.npmjs.com/package/nan)). 173 | 174 | Fortunately there is a fix: You need to install and use version `4.8` of `g++` in order to compile the dependency. 175 | 176 | Have a look at leakage's [.travis.yml](./.travis.yml) file to see how it can be done or find further details by @btmills in this [issue](https://github.com/andywer/leakage/issues/4#issuecomment-269449814). 177 | 178 | 179 | ## FAQ 180 | 181 |
182 | I encountered a timeout error 183 | 184 | If you see an error like `Error: Timeout of 2000ms exceeded. (...)` it means that your test took so long that the test runner cancelled it. 185 | 186 | You can easily increase the timeout. Have a look at your test runner's documentation for that. When using Mocha, for instance, you can run it with `--timeout 10000` to increase the timeout to 10000ms (10s). 187 |
188 | 189 |
190 | Why are my tests slow anyway? 191 | 192 | Leakage tests are rather slow compared to usual unit tests, since heap snapshotting and diffing takes some time and has to be done several times per test. 193 | 194 | You can try to reduce the number of heap diffs created, but beware that fewer heap diffs can result in less accurate results. See [API](#api) for details. 195 |
196 | 197 | 198 | ## Contribute 199 | 200 | Got any feedback, suggestions, ...? Feel free to open an [issue](https://github.com/andywer/leakage/issues) and share your thoughts! 201 | 202 | Used it successfully or were unable to use it? Let us know! 203 | 204 | Have an improvement? Open a pull request any time. 205 | 206 | 207 | ## License 208 | 209 | Released under the terms of the MIT license. See [LICENSE](./LICENSE) for details. 210 | -------------------------------------------------------------------------------- /docs/failing-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andywer/leakage/da86e4ace41a5d7e483958c522e1f8a4944ce31f/docs/failing-test.png -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Disclaimer: 3 | * 4 | * The code in this file is quite ugly. Usually in a review I would be very 5 | * unhappy if I saw something like this. 6 | * But it's not this code's job to look pleasant. It's job is to create heap 7 | * diffs while leaving the smallest possible heap footprint itself. To achieve 8 | * that we do a couple of things: 9 | * 10 | * - We create all objects (including functions and arrays) as early as possible 11 | * and only once 12 | * - We create arrays using the `Array` constructor and pass the size we need 13 | * to avoid re-allocations 14 | * - We never assign values of different types (number, object, ...) to a variable 15 | * - We try to avoid promises whereever possible, since they come with a big 16 | * heap footprint 17 | * - We use setImmediate() in the right places to create a new execution context 18 | * to allow garbage-collecting the old execution context's objects 19 | * - We have dedicated heap footprint tests (see `test/heap-footprint.test.js`) 20 | * and we test if changes to this code alter its heap footprint 21 | */ 22 | 23 | const fs = require('fs') 24 | const memwatch = require('@aidemaster/node-memwatch') 25 | const minimist = require('minimist') 26 | const path = require('path') 27 | const { createResult } = require('./result') 28 | const { MemoryLeakError, testConstantHeapSize } = require('./testConstantHeapSize') 29 | 30 | const argv = minimist(process.argv.slice(2)) 31 | let currentlyRunningTests = 0 32 | 33 | module.exports = { 34 | iterate, 35 | MemoryLeakError 36 | } 37 | 38 | function iterate (iteratorFn, options = {}) { 39 | const runAndHeapDiff = () => { 40 | memwatch.gc() 41 | memwatch.gc() 42 | 43 | const heapDiff = new memwatch.HeapDiff() 44 | for (let index = 0; index < iterations; index++) { 45 | const result = iteratorFn() 46 | if (result && typeof result.then === 'function') { 47 | throw new Error(`Tried to use iterate() on an async function. Use iterate.async() instead.`) 48 | } 49 | } 50 | return heapDiff.end() 51 | } 52 | 53 | const { iterations = 30, gcollections = 6 } = options 54 | const heapDiffs = new Array(gcollections) 55 | 56 | for (let gcIndex = 0; gcIndex < gcollections; gcIndex++) { 57 | heapDiffs[ gcIndex ] = runAndHeapDiff() 58 | } 59 | 60 | if (argv['heap-file']) { 61 | saveHeapDiffs(heapDiffs, argv['heap-file']) 62 | } 63 | 64 | const heapError = testConstantHeapSize(heapDiffs, { iterations, gcollections }) 65 | if (heapError) { 66 | throw heapError 67 | } 68 | 69 | return createResult(heapDiffs, { iterations, gcollections }) 70 | } 71 | 72 | iterate.async = function iterateAsync (iteratorFn, options = {}) { 73 | const { iterations = 30, gcollections = 6 } = options 74 | const heapDiffs = new Array(gcollections) 75 | 76 | const runner = { 77 | gcIndex: 0, 78 | error: null, 79 | heapDiff: null, 80 | reject: () => {}, 81 | resolve: () => {}, 82 | 83 | run () { 84 | memwatch.gc() 85 | memwatch.gc() 86 | 87 | let currentIterationsDone = 0 88 | runner.heapDiff = new memwatch.HeapDiff() 89 | 90 | for (let index = 0; index < iterations; index++) { 91 | iteratorFn().then( 92 | () => { 93 | currentIterationsDone++ 94 | if (currentIterationsDone === iterations) { 95 | setImmediate(runner.onHeapDiff) 96 | } 97 | }, 98 | error => { 99 | currentIterationsDone++ 100 | runner.error = error 101 | if (currentIterationsDone === iterations) { 102 | setImmediate(runner.onHeapDiff) 103 | } 104 | } 105 | ) 106 | } 107 | }, 108 | onHeapDiff () { 109 | memwatch.gc() 110 | heapDiffs[ runner.gcIndex ] = runner.heapDiff.end() 111 | runner.gcIndex++ 112 | 113 | if (runner.gcIndex === gcollections) { 114 | runner.onAllDone() 115 | } else { 116 | // If `setImmediate(runner.run)` is used here we will always have leaky diffs! Why?! 117 | runner.run() 118 | } 119 | }, 120 | onAllDone () { 121 | if (argv['heap-file']) { 122 | saveHeapDiffs(heapDiffs, argv['heap-file']) 123 | } 124 | 125 | currentlyRunningTests-- 126 | 127 | if (runner.error) { 128 | runner.reject(runner.error) 129 | } else { 130 | const heapError = testConstantHeapSize(heapDiffs, { iterations, gcollections, sensitivity: 5 * 1024 }) 131 | if (heapError) { 132 | runner.reject(heapError) 133 | } else { 134 | runner.resolve(createResult(heapDiffs, { iterations, gcollections })) 135 | } 136 | } 137 | } 138 | } 139 | 140 | return new Promise((resolve, reject) => { 141 | runner.resolve = resolve 142 | runner.reject = reject 143 | 144 | if (currentlyRunningTests > 0) { 145 | return reject(new Error( 146 | `Detected concurrently running tests. ` + 147 | `This will render the heap snapshots unusable. ` + 148 | `Make sure the tests are run strictly sequentially.` 149 | )) 150 | } 151 | currentlyRunningTests++ 152 | 153 | // Since the first iterator call always inflates the heap a lot, we do a blind first run here 154 | const promise = iteratorFn() 155 | 156 | if (!promise || typeof promise.then !== 'function') { 157 | return reject(new Error(`Tried to use iterate.async() on a synchronous function. Use iterate() instead.`)) 158 | } 159 | 160 | promise.then( 161 | () => setImmediate(runner.run), 162 | error => reject(error) 163 | ) 164 | }) 165 | } 166 | 167 | function saveHeapDiffs (heapDiffs, outFileName) { 168 | const outFilePath = path.resolve(process.cwd(), outFileName) 169 | fs.writeFileSync(outFilePath, JSON.stringify(heapDiffs, null, 2), { encoding: 'utf8' }) 170 | } 171 | -------------------------------------------------------------------------------- /lib/result.js: -------------------------------------------------------------------------------- 1 | const prettyBytes = require('pretty-bytes') 2 | 3 | module.exports = { 4 | createResult 5 | } 6 | 7 | class Result { 8 | constructor (heapDiffs, gcollections, iterations) { 9 | this.heapDiffs = heapDiffs 10 | this.gcollections = gcollections 11 | this.iterations = iterations 12 | } 13 | 14 | printSummary (title, log = console.log) { 15 | const changesInBytes = this.heapDiffs.map(heapDiff => heapDiff.change.size_bytes) 16 | const average = changesInBytes.reduce((sum, change) => sum + change, 0) / changesInBytes.length 17 | const minimum = changesInBytes.reduce((min, change) => change < min ? change : min, Infinity) 18 | const maximum = changesInBytes.reduce((max, change) => change > max ? change : max, -Infinity) 19 | 20 | log(title ? `Leak test summary - ${title}:` : `Leak test summary:`) 21 | log(` Did ${this.gcollections} heap diffs, iterating ${this.iterations} times each.`) 22 | log(` Heap diff summary: ${formatDiffSize(average)} avg, ${formatDiffSize(minimum)} min, ${formatDiffSize(maximum)} max`) 23 | log(` Heap diffs: ${this.heapDiffs.map(heapDiff => formatDiffSize(heapDiff.change.size_bytes))}`) 24 | } 25 | } 26 | 27 | function createResult (heapDiffs, options) { 28 | const { gcollections, iterations } = options 29 | 30 | return new Result(heapDiffs, gcollections, iterations) 31 | } 32 | 33 | function formatDiffSize (size) { 34 | const formattedSize = prettyBytes(size) 35 | return size > 0 ? `+${formattedSize}` : formattedSize 36 | } 37 | -------------------------------------------------------------------------------- /lib/testConstantHeapSize.js: -------------------------------------------------------------------------------- 1 | const ExtendableError = require('es6-error') 2 | const prettyBytes = require('pretty-bytes') 3 | 4 | class MemoryLeakError extends ExtendableError { } 5 | 6 | module.exports = { 7 | MemoryLeakError, 8 | testConstantHeapSize 9 | } 10 | 11 | function testConstantHeapSize (heapDiffs, { iterations, gcollections, sensitivity = 1024 }) { 12 | const subsequentHeapGrowths = getSubsequentHeapGrowths(heapDiffs, sensitivity) 13 | const throwOnSubsequentHeapGrowths = Math.floor(heapDiffs.length * 2 / 3) 14 | 15 | if (subsequentHeapGrowths.length > throwOnSubsequentHeapGrowths) { 16 | const lastHeapDiff = subsequentHeapGrowths[ subsequentHeapGrowths.length - 1 ] 17 | const heapGrowthIterations = Math.round(subsequentHeapGrowths.length * iterations) 18 | 19 | const growthInBytes = subsequentHeapGrowths 20 | .map(heapDiff => heapDiff.change.size_bytes) 21 | .reduce((total, heapGrowth) => (total + heapGrowth), 0) 22 | 23 | return new MemoryLeakError( 24 | `Heap grew on ${subsequentHeapGrowths.length} subsequent garbage collections ` + 25 | `(${formatInteger(heapGrowthIterations)} of ${iterations * gcollections} iterations) ` + 26 | `by ${prettyBytes(growthInBytes)}.\n\n` + 27 | ` Iterations between GCs: ${formatInteger(iterations)}\n\n` + 28 | ` Final GC details:\n` + 29 | ` ${prettyHeapContents(lastHeapDiff).trimLeft()}\n` 30 | ) 31 | } else { 32 | return null 33 | } 34 | } 35 | 36 | function getSubsequentHeapGrowths (heapDiffs, sensitivity) { 37 | const growthSeriesSets = [] 38 | let subsequentGrowths = [] 39 | 40 | heapDiffs.forEach(heapDiff => { 41 | if (heapDiff.change.size_bytes > sensitivity) { 42 | subsequentGrowths.push(heapDiff) 43 | } else { 44 | if (subsequentGrowths.length > 0) { 45 | growthSeriesSets.push(subsequentGrowths) 46 | } 47 | subsequentGrowths = [] 48 | } 49 | }) 50 | 51 | if (subsequentGrowths.length > 0) { 52 | growthSeriesSets.push(subsequentGrowths) 53 | } 54 | 55 | return getLongestItem(growthSeriesSets, []) 56 | } 57 | 58 | function getLongestItem (array, defaultValue) { 59 | return array.reduce((longestItem, currentItem) => ( 60 | currentItem.length > longestItem.length ? currentItem : longestItem 61 | ), defaultValue) 62 | } 63 | 64 | function prettyHeapContents (lastHeapDiff) { 65 | const byGrowth = (a, b) => (a.size_bytes < b.size_bytes ? 1 : -1) 66 | 67 | const formatHeapContent = (item) => ( 68 | `[${prettyBytes(item.size_bytes).padStart(10)}] [+ ${String(item['+']).padStart(3)}x] [- ${String(item['-']).padStart(3)}x] ${item.what}` 69 | ) 70 | 71 | const sortedDetails = [].concat(lastHeapDiff.change.details).sort(byGrowth) 72 | const formattedHeapContents = sortedDetails.map((heapContentItem) => formatHeapContent(heapContentItem)) 73 | 74 | const heapContentLines = formattedHeapContents.length > 4 75 | ? formattedHeapContents.slice(0, 4).concat(`... (${formattedHeapContents.length - 4} more)`) 76 | : formattedHeapContents 77 | 78 | return heapContentLines 79 | .map((line) => ` ${line}`) 80 | .join('\n') 81 | } 82 | 83 | function formatInteger (value) { 84 | return Math.round(value) !== value ? '~' + Math.round(value) : value 85 | } 86 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leakage", 3 | "version": "0.5.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@aidemaster/node-memwatch": { 8 | "version": "1.0.5", 9 | "resolved": "https://registry.npmjs.org/@aidemaster/node-memwatch/-/node-memwatch-1.0.5.tgz", 10 | "integrity": "sha512-S4M2lc0EmlCwgchzKNO53r4vXsDE/FmF/t7ecvpEmvN/AhCHjhqsGQT/0URpkYMjIucVgJZsHRW2xpyj5RHeMw==", 11 | "requires": { 12 | "bindings": "^1.3.0", 13 | "nan": "^2.9.2" 14 | } 15 | }, 16 | "acorn": { 17 | "version": "5.6.1", 18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.1.tgz", 19 | "integrity": "sha512-XH4o5BK5jmw9PzSGK7mNf+/xV+mPxQxGZoeC36OVsJZYV77JAG9NnI7T90hoUpI/C1TOfXWTvugRdZ9ZR3iE2Q==", 20 | "dev": true 21 | }, 22 | "acorn-jsx": { 23 | "version": "3.0.1", 24 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 25 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 26 | "dev": true, 27 | "requires": { 28 | "acorn": "^3.0.4" 29 | }, 30 | "dependencies": { 31 | "acorn": { 32 | "version": "3.3.0", 33 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 34 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", 35 | "dev": true 36 | } 37 | } 38 | }, 39 | "ajv": { 40 | "version": "5.5.2", 41 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 42 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 43 | "dev": true, 44 | "requires": { 45 | "co": "^4.6.0", 46 | "fast-deep-equal": "^1.0.0", 47 | "fast-json-stable-stringify": "^2.0.0", 48 | "json-schema-traverse": "^0.3.0" 49 | } 50 | }, 51 | "ajv-keywords": { 52 | "version": "2.1.1", 53 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 54 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", 55 | "dev": true 56 | }, 57 | "ansi-escapes": { 58 | "version": "3.1.0", 59 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", 60 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", 61 | "dev": true 62 | }, 63 | "ansi-regex": { 64 | "version": "2.1.1", 65 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 66 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 67 | "dev": true 68 | }, 69 | "ansi-styles": { 70 | "version": "2.2.1", 71 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 72 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 73 | "dev": true 74 | }, 75 | "argparse": { 76 | "version": "1.0.10", 77 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 78 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 79 | "dev": true, 80 | "requires": { 81 | "sprintf-js": "~1.0.2" 82 | } 83 | }, 84 | "array-includes": { 85 | "version": "3.0.3", 86 | "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", 87 | "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", 88 | "dev": true, 89 | "requires": { 90 | "define-properties": "^1.1.2", 91 | "es-abstract": "^1.7.0" 92 | } 93 | }, 94 | "array-union": { 95 | "version": "1.0.2", 96 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 97 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 98 | "dev": true, 99 | "requires": { 100 | "array-uniq": "^1.0.1" 101 | } 102 | }, 103 | "array-uniq": { 104 | "version": "1.0.3", 105 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 106 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 107 | "dev": true 108 | }, 109 | "arrify": { 110 | "version": "1.0.1", 111 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 112 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", 113 | "dev": true 114 | }, 115 | "asap": { 116 | "version": "2.0.6", 117 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 118 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", 119 | "dev": true 120 | }, 121 | "assertion-error": { 122 | "version": "1.0.2", 123 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", 124 | "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", 125 | "dev": true 126 | }, 127 | "babel-code-frame": { 128 | "version": "6.26.0", 129 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 130 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 131 | "dev": true, 132 | "requires": { 133 | "chalk": "^1.1.3", 134 | "esutils": "^2.0.2", 135 | "js-tokens": "^3.0.2" 136 | }, 137 | "dependencies": { 138 | "chalk": { 139 | "version": "1.1.3", 140 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 141 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 142 | "dev": true, 143 | "requires": { 144 | "ansi-styles": "^2.2.1", 145 | "escape-string-regexp": "^1.0.2", 146 | "has-ansi": "^2.0.0", 147 | "strip-ansi": "^3.0.0", 148 | "supports-color": "^2.0.0" 149 | } 150 | }, 151 | "strip-ansi": { 152 | "version": "3.0.1", 153 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 154 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 155 | "dev": true, 156 | "requires": { 157 | "ansi-regex": "^2.0.0" 158 | } 159 | }, 160 | "supports-color": { 161 | "version": "2.0.0", 162 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 163 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 164 | "dev": true 165 | } 166 | } 167 | }, 168 | "balanced-match": { 169 | "version": "0.4.2", 170 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", 171 | "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", 172 | "dev": true 173 | }, 174 | "bindings": { 175 | "version": "1.3.0", 176 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 177 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" 178 | }, 179 | "brace-expansion": { 180 | "version": "1.1.7", 181 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", 182 | "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", 183 | "dev": true, 184 | "requires": { 185 | "balanced-match": "^0.4.1", 186 | "concat-map": "0.0.1" 187 | } 188 | }, 189 | "browser-stdout": { 190 | "version": "1.3.1", 191 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 192 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 193 | "dev": true 194 | }, 195 | "buffer-from": { 196 | "version": "1.1.0", 197 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", 198 | "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", 199 | "dev": true 200 | }, 201 | "builtin-modules": { 202 | "version": "1.1.1", 203 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 204 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 205 | "dev": true 206 | }, 207 | "caller-path": { 208 | "version": "0.1.0", 209 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 210 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 211 | "dev": true, 212 | "requires": { 213 | "callsites": "^0.2.0" 214 | } 215 | }, 216 | "callsites": { 217 | "version": "0.2.0", 218 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 219 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", 220 | "dev": true 221 | }, 222 | "chai": { 223 | "version": "3.5.0", 224 | "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", 225 | "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", 226 | "dev": true, 227 | "requires": { 228 | "assertion-error": "^1.0.1", 229 | "deep-eql": "^0.1.3", 230 | "type-detect": "^1.0.0" 231 | } 232 | }, 233 | "chai-as-promised": { 234 | "version": "6.0.0", 235 | "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-6.0.0.tgz", 236 | "integrity": "sha1-GgKkM6byTa+sY7nJb6FoTbGqjaY=", 237 | "dev": true, 238 | "requires": { 239 | "check-error": "^1.0.2" 240 | } 241 | }, 242 | "chalk": { 243 | "version": "2.4.1", 244 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 245 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 246 | "dev": true, 247 | "requires": { 248 | "ansi-styles": "^3.2.1", 249 | "escape-string-regexp": "^1.0.5", 250 | "supports-color": "^5.3.0" 251 | }, 252 | "dependencies": { 253 | "ansi-styles": { 254 | "version": "3.2.1", 255 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 256 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 257 | "dev": true, 258 | "requires": { 259 | "color-convert": "^1.9.0" 260 | } 261 | }, 262 | "has-flag": { 263 | "version": "3.0.0", 264 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 265 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 266 | "dev": true 267 | }, 268 | "supports-color": { 269 | "version": "5.4.0", 270 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 271 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 272 | "dev": true, 273 | "requires": { 274 | "has-flag": "^3.0.0" 275 | } 276 | } 277 | } 278 | }, 279 | "chardet": { 280 | "version": "0.4.2", 281 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 282 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", 283 | "dev": true 284 | }, 285 | "check-error": { 286 | "version": "1.0.2", 287 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 288 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 289 | "dev": true 290 | }, 291 | "circular-json": { 292 | "version": "0.3.3", 293 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 294 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 295 | "dev": true 296 | }, 297 | "cli-cursor": { 298 | "version": "2.1.0", 299 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 300 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 301 | "dev": true, 302 | "requires": { 303 | "restore-cursor": "^2.0.0" 304 | } 305 | }, 306 | "cli-width": { 307 | "version": "2.2.0", 308 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 309 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 310 | "dev": true 311 | }, 312 | "co": { 313 | "version": "4.6.0", 314 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 315 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 316 | "dev": true 317 | }, 318 | "color-convert": { 319 | "version": "1.9.1", 320 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 321 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 322 | "dev": true, 323 | "requires": { 324 | "color-name": "^1.1.1" 325 | } 326 | }, 327 | "color-name": { 328 | "version": "1.1.3", 329 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 330 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 331 | "dev": true 332 | }, 333 | "commander": { 334 | "version": "2.15.1", 335 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 336 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 337 | "dev": true 338 | }, 339 | "concat-map": { 340 | "version": "0.0.1", 341 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 342 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 343 | "dev": true 344 | }, 345 | "concat-stream": { 346 | "version": "1.6.2", 347 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 348 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 349 | "dev": true, 350 | "requires": { 351 | "buffer-from": "^1.0.0", 352 | "inherits": "^2.0.3", 353 | "readable-stream": "^2.2.2", 354 | "typedarray": "^0.0.6" 355 | } 356 | }, 357 | "contains-path": { 358 | "version": "0.1.0", 359 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", 360 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", 361 | "dev": true 362 | }, 363 | "core-js": { 364 | "version": "1.2.7", 365 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", 366 | "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", 367 | "dev": true 368 | }, 369 | "core-util-is": { 370 | "version": "1.0.2", 371 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 372 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 373 | "dev": true 374 | }, 375 | "cross-spawn": { 376 | "version": "5.1.0", 377 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 378 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 379 | "dev": true, 380 | "requires": { 381 | "lru-cache": "^4.0.1", 382 | "shebang-command": "^1.2.0", 383 | "which": "^1.2.9" 384 | } 385 | }, 386 | "debug": { 387 | "version": "3.1.0", 388 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 389 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 390 | "dev": true, 391 | "requires": { 392 | "ms": "2.0.0" 393 | } 394 | }, 395 | "debug-log": { 396 | "version": "1.0.1", 397 | "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", 398 | "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", 399 | "dev": true 400 | }, 401 | "deep-eql": { 402 | "version": "0.1.3", 403 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", 404 | "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", 405 | "dev": true, 406 | "requires": { 407 | "type-detect": "0.1.1" 408 | }, 409 | "dependencies": { 410 | "type-detect": { 411 | "version": "0.1.1", 412 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", 413 | "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", 414 | "dev": true 415 | } 416 | } 417 | }, 418 | "deep-is": { 419 | "version": "0.1.3", 420 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 421 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 422 | "dev": true 423 | }, 424 | "define-properties": { 425 | "version": "1.1.2", 426 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 427 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 428 | "dev": true, 429 | "requires": { 430 | "foreach": "^2.0.5", 431 | "object-keys": "^1.0.8" 432 | } 433 | }, 434 | "deglob": { 435 | "version": "2.1.0", 436 | "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz", 437 | "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=", 438 | "dev": true, 439 | "requires": { 440 | "find-root": "^1.0.0", 441 | "glob": "^7.0.5", 442 | "ignore": "^3.0.9", 443 | "pkg-config": "^1.1.0", 444 | "run-parallel": "^1.1.2", 445 | "uniq": "^1.0.1" 446 | } 447 | }, 448 | "del": { 449 | "version": "2.2.2", 450 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", 451 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", 452 | "dev": true, 453 | "requires": { 454 | "globby": "^5.0.0", 455 | "is-path-cwd": "^1.0.0", 456 | "is-path-in-cwd": "^1.0.0", 457 | "object-assign": "^4.0.1", 458 | "pify": "^2.0.0", 459 | "pinkie-promise": "^2.0.0", 460 | "rimraf": "^2.2.8" 461 | } 462 | }, 463 | "diff": { 464 | "version": "3.5.0", 465 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 466 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 467 | "dev": true 468 | }, 469 | "doctrine": { 470 | "version": "2.1.0", 471 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 472 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 473 | "dev": true, 474 | "requires": { 475 | "esutils": "^2.0.2" 476 | } 477 | }, 478 | "encoding": { 479 | "version": "0.1.12", 480 | "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", 481 | "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", 482 | "dev": true, 483 | "requires": { 484 | "iconv-lite": "~0.4.13" 485 | } 486 | }, 487 | "error-ex": { 488 | "version": "1.3.1", 489 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 490 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 491 | "dev": true, 492 | "requires": { 493 | "is-arrayish": "^0.2.1" 494 | } 495 | }, 496 | "es-abstract": { 497 | "version": "1.12.0", 498 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", 499 | "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", 500 | "dev": true, 501 | "requires": { 502 | "es-to-primitive": "^1.1.1", 503 | "function-bind": "^1.1.1", 504 | "has": "^1.0.1", 505 | "is-callable": "^1.1.3", 506 | "is-regex": "^1.0.4" 507 | } 508 | }, 509 | "es-to-primitive": { 510 | "version": "1.1.1", 511 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", 512 | "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", 513 | "dev": true, 514 | "requires": { 515 | "is-callable": "^1.1.1", 516 | "is-date-object": "^1.0.1", 517 | "is-symbol": "^1.0.1" 518 | } 519 | }, 520 | "es6-error": { 521 | "version": "4.0.2", 522 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.0.2.tgz", 523 | "integrity": "sha1-7sXHJurO9Rt/a3PCDbbhsTsGnJg=" 524 | }, 525 | "escape-string-regexp": { 526 | "version": "1.0.5", 527 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 528 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 529 | "dev": true 530 | }, 531 | "eslint": { 532 | "version": "4.18.2", 533 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", 534 | "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", 535 | "dev": true, 536 | "requires": { 537 | "ajv": "^5.3.0", 538 | "babel-code-frame": "^6.22.0", 539 | "chalk": "^2.1.0", 540 | "concat-stream": "^1.6.0", 541 | "cross-spawn": "^5.1.0", 542 | "debug": "^3.1.0", 543 | "doctrine": "^2.1.0", 544 | "eslint-scope": "^3.7.1", 545 | "eslint-visitor-keys": "^1.0.0", 546 | "espree": "^3.5.2", 547 | "esquery": "^1.0.0", 548 | "esutils": "^2.0.2", 549 | "file-entry-cache": "^2.0.0", 550 | "functional-red-black-tree": "^1.0.1", 551 | "glob": "^7.1.2", 552 | "globals": "^11.0.1", 553 | "ignore": "^3.3.3", 554 | "imurmurhash": "^0.1.4", 555 | "inquirer": "^3.0.6", 556 | "is-resolvable": "^1.0.0", 557 | "js-yaml": "^3.9.1", 558 | "json-stable-stringify-without-jsonify": "^1.0.1", 559 | "levn": "^0.3.0", 560 | "lodash": "^4.17.4", 561 | "minimatch": "^3.0.2", 562 | "mkdirp": "^0.5.1", 563 | "natural-compare": "^1.4.0", 564 | "optionator": "^0.8.2", 565 | "path-is-inside": "^1.0.2", 566 | "pluralize": "^7.0.0", 567 | "progress": "^2.0.0", 568 | "require-uncached": "^1.0.3", 569 | "semver": "^5.3.0", 570 | "strip-ansi": "^4.0.0", 571 | "strip-json-comments": "~2.0.1", 572 | "table": "4.0.2", 573 | "text-table": "~0.2.0" 574 | }, 575 | "dependencies": { 576 | "debug": { 577 | "version": "3.1.0", 578 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 579 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 580 | "dev": true, 581 | "requires": { 582 | "ms": "2.0.0" 583 | } 584 | }, 585 | "glob": { 586 | "version": "7.1.2", 587 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 588 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 589 | "dev": true, 590 | "requires": { 591 | "fs.realpath": "^1.0.0", 592 | "inflight": "^1.0.4", 593 | "inherits": "2", 594 | "minimatch": "^3.0.4", 595 | "once": "^1.3.0", 596 | "path-is-absolute": "^1.0.0" 597 | } 598 | }, 599 | "ms": { 600 | "version": "2.0.0", 601 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 602 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 603 | "dev": true 604 | } 605 | } 606 | }, 607 | "eslint-config-standard": { 608 | "version": "11.0.0", 609 | "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", 610 | "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", 611 | "dev": true 612 | }, 613 | "eslint-config-standard-jsx": { 614 | "version": "5.0.0", 615 | "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-5.0.0.tgz", 616 | "integrity": "sha512-rLToPAEqLMPBfWnYTu6xRhm2OWziS2n40QFqJ8jAM8NSVzeVKTa3nclhsU4DpPJQRY60F34Oo1wi/71PN/eITg==", 617 | "dev": true 618 | }, 619 | "eslint-import-resolver-node": { 620 | "version": "0.3.2", 621 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", 622 | "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", 623 | "dev": true, 624 | "requires": { 625 | "debug": "^2.6.9", 626 | "resolve": "^1.5.0" 627 | }, 628 | "dependencies": { 629 | "debug": { 630 | "version": "2.6.9", 631 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 632 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 633 | "dev": true, 634 | "requires": { 635 | "ms": "2.0.0" 636 | } 637 | }, 638 | "ms": { 639 | "version": "2.0.0", 640 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 641 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 642 | "dev": true 643 | } 644 | } 645 | }, 646 | "eslint-module-utils": { 647 | "version": "2.2.0", 648 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", 649 | "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", 650 | "dev": true, 651 | "requires": { 652 | "debug": "^2.6.8", 653 | "pkg-dir": "^1.0.0" 654 | }, 655 | "dependencies": { 656 | "debug": { 657 | "version": "2.6.9", 658 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 659 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 660 | "dev": true, 661 | "requires": { 662 | "ms": "2.0.0" 663 | } 664 | }, 665 | "ms": { 666 | "version": "2.0.0", 667 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 668 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 669 | "dev": true 670 | } 671 | } 672 | }, 673 | "eslint-plugin-import": { 674 | "version": "2.9.0", 675 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz", 676 | "integrity": "sha1-JgAu+/ylmJtyiKwEdQi9JPIXsWk=", 677 | "dev": true, 678 | "requires": { 679 | "builtin-modules": "^1.1.1", 680 | "contains-path": "^0.1.0", 681 | "debug": "^2.6.8", 682 | "doctrine": "1.5.0", 683 | "eslint-import-resolver-node": "^0.3.1", 684 | "eslint-module-utils": "^2.1.1", 685 | "has": "^1.0.1", 686 | "lodash": "^4.17.4", 687 | "minimatch": "^3.0.3", 688 | "read-pkg-up": "^2.0.0" 689 | }, 690 | "dependencies": { 691 | "debug": { 692 | "version": "2.6.9", 693 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 694 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 695 | "dev": true, 696 | "requires": { 697 | "ms": "2.0.0" 698 | } 699 | }, 700 | "doctrine": { 701 | "version": "1.5.0", 702 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", 703 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", 704 | "dev": true, 705 | "requires": { 706 | "esutils": "^2.0.2", 707 | "isarray": "^1.0.0" 708 | } 709 | }, 710 | "ms": { 711 | "version": "2.0.0", 712 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 713 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 714 | "dev": true 715 | } 716 | } 717 | }, 718 | "eslint-plugin-node": { 719 | "version": "6.0.1", 720 | "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", 721 | "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", 722 | "dev": true, 723 | "requires": { 724 | "ignore": "^3.3.6", 725 | "minimatch": "^3.0.4", 726 | "resolve": "^1.3.3", 727 | "semver": "^5.4.1" 728 | } 729 | }, 730 | "eslint-plugin-promise": { 731 | "version": "3.7.0", 732 | "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz", 733 | "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==", 734 | "dev": true 735 | }, 736 | "eslint-plugin-react": { 737 | "version": "7.7.0", 738 | "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz", 739 | "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==", 740 | "dev": true, 741 | "requires": { 742 | "doctrine": "^2.0.2", 743 | "has": "^1.0.1", 744 | "jsx-ast-utils": "^2.0.1", 745 | "prop-types": "^15.6.0" 746 | } 747 | }, 748 | "eslint-plugin-standard": { 749 | "version": "3.0.1", 750 | "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", 751 | "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", 752 | "dev": true 753 | }, 754 | "eslint-scope": { 755 | "version": "3.7.1", 756 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", 757 | "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", 758 | "dev": true, 759 | "requires": { 760 | "esrecurse": "^4.1.0", 761 | "estraverse": "^4.1.1" 762 | } 763 | }, 764 | "eslint-visitor-keys": { 765 | "version": "1.0.0", 766 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 767 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", 768 | "dev": true 769 | }, 770 | "espree": { 771 | "version": "3.5.4", 772 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 773 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 774 | "dev": true, 775 | "requires": { 776 | "acorn": "^5.5.0", 777 | "acorn-jsx": "^3.0.0" 778 | } 779 | }, 780 | "esprima": { 781 | "version": "4.0.1", 782 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 783 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 784 | "dev": true 785 | }, 786 | "esquery": { 787 | "version": "1.0.1", 788 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 789 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 790 | "dev": true, 791 | "requires": { 792 | "estraverse": "^4.0.0" 793 | } 794 | }, 795 | "esrecurse": { 796 | "version": "4.2.1", 797 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 798 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 799 | "dev": true, 800 | "requires": { 801 | "estraverse": "^4.1.0" 802 | } 803 | }, 804 | "estraverse": { 805 | "version": "4.2.0", 806 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 807 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 808 | "dev": true 809 | }, 810 | "esutils": { 811 | "version": "2.0.2", 812 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 813 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 814 | "dev": true 815 | }, 816 | "external-editor": { 817 | "version": "2.2.0", 818 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 819 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 820 | "dev": true, 821 | "requires": { 822 | "chardet": "^0.4.0", 823 | "iconv-lite": "^0.4.17", 824 | "tmp": "^0.0.33" 825 | } 826 | }, 827 | "fast-deep-equal": { 828 | "version": "1.1.0", 829 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 830 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 831 | "dev": true 832 | }, 833 | "fast-json-stable-stringify": { 834 | "version": "2.0.0", 835 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 836 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 837 | "dev": true 838 | }, 839 | "fast-levenshtein": { 840 | "version": "2.0.6", 841 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 842 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 843 | "dev": true 844 | }, 845 | "fbjs": { 846 | "version": "0.8.16", 847 | "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", 848 | "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", 849 | "dev": true, 850 | "requires": { 851 | "core-js": "^1.0.0", 852 | "isomorphic-fetch": "^2.1.1", 853 | "loose-envify": "^1.0.0", 854 | "object-assign": "^4.1.0", 855 | "promise": "^7.1.1", 856 | "setimmediate": "^1.0.5", 857 | "ua-parser-js": "^0.7.9" 858 | } 859 | }, 860 | "figures": { 861 | "version": "2.0.0", 862 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 863 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 864 | "dev": true, 865 | "requires": { 866 | "escape-string-regexp": "^1.0.5" 867 | } 868 | }, 869 | "file-entry-cache": { 870 | "version": "2.0.0", 871 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 872 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 873 | "dev": true, 874 | "requires": { 875 | "flat-cache": "^1.2.1", 876 | "object-assign": "^4.0.1" 877 | } 878 | }, 879 | "find-root": { 880 | "version": "1.1.0", 881 | "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", 882 | "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", 883 | "dev": true 884 | }, 885 | "find-up": { 886 | "version": "1.1.2", 887 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 888 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 889 | "dev": true, 890 | "requires": { 891 | "path-exists": "^2.0.0", 892 | "pinkie-promise": "^2.0.0" 893 | } 894 | }, 895 | "flat-cache": { 896 | "version": "1.3.0", 897 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", 898 | "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", 899 | "dev": true, 900 | "requires": { 901 | "circular-json": "^0.3.1", 902 | "del": "^2.0.2", 903 | "graceful-fs": "^4.1.2", 904 | "write": "^0.2.1" 905 | } 906 | }, 907 | "foreach": { 908 | "version": "2.0.5", 909 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 910 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", 911 | "dev": true 912 | }, 913 | "fs.realpath": { 914 | "version": "1.0.0", 915 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 916 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 917 | "dev": true 918 | }, 919 | "function-bind": { 920 | "version": "1.1.1", 921 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 922 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 923 | "dev": true 924 | }, 925 | "functional-red-black-tree": { 926 | "version": "1.0.1", 927 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 928 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 929 | "dev": true 930 | }, 931 | "get-stdin": { 932 | "version": "6.0.0", 933 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", 934 | "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", 935 | "dev": true 936 | }, 937 | "glob": { 938 | "version": "7.1.1", 939 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", 940 | "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", 941 | "dev": true, 942 | "requires": { 943 | "fs.realpath": "^1.0.0", 944 | "inflight": "^1.0.4", 945 | "inherits": "2", 946 | "minimatch": "^3.0.2", 947 | "once": "^1.3.0", 948 | "path-is-absolute": "^1.0.0" 949 | } 950 | }, 951 | "globals": { 952 | "version": "11.5.0", 953 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", 954 | "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", 955 | "dev": true 956 | }, 957 | "globby": { 958 | "version": "5.0.0", 959 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", 960 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", 961 | "dev": true, 962 | "requires": { 963 | "array-union": "^1.0.1", 964 | "arrify": "^1.0.0", 965 | "glob": "^7.0.3", 966 | "object-assign": "^4.0.1", 967 | "pify": "^2.0.0", 968 | "pinkie-promise": "^2.0.0" 969 | } 970 | }, 971 | "graceful-fs": { 972 | "version": "4.1.11", 973 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 974 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 975 | "dev": true 976 | }, 977 | "growl": { 978 | "version": "1.10.5", 979 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 980 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 981 | "dev": true 982 | }, 983 | "has": { 984 | "version": "1.0.2", 985 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.2.tgz", 986 | "integrity": "sha512-D5/WxwX+SrGfs/fiQn34RAoIZkCLJBDEfBWS1kmTI6G/1mtjhxTBiIiJi8EsKhwaQqKqj7lpKOi3i69tg3P+OQ==", 987 | "dev": true, 988 | "requires": { 989 | "function-bind": "^1.1.1" 990 | } 991 | }, 992 | "has-ansi": { 993 | "version": "2.0.0", 994 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 995 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 996 | "dev": true, 997 | "requires": { 998 | "ansi-regex": "^2.0.0" 999 | } 1000 | }, 1001 | "has-flag": { 1002 | "version": "3.0.0", 1003 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1004 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1005 | "dev": true 1006 | }, 1007 | "he": { 1008 | "version": "1.1.1", 1009 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 1010 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 1011 | "dev": true 1012 | }, 1013 | "hosted-git-info": { 1014 | "version": "2.8.9", 1015 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", 1016 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", 1017 | "dev": true 1018 | }, 1019 | "iconv-lite": { 1020 | "version": "0.4.23", 1021 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 1022 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 1023 | "dev": true, 1024 | "requires": { 1025 | "safer-buffer": ">= 2.1.2 < 3" 1026 | } 1027 | }, 1028 | "ignore": { 1029 | "version": "3.3.8", 1030 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", 1031 | "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", 1032 | "dev": true 1033 | }, 1034 | "imurmurhash": { 1035 | "version": "0.1.4", 1036 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1037 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1038 | "dev": true 1039 | }, 1040 | "inflight": { 1041 | "version": "1.0.6", 1042 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1043 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1044 | "dev": true, 1045 | "requires": { 1046 | "once": "^1.3.0", 1047 | "wrappy": "1" 1048 | } 1049 | }, 1050 | "inherits": { 1051 | "version": "2.0.3", 1052 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1053 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 1054 | "dev": true 1055 | }, 1056 | "inquirer": { 1057 | "version": "3.3.0", 1058 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 1059 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 1060 | "dev": true, 1061 | "requires": { 1062 | "ansi-escapes": "^3.0.0", 1063 | "chalk": "^2.0.0", 1064 | "cli-cursor": "^2.1.0", 1065 | "cli-width": "^2.0.0", 1066 | "external-editor": "^2.0.4", 1067 | "figures": "^2.0.0", 1068 | "lodash": "^4.3.0", 1069 | "mute-stream": "0.0.7", 1070 | "run-async": "^2.2.0", 1071 | "rx-lite": "^4.0.8", 1072 | "rx-lite-aggregates": "^4.0.8", 1073 | "string-width": "^2.1.0", 1074 | "strip-ansi": "^4.0.0", 1075 | "through": "^2.3.6" 1076 | } 1077 | }, 1078 | "is-arrayish": { 1079 | "version": "0.2.1", 1080 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1081 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 1082 | "dev": true 1083 | }, 1084 | "is-builtin-module": { 1085 | "version": "1.0.0", 1086 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 1087 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 1088 | "dev": true, 1089 | "requires": { 1090 | "builtin-modules": "^1.0.0" 1091 | } 1092 | }, 1093 | "is-callable": { 1094 | "version": "1.1.3", 1095 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", 1096 | "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", 1097 | "dev": true 1098 | }, 1099 | "is-date-object": { 1100 | "version": "1.0.1", 1101 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 1102 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 1103 | "dev": true 1104 | }, 1105 | "is-fullwidth-code-point": { 1106 | "version": "2.0.0", 1107 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1108 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1109 | "dev": true 1110 | }, 1111 | "is-path-cwd": { 1112 | "version": "1.0.0", 1113 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", 1114 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", 1115 | "dev": true 1116 | }, 1117 | "is-path-in-cwd": { 1118 | "version": "1.0.1", 1119 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", 1120 | "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", 1121 | "dev": true, 1122 | "requires": { 1123 | "is-path-inside": "^1.0.0" 1124 | } 1125 | }, 1126 | "is-path-inside": { 1127 | "version": "1.0.1", 1128 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", 1129 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", 1130 | "dev": true, 1131 | "requires": { 1132 | "path-is-inside": "^1.0.1" 1133 | } 1134 | }, 1135 | "is-promise": { 1136 | "version": "2.1.0", 1137 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 1138 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 1139 | "dev": true 1140 | }, 1141 | "is-regex": { 1142 | "version": "1.0.4", 1143 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 1144 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 1145 | "dev": true, 1146 | "requires": { 1147 | "has": "^1.0.1" 1148 | } 1149 | }, 1150 | "is-resolvable": { 1151 | "version": "1.1.0", 1152 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 1153 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", 1154 | "dev": true 1155 | }, 1156 | "is-stream": { 1157 | "version": "1.1.0", 1158 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1159 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 1160 | "dev": true 1161 | }, 1162 | "is-symbol": { 1163 | "version": "1.0.1", 1164 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", 1165 | "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", 1166 | "dev": true 1167 | }, 1168 | "isarray": { 1169 | "version": "1.0.0", 1170 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1171 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 1172 | "dev": true 1173 | }, 1174 | "isexe": { 1175 | "version": "2.0.0", 1176 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1177 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1178 | "dev": true 1179 | }, 1180 | "isomorphic-fetch": { 1181 | "version": "2.2.1", 1182 | "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", 1183 | "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", 1184 | "dev": true, 1185 | "requires": { 1186 | "node-fetch": "^1.0.1", 1187 | "whatwg-fetch": ">=0.10.0" 1188 | } 1189 | }, 1190 | "js-tokens": { 1191 | "version": "3.0.2", 1192 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1193 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 1194 | "dev": true 1195 | }, 1196 | "js-yaml": { 1197 | "version": "3.13.1", 1198 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1199 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1200 | "dev": true, 1201 | "requires": { 1202 | "argparse": "^1.0.7", 1203 | "esprima": "^4.0.0" 1204 | } 1205 | }, 1206 | "json-parse-better-errors": { 1207 | "version": "1.0.2", 1208 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 1209 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", 1210 | "dev": true 1211 | }, 1212 | "json-schema-traverse": { 1213 | "version": "0.3.1", 1214 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1215 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 1216 | "dev": true 1217 | }, 1218 | "json-stable-stringify-without-jsonify": { 1219 | "version": "1.0.1", 1220 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1221 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1222 | "dev": true 1223 | }, 1224 | "jsx-ast-utils": { 1225 | "version": "2.0.1", 1226 | "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", 1227 | "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", 1228 | "dev": true, 1229 | "requires": { 1230 | "array-includes": "^3.0.3" 1231 | } 1232 | }, 1233 | "levn": { 1234 | "version": "0.3.0", 1235 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1236 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1237 | "dev": true, 1238 | "requires": { 1239 | "prelude-ls": "~1.1.2", 1240 | "type-check": "~0.3.2" 1241 | } 1242 | }, 1243 | "load-json-file": { 1244 | "version": "2.0.0", 1245 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 1246 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 1247 | "dev": true, 1248 | "requires": { 1249 | "graceful-fs": "^4.1.2", 1250 | "parse-json": "^2.2.0", 1251 | "pify": "^2.0.0", 1252 | "strip-bom": "^3.0.0" 1253 | } 1254 | }, 1255 | "locate-path": { 1256 | "version": "2.0.0", 1257 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 1258 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 1259 | "dev": true, 1260 | "requires": { 1261 | "p-locate": "^2.0.0", 1262 | "path-exists": "^3.0.0" 1263 | }, 1264 | "dependencies": { 1265 | "path-exists": { 1266 | "version": "3.0.0", 1267 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1268 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1269 | "dev": true 1270 | } 1271 | } 1272 | }, 1273 | "lodash": { 1274 | "version": "4.17.21", 1275 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1276 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1277 | "dev": true 1278 | }, 1279 | "loose-envify": { 1280 | "version": "1.3.1", 1281 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 1282 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 1283 | "dev": true, 1284 | "requires": { 1285 | "js-tokens": "^3.0.0" 1286 | } 1287 | }, 1288 | "lru-cache": { 1289 | "version": "4.1.3", 1290 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 1291 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 1292 | "dev": true, 1293 | "requires": { 1294 | "pseudomap": "^1.0.2", 1295 | "yallist": "^2.1.2" 1296 | } 1297 | }, 1298 | "mimic-fn": { 1299 | "version": "1.2.0", 1300 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 1301 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 1302 | "dev": true 1303 | }, 1304 | "minimatch": { 1305 | "version": "3.0.4", 1306 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1307 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1308 | "dev": true, 1309 | "requires": { 1310 | "brace-expansion": "^1.1.7" 1311 | } 1312 | }, 1313 | "minimist": { 1314 | "version": "1.2.6", 1315 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 1316 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" 1317 | }, 1318 | "mkdirp": { 1319 | "version": "0.5.1", 1320 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1321 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1322 | "dev": true, 1323 | "requires": { 1324 | "minimist": "0.0.8" 1325 | }, 1326 | "dependencies": { 1327 | "minimist": { 1328 | "version": "0.0.8", 1329 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1330 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1331 | "dev": true 1332 | } 1333 | } 1334 | }, 1335 | "mocha": { 1336 | "version": "5.2.0", 1337 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 1338 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 1339 | "dev": true, 1340 | "requires": { 1341 | "browser-stdout": "1.3.1", 1342 | "commander": "2.15.1", 1343 | "debug": "3.1.0", 1344 | "diff": "3.5.0", 1345 | "escape-string-regexp": "1.0.5", 1346 | "glob": "7.1.2", 1347 | "growl": "1.10.5", 1348 | "he": "1.1.1", 1349 | "minimatch": "3.0.4", 1350 | "mkdirp": "0.5.1", 1351 | "supports-color": "5.4.0" 1352 | }, 1353 | "dependencies": { 1354 | "glob": { 1355 | "version": "7.1.2", 1356 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 1357 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1358 | "dev": true, 1359 | "requires": { 1360 | "fs.realpath": "^1.0.0", 1361 | "inflight": "^1.0.4", 1362 | "inherits": "2", 1363 | "minimatch": "^3.0.4", 1364 | "once": "^1.3.0", 1365 | "path-is-absolute": "^1.0.0" 1366 | } 1367 | } 1368 | } 1369 | }, 1370 | "ms": { 1371 | "version": "2.0.0", 1372 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1373 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1374 | "dev": true 1375 | }, 1376 | "mute-stream": { 1377 | "version": "0.0.7", 1378 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1379 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 1380 | "dev": true 1381 | }, 1382 | "nan": { 1383 | "version": "2.10.0", 1384 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 1385 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" 1386 | }, 1387 | "natural-compare": { 1388 | "version": "1.4.0", 1389 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1390 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1391 | "dev": true 1392 | }, 1393 | "node-fetch": { 1394 | "version": "1.7.3", 1395 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", 1396 | "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", 1397 | "dev": true, 1398 | "requires": { 1399 | "encoding": "^0.1.11", 1400 | "is-stream": "^1.0.1" 1401 | } 1402 | }, 1403 | "normalize-package-data": { 1404 | "version": "2.4.0", 1405 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1406 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1407 | "dev": true, 1408 | "requires": { 1409 | "hosted-git-info": "^2.1.4", 1410 | "is-builtin-module": "^1.0.0", 1411 | "semver": "2 || 3 || 4 || 5", 1412 | "validate-npm-package-license": "^3.0.1" 1413 | } 1414 | }, 1415 | "object-assign": { 1416 | "version": "4.1.1", 1417 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1418 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1419 | "dev": true 1420 | }, 1421 | "object-keys": { 1422 | "version": "1.0.11", 1423 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", 1424 | "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", 1425 | "dev": true 1426 | }, 1427 | "once": { 1428 | "version": "1.4.0", 1429 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1430 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1431 | "dev": true, 1432 | "requires": { 1433 | "wrappy": "1" 1434 | } 1435 | }, 1436 | "onetime": { 1437 | "version": "2.0.1", 1438 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1439 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1440 | "dev": true, 1441 | "requires": { 1442 | "mimic-fn": "^1.0.0" 1443 | } 1444 | }, 1445 | "optionator": { 1446 | "version": "0.8.2", 1447 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1448 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1449 | "dev": true, 1450 | "requires": { 1451 | "deep-is": "~0.1.3", 1452 | "fast-levenshtein": "~2.0.4", 1453 | "levn": "~0.3.0", 1454 | "prelude-ls": "~1.1.2", 1455 | "type-check": "~0.3.2", 1456 | "wordwrap": "~1.0.0" 1457 | } 1458 | }, 1459 | "os-tmpdir": { 1460 | "version": "1.0.2", 1461 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1462 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1463 | "dev": true 1464 | }, 1465 | "p-limit": { 1466 | "version": "1.2.0", 1467 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", 1468 | "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", 1469 | "dev": true, 1470 | "requires": { 1471 | "p-try": "^1.0.0" 1472 | } 1473 | }, 1474 | "p-locate": { 1475 | "version": "2.0.0", 1476 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1477 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1478 | "dev": true, 1479 | "requires": { 1480 | "p-limit": "^1.1.0" 1481 | } 1482 | }, 1483 | "p-try": { 1484 | "version": "1.0.0", 1485 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 1486 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", 1487 | "dev": true 1488 | }, 1489 | "parse-json": { 1490 | "version": "2.2.0", 1491 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1492 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1493 | "dev": true, 1494 | "requires": { 1495 | "error-ex": "^1.2.0" 1496 | } 1497 | }, 1498 | "path-exists": { 1499 | "version": "2.1.0", 1500 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 1501 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 1502 | "dev": true, 1503 | "requires": { 1504 | "pinkie-promise": "^2.0.0" 1505 | } 1506 | }, 1507 | "path-is-absolute": { 1508 | "version": "1.0.1", 1509 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1510 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1511 | "dev": true 1512 | }, 1513 | "path-is-inside": { 1514 | "version": "1.0.2", 1515 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1516 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 1517 | "dev": true 1518 | }, 1519 | "path-parse": { 1520 | "version": "1.0.7", 1521 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1522 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1523 | "dev": true 1524 | }, 1525 | "path-type": { 1526 | "version": "2.0.0", 1527 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 1528 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 1529 | "dev": true, 1530 | "requires": { 1531 | "pify": "^2.0.0" 1532 | } 1533 | }, 1534 | "pify": { 1535 | "version": "2.3.0", 1536 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1537 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1538 | "dev": true 1539 | }, 1540 | "pinkie": { 1541 | "version": "2.0.4", 1542 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1543 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1544 | "dev": true 1545 | }, 1546 | "pinkie-promise": { 1547 | "version": "2.0.1", 1548 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1549 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1550 | "dev": true, 1551 | "requires": { 1552 | "pinkie": "^2.0.0" 1553 | } 1554 | }, 1555 | "pkg-conf": { 1556 | "version": "2.1.0", 1557 | "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", 1558 | "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", 1559 | "dev": true, 1560 | "requires": { 1561 | "find-up": "^2.0.0", 1562 | "load-json-file": "^4.0.0" 1563 | }, 1564 | "dependencies": { 1565 | "find-up": { 1566 | "version": "2.1.0", 1567 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 1568 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 1569 | "dev": true, 1570 | "requires": { 1571 | "locate-path": "^2.0.0" 1572 | } 1573 | }, 1574 | "load-json-file": { 1575 | "version": "4.0.0", 1576 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", 1577 | "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", 1578 | "dev": true, 1579 | "requires": { 1580 | "graceful-fs": "^4.1.2", 1581 | "parse-json": "^4.0.0", 1582 | "pify": "^3.0.0", 1583 | "strip-bom": "^3.0.0" 1584 | } 1585 | }, 1586 | "parse-json": { 1587 | "version": "4.0.0", 1588 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 1589 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 1590 | "dev": true, 1591 | "requires": { 1592 | "error-ex": "^1.3.1", 1593 | "json-parse-better-errors": "^1.0.1" 1594 | } 1595 | }, 1596 | "pify": { 1597 | "version": "3.0.0", 1598 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1599 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 1600 | "dev": true 1601 | } 1602 | } 1603 | }, 1604 | "pkg-config": { 1605 | "version": "1.1.1", 1606 | "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", 1607 | "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", 1608 | "dev": true, 1609 | "requires": { 1610 | "debug-log": "^1.0.0", 1611 | "find-root": "^1.0.0", 1612 | "xtend": "^4.0.1" 1613 | } 1614 | }, 1615 | "pkg-dir": { 1616 | "version": "1.0.0", 1617 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", 1618 | "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", 1619 | "dev": true, 1620 | "requires": { 1621 | "find-up": "^1.0.0" 1622 | } 1623 | }, 1624 | "pluralize": { 1625 | "version": "7.0.0", 1626 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 1627 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 1628 | "dev": true 1629 | }, 1630 | "prelude-ls": { 1631 | "version": "1.1.2", 1632 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1633 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1634 | "dev": true 1635 | }, 1636 | "pretty-bytes": { 1637 | "version": "4.0.2", 1638 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", 1639 | "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=" 1640 | }, 1641 | "process-nextick-args": { 1642 | "version": "2.0.0", 1643 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1644 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 1645 | "dev": true 1646 | }, 1647 | "progress": { 1648 | "version": "2.0.0", 1649 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", 1650 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", 1651 | "dev": true 1652 | }, 1653 | "promise": { 1654 | "version": "7.3.1", 1655 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 1656 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 1657 | "dev": true, 1658 | "requires": { 1659 | "asap": "~2.0.3" 1660 | } 1661 | }, 1662 | "prop-types": { 1663 | "version": "15.6.1", 1664 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz", 1665 | "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==", 1666 | "dev": true, 1667 | "requires": { 1668 | "fbjs": "^0.8.16", 1669 | "loose-envify": "^1.3.1", 1670 | "object-assign": "^4.1.1" 1671 | } 1672 | }, 1673 | "pseudomap": { 1674 | "version": "1.0.2", 1675 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1676 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 1677 | "dev": true 1678 | }, 1679 | "read-pkg": { 1680 | "version": "2.0.0", 1681 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 1682 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 1683 | "dev": true, 1684 | "requires": { 1685 | "load-json-file": "^2.0.0", 1686 | "normalize-package-data": "^2.3.2", 1687 | "path-type": "^2.0.0" 1688 | } 1689 | }, 1690 | "read-pkg-up": { 1691 | "version": "2.0.0", 1692 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 1693 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 1694 | "dev": true, 1695 | "requires": { 1696 | "find-up": "^2.0.0", 1697 | "read-pkg": "^2.0.0" 1698 | }, 1699 | "dependencies": { 1700 | "find-up": { 1701 | "version": "2.1.0", 1702 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 1703 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 1704 | "dev": true, 1705 | "requires": { 1706 | "locate-path": "^2.0.0" 1707 | } 1708 | } 1709 | } 1710 | }, 1711 | "readable-stream": { 1712 | "version": "2.3.6", 1713 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1714 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1715 | "dev": true, 1716 | "requires": { 1717 | "core-util-is": "~1.0.0", 1718 | "inherits": "~2.0.3", 1719 | "isarray": "~1.0.0", 1720 | "process-nextick-args": "~2.0.0", 1721 | "safe-buffer": "~5.1.1", 1722 | "string_decoder": "~1.1.1", 1723 | "util-deprecate": "~1.0.1" 1724 | } 1725 | }, 1726 | "require-uncached": { 1727 | "version": "1.0.3", 1728 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 1729 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 1730 | "dev": true, 1731 | "requires": { 1732 | "caller-path": "^0.1.0", 1733 | "resolve-from": "^1.0.0" 1734 | } 1735 | }, 1736 | "resolve": { 1737 | "version": "1.7.1", 1738 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", 1739 | "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", 1740 | "dev": true, 1741 | "requires": { 1742 | "path-parse": "^1.0.5" 1743 | } 1744 | }, 1745 | "resolve-from": { 1746 | "version": "1.0.1", 1747 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 1748 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", 1749 | "dev": true 1750 | }, 1751 | "restore-cursor": { 1752 | "version": "2.0.0", 1753 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1754 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1755 | "dev": true, 1756 | "requires": { 1757 | "onetime": "^2.0.0", 1758 | "signal-exit": "^3.0.2" 1759 | } 1760 | }, 1761 | "rimraf": { 1762 | "version": "2.6.2", 1763 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1764 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1765 | "dev": true, 1766 | "requires": { 1767 | "glob": "^7.0.5" 1768 | } 1769 | }, 1770 | "run-async": { 1771 | "version": "2.3.0", 1772 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1773 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1774 | "dev": true, 1775 | "requires": { 1776 | "is-promise": "^2.1.0" 1777 | } 1778 | }, 1779 | "run-parallel": { 1780 | "version": "1.1.9", 1781 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", 1782 | "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", 1783 | "dev": true 1784 | }, 1785 | "rx-lite": { 1786 | "version": "4.0.8", 1787 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 1788 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", 1789 | "dev": true 1790 | }, 1791 | "rx-lite-aggregates": { 1792 | "version": "4.0.8", 1793 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 1794 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 1795 | "dev": true, 1796 | "requires": { 1797 | "rx-lite": "*" 1798 | } 1799 | }, 1800 | "safe-buffer": { 1801 | "version": "5.1.2", 1802 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1803 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1804 | "dev": true 1805 | }, 1806 | "safer-buffer": { 1807 | "version": "2.1.2", 1808 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1809 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1810 | "dev": true 1811 | }, 1812 | "semver": { 1813 | "version": "5.5.0", 1814 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 1815 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", 1816 | "dev": true 1817 | }, 1818 | "setimmediate": { 1819 | "version": "1.0.5", 1820 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 1821 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", 1822 | "dev": true 1823 | }, 1824 | "shebang-command": { 1825 | "version": "1.2.0", 1826 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1827 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1828 | "dev": true, 1829 | "requires": { 1830 | "shebang-regex": "^1.0.0" 1831 | } 1832 | }, 1833 | "shebang-regex": { 1834 | "version": "1.0.0", 1835 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1836 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1837 | "dev": true 1838 | }, 1839 | "signal-exit": { 1840 | "version": "3.0.2", 1841 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1842 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1843 | "dev": true 1844 | }, 1845 | "slice-ansi": { 1846 | "version": "1.0.0", 1847 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 1848 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 1849 | "dev": true, 1850 | "requires": { 1851 | "is-fullwidth-code-point": "^2.0.0" 1852 | } 1853 | }, 1854 | "spdx-correct": { 1855 | "version": "3.0.0", 1856 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", 1857 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", 1858 | "dev": true, 1859 | "requires": { 1860 | "spdx-expression-parse": "^3.0.0", 1861 | "spdx-license-ids": "^3.0.0" 1862 | } 1863 | }, 1864 | "spdx-exceptions": { 1865 | "version": "2.1.0", 1866 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", 1867 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", 1868 | "dev": true 1869 | }, 1870 | "spdx-expression-parse": { 1871 | "version": "3.0.0", 1872 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 1873 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 1874 | "dev": true, 1875 | "requires": { 1876 | "spdx-exceptions": "^2.1.0", 1877 | "spdx-license-ids": "^3.0.0" 1878 | } 1879 | }, 1880 | "spdx-license-ids": { 1881 | "version": "3.0.0", 1882 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", 1883 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", 1884 | "dev": true 1885 | }, 1886 | "sprintf-js": { 1887 | "version": "1.0.3", 1888 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1889 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1890 | "dev": true 1891 | }, 1892 | "standard": { 1893 | "version": "11.0.1", 1894 | "resolved": "https://registry.npmjs.org/standard/-/standard-11.0.1.tgz", 1895 | "integrity": "sha512-nu0jAcHiSc8H+gJCXeiziMVZNDYi8MuqrYJKxTgjP4xKXZMKm311boqQIzDrYI/ktosltxt2CbDjYQs9ANC8IA==", 1896 | "dev": true, 1897 | "requires": { 1898 | "eslint": "~4.18.0", 1899 | "eslint-config-standard": "11.0.0", 1900 | "eslint-config-standard-jsx": "5.0.0", 1901 | "eslint-plugin-import": "~2.9.0", 1902 | "eslint-plugin-node": "~6.0.0", 1903 | "eslint-plugin-promise": "~3.7.0", 1904 | "eslint-plugin-react": "~7.7.0", 1905 | "eslint-plugin-standard": "~3.0.1", 1906 | "standard-engine": "~8.0.0" 1907 | } 1908 | }, 1909 | "standard-engine": { 1910 | "version": "8.0.1", 1911 | "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-8.0.1.tgz", 1912 | "integrity": "sha512-LA531C3+nljom/XRvdW/hGPXwmilRkaRkENhO3FAGF1Vtq/WtCXzgmnc5S6vUHHsgv534MRy02C1ikMwZXC+tw==", 1913 | "dev": true, 1914 | "requires": { 1915 | "deglob": "^2.1.0", 1916 | "get-stdin": "^6.0.0", 1917 | "minimist": "^1.1.0", 1918 | "pkg-conf": "^2.0.0" 1919 | } 1920 | }, 1921 | "string-width": { 1922 | "version": "2.1.1", 1923 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1924 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1925 | "dev": true, 1926 | "requires": { 1927 | "is-fullwidth-code-point": "^2.0.0", 1928 | "strip-ansi": "^4.0.0" 1929 | } 1930 | }, 1931 | "string_decoder": { 1932 | "version": "1.1.1", 1933 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1934 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1935 | "dev": true, 1936 | "requires": { 1937 | "safe-buffer": "~5.1.0" 1938 | } 1939 | }, 1940 | "strip-ansi": { 1941 | "version": "4.0.0", 1942 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1943 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1944 | "dev": true, 1945 | "requires": { 1946 | "ansi-regex": "^3.0.0" 1947 | }, 1948 | "dependencies": { 1949 | "ansi-regex": { 1950 | "version": "3.0.0", 1951 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1952 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1953 | "dev": true 1954 | } 1955 | } 1956 | }, 1957 | "strip-bom": { 1958 | "version": "3.0.0", 1959 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1960 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 1961 | "dev": true 1962 | }, 1963 | "strip-json-comments": { 1964 | "version": "2.0.1", 1965 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1966 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1967 | "dev": true 1968 | }, 1969 | "supports-color": { 1970 | "version": "5.4.0", 1971 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 1972 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 1973 | "dev": true, 1974 | "requires": { 1975 | "has-flag": "^3.0.0" 1976 | } 1977 | }, 1978 | "table": { 1979 | "version": "4.0.2", 1980 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 1981 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 1982 | "dev": true, 1983 | "requires": { 1984 | "ajv": "^5.2.3", 1985 | "ajv-keywords": "^2.1.0", 1986 | "chalk": "^2.1.0", 1987 | "lodash": "^4.17.4", 1988 | "slice-ansi": "1.0.0", 1989 | "string-width": "^2.1.1" 1990 | } 1991 | }, 1992 | "text-table": { 1993 | "version": "0.2.0", 1994 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1995 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1996 | "dev": true 1997 | }, 1998 | "through": { 1999 | "version": "2.3.8", 2000 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2001 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2002 | "dev": true 2003 | }, 2004 | "tmp": { 2005 | "version": "0.0.33", 2006 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2007 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2008 | "dev": true, 2009 | "requires": { 2010 | "os-tmpdir": "~1.0.2" 2011 | } 2012 | }, 2013 | "type-check": { 2014 | "version": "0.3.2", 2015 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2016 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2017 | "dev": true, 2018 | "requires": { 2019 | "prelude-ls": "~1.1.2" 2020 | } 2021 | }, 2022 | "type-detect": { 2023 | "version": "1.0.0", 2024 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", 2025 | "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", 2026 | "dev": true 2027 | }, 2028 | "typedarray": { 2029 | "version": "0.0.6", 2030 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 2031 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 2032 | "dev": true 2033 | }, 2034 | "ua-parser-js": { 2035 | "version": "0.7.33", 2036 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz", 2037 | "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", 2038 | "dev": true 2039 | }, 2040 | "uniq": { 2041 | "version": "1.0.1", 2042 | "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", 2043 | "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", 2044 | "dev": true 2045 | }, 2046 | "util-deprecate": { 2047 | "version": "1.0.2", 2048 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2049 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 2050 | "dev": true 2051 | }, 2052 | "validate-npm-package-license": { 2053 | "version": "3.0.3", 2054 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", 2055 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", 2056 | "dev": true, 2057 | "requires": { 2058 | "spdx-correct": "^3.0.0", 2059 | "spdx-expression-parse": "^3.0.0" 2060 | } 2061 | }, 2062 | "whatwg-fetch": { 2063 | "version": "2.0.4", 2064 | "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", 2065 | "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", 2066 | "dev": true 2067 | }, 2068 | "which": { 2069 | "version": "1.3.1", 2070 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2071 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2072 | "dev": true, 2073 | "requires": { 2074 | "isexe": "^2.0.0" 2075 | } 2076 | }, 2077 | "wordwrap": { 2078 | "version": "1.0.0", 2079 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2080 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2081 | "dev": true 2082 | }, 2083 | "wrappy": { 2084 | "version": "1.0.2", 2085 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2086 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2087 | "dev": true 2088 | }, 2089 | "write": { 2090 | "version": "0.2.1", 2091 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 2092 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 2093 | "dev": true, 2094 | "requires": { 2095 | "mkdirp": "^0.5.1" 2096 | } 2097 | }, 2098 | "xtend": { 2099 | "version": "4.0.1", 2100 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2101 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 2102 | "dev": true 2103 | }, 2104 | "yallist": { 2105 | "version": "2.1.2", 2106 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2107 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 2108 | "dev": true 2109 | } 2110 | } 2111 | } 2112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leakage", 3 | "version": "0.5.0", 4 | "description": "Memory leak testing for node. Javascript memory footprinting using your favorite test runner.", 5 | "main": "lib/index", 6 | "scripts": { 7 | "test": "mocha --timeout 60000 test/", 8 | "posttest": "standard src/**/*.js test/**/*.js" 9 | }, 10 | "author": "Andy Wermke ", 11 | "contributors": [ 12 | "Brandon Mills (https://github.com/btmills)" 13 | ], 14 | "license": "MIT", 15 | "repository": "andywer/leakage", 16 | "bugs": "https://github.com/andywer/leakage/issues", 17 | "keywords": [ 18 | "memory leak", 19 | "testing", 20 | "node", 21 | "javascript", 22 | "v8", 23 | "heap" 24 | ], 25 | "files": [ 26 | "lib/" 27 | ], 28 | "engines": { 29 | "node": ">= 8.0" 30 | }, 31 | "dependencies": { 32 | "@aidemaster/node-memwatch": "^1.0.5", 33 | "es6-error": "^4.0.2", 34 | "minimist": "^1.2.0", 35 | "pretty-bytes": "^4.0.2" 36 | }, 37 | "devDependencies": { 38 | "chai": "^3.5.0", 39 | "chai-as-promised": "^6.0.0", 40 | "mocha": "^5.2.0", 41 | "standard": "^11.0.1" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/heap-footprint.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | // Using mocha, since for memory leak testing we want the tests run serially, anyway 3 | 4 | const expect = require('chai').expect 5 | const { iterate } = require('../lib/index') 6 | 7 | describe('leakage', () => { 8 | it('creates a clean heap diff when running a sync no-op function', () => { 9 | const result = iterate(() => {}) 10 | result.printSummary('sync no-op function') 11 | 12 | for (const heapDiff of result.heapDiffs) { 13 | expect(Math.abs(heapDiff.change.size_bytes)).to.be.below(1024) 14 | } 15 | }) 16 | 17 | it('creates a clean heap diff when running an async no-op function', () => { 18 | return iterate.async(() => Promise.resolve()) 19 | .then(result => { 20 | result.printSummary('async no-op function') 21 | for (const heapDiff of result.heapDiffs) { 22 | expect(Math.abs(heapDiff.change.size_bytes)).to.be.below(17 * 1024) 23 | } 24 | }) 25 | }) 26 | 27 | it('creates only a small heap diff when running an async deferred no-op function', () => { 28 | const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) 29 | return iterate.async(() => delay(10), { gcollections: 15 }) 30 | .then(result => { 31 | result.printSummary('async deferred no-op function') 32 | for (const heapDiff of result.heapDiffs) { 33 | expect(Math.abs(heapDiff.change.size_bytes)).to.be.below(24 * 1024) 34 | } 35 | }) 36 | }) 37 | 38 | // TODO: The sensitivity level is not exceeded when running sync code with few and with many iterations 39 | // TODO: The sensitivity level is not exceeded when running async code with few and with many iterations 40 | }) 41 | -------------------------------------------------------------------------------- /test/integration.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | // Using mocha, since for memory leak testing we want the tests run serially, anyway 3 | 4 | require('chai').use(require('chai-as-promised')) 5 | 6 | const assert = require('chai').assert 7 | const expect = require('chai').expect 8 | const { iterate, MemoryLeakError } = require('../lib/index') 9 | 10 | describe('leakage', () => { 11 | it('throws an error when testing leaky code', () => { 12 | const objects = [] 13 | 14 | expect(() => iterate(() => { 15 | const newObject = { foo: 'bar' } 16 | objects.push(newObject) // <= leak 17 | }, { iterations: 300 })).to.throw(MemoryLeakError, /Heap grew on \d subsequent garbage collections[\s\S]*Iterations between GCs: 30[\s\S]*Final GC details:/) 18 | }) 19 | 20 | it('does not throw when testing non-leaky code', () => { 21 | expect(() => iterate(() => { 22 | const objects = [] 23 | const newObject = { foo: 'bar' } 24 | objects.push(newObject) 25 | }, { iterations: 300 })).to.not.throw() 26 | }) 27 | 28 | // Regression test: Would throw when run again with a different runner 29 | it('does not throw when testing non-leaky code again', () => { 30 | expect(() => iterate(() => { 31 | const objects = [] 32 | const newObject = { foo: 'bar' } 33 | objects.push(newObject) 34 | })).to.not.throw() 35 | }) 36 | 37 | it('returns a rejecting promise when testing leaky code', () => { 38 | const objects = [] 39 | 40 | return expect( 41 | iterate.async(() => new Promise( 42 | resolve => setTimeout(() => { 43 | const newObject = { 44 | foo: 'bar', 45 | baz () { 46 | return 'Some output' 47 | } 48 | } 49 | objects.push(newObject) // <= leak 50 | resolve() 51 | }, 20) 52 | )) 53 | ).to.eventually.be.rejectedWith(MemoryLeakError, /^Heap grew on \d subsequent garbage collections[\s\S]*Iterations between GCs: 30[\s\S]*Final GC details:/) 54 | }) 55 | 56 | it('returns a resolving promise when testing non-leaky code', () => { 57 | const promise = iterate.async(() => new Promise( 58 | resolve => setTimeout(() => { 59 | const objects = [] 60 | const newObject = { foo: 'bar' } 61 | objects.push(newObject) 62 | resolve() 63 | }, 20) 64 | )) 65 | assert(promise.then) 66 | expect(typeof promise.then).to.equal('function') 67 | 68 | return promise 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /test/usability.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | // Using mocha, since for memory leak testing we want the tests run serially, anyway 3 | 4 | require('chai').use(require('chai-as-promised')) 5 | 6 | const expect = require('chai').expect 7 | const { iterate } = require('../lib/index') 8 | 9 | describe('leakage', () => { 10 | it('throws on iterate()', () => { 11 | expect( 12 | () => iterate(() => Promise.resolve()) 13 | ).to.throw(/Use iterate\.async\(\)/) 14 | }) 15 | 16 | it('rejects iterate.async()', () => { 17 | return expect( 18 | iterate.async(() => {}) 19 | ).to.eventually.be.rejectedWith(/Use iterate\(\)/) 20 | }) 21 | 22 | it('rejects concurrent test runs', () => { 23 | return expect( 24 | Promise.all([ 25 | iterate.async(() => Promise.resolve()), 26 | iterate.async(() => Promise.resolve()) 27 | ]) 28 | ).to.eventually.be.rejectedWith(/Detected concurrently running tests/) 29 | }) 30 | 31 | it('returns a useful test result and can print its summary', () => { 32 | const result = iterate(() => {}, { gcollections: 2, iterations: 10 }) 33 | expect(result.heapDiffs).to.be.an('array') 34 | expect(result.gcollections).to.be.a('number') 35 | expect(result.iterations).to.be.a('number') 36 | 37 | const summaryLines = [] 38 | result.printSummary('Some title', line => summaryLines.push(line)) 39 | 40 | expect(summaryLines[0].trim()).to.equal('Leak test summary - Some title:') 41 | expect(summaryLines[1].trim()).to.equal('Did 2 heap diffs, iterating 10 times each.') 42 | }) 43 | }) 44 | --------------------------------------------------------------------------------