├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── algorithms ├── misc │ ├── activity-selection │ │ ├── activity-selection.spec.ts │ │ └── activity-selection.ts │ ├── change-making │ │ ├── change-making.spec.ts │ │ └── change-making.ts │ ├── huffman │ │ ├── __snapshots__ │ │ │ └── huffman.spec.ts.snap │ │ ├── huffman.spec.ts │ │ └── huffman.ts │ ├── inversions-count │ │ ├── inversions-count.spec.ts │ │ └── inversions-count.ts │ ├── longest-common-subsequence │ │ ├── __snapshots__ │ │ │ └── longest-common-subsequence.spec.ts.snap │ │ ├── longest-common-subsequence.spec.ts │ │ └── longest-common-subsequence.ts │ ├── maximum-subarray │ │ ├── maximum-subarray.spec.ts │ │ └── maximum-subarray.ts │ ├── priority-queue │ │ ├── priority-queue.spec.ts │ │ └── priority-queue.ts │ └── rod-cutting │ │ ├── rod-cutting.spec.ts │ │ └── rod-cutting.ts ├── search │ ├── binary-search-tree │ │ ├── __snapshots__ │ │ │ └── binary-search-tree.spec.ts.snap │ │ ├── binary-search-tree.spec.ts │ │ └── binary-search-tree.ts │ └── binary-search │ │ ├── binary-search.spec.ts │ │ └── binary-search.ts ├── sort │ ├── counting-sort │ │ ├── counting-sort.spec.ts │ │ └── counting-sort.ts │ ├── heap-sort │ │ ├── heap-sort.spec.ts │ │ └── heap-sort.ts │ ├── insertion-sort │ │ ├── insertion-sort.spec.ts │ │ └── insertion-sort.ts │ ├── merge-and-insertion-sort │ │ ├── merge-and-insertion-sort.spec.ts │ │ └── merge-and-insertion-sort.ts │ ├── merge-sort │ │ ├── merge-sort.spec.ts │ │ └── merge-sort.ts │ ├── quick-sort │ │ ├── quick-sort.spec.ts │ │ └── quick-sort.ts │ └── selection-sort │ │ ├── selection-sort.spec.ts │ │ └── selection-sort.ts └── utils.ts ├── assets ├── jest-1.png └── jest.png ├── package-lock.json ├── package.json ├── tests ├── btree-serializer.js └── matrix-serializer.js ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node,linux,macos,windows 2 | 3 | ### Linux ### 4 | *~ 5 | 6 | # temporary files which can be created if a process still has a handle open of a deleted file 7 | .fuse_hidden* 8 | 9 | # KDE directory preferences 10 | .directory 11 | 12 | # Linux trash folder which might appear on any partition or disk 13 | .Trash-* 14 | 15 | # .nfs files are created when an open file is removed but is still being accessed 16 | .nfs* 17 | 18 | ### macOS ### 19 | *.DS_Store 20 | .AppleDouble 21 | .LSOverride 22 | 23 | # Icon must end with two \r 24 | Icon 25 | 26 | # Thumbnails 27 | ._* 28 | 29 | # Files that might appear in the root of a volume 30 | .DocumentRevisions-V100 31 | .fseventsd 32 | .Spotlight-V100 33 | .TemporaryItems 34 | .Trashes 35 | .VolumeIcon.icns 36 | .com.apple.timemachine.donotpresent 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | 45 | ### Node ### 46 | # Logs 47 | logs 48 | *.log 49 | npm-debug.log* 50 | yarn-debug.log* 51 | yarn-error.log* 52 | 53 | # Runtime data 54 | pids 55 | *.pid 56 | *.seed 57 | *.pid.lock 58 | 59 | # Directory for instrumented libs generated by jscoverage/JSCover 60 | lib-cov 61 | 62 | # Coverage directory used by tools like istanbul 63 | coverage 64 | 65 | # nyc test coverage 66 | .nyc_output 67 | 68 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 69 | .grunt 70 | 71 | # Bower dependency directory (https://bower.io/) 72 | bower_components 73 | 74 | # node-waf configuration 75 | .lock-wscript 76 | 77 | # Compiled binary addons (http://nodejs.org/api/addons.html) 78 | build/Release 79 | 80 | # Dependency directories 81 | node_modules/ 82 | jspm_packages/ 83 | 84 | # Typescript v1 declaration files 85 | typings/ 86 | 87 | # Optional npm cache directory 88 | .npm 89 | 90 | # Optional eslint cache 91 | .eslintcache 92 | 93 | # Optional REPL history 94 | .node_repl_history 95 | 96 | # Output of 'npm pack' 97 | *.tgz 98 | 99 | # Yarn Integrity file 100 | .yarn-integrity 101 | 102 | # dotenv environment variables file 103 | .env 104 | 105 | 106 | ### Windows ### 107 | # Windows thumbnail cache files 108 | Thumbs.db 109 | ehthumbs.db 110 | ehthumbs_vista.db 111 | 112 | # Folder config file 113 | Desktop.ini 114 | 115 | # Recycle Bin used on file shares 116 | $RECYCLE.BIN/ 117 | 118 | # Windows Installer files 119 | *.cab 120 | *.msi 121 | *.msm 122 | *.msp 123 | 124 | # Windows shortcuts 125 | *.lnk 126 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | - "6" 5 | notifications: 6 | email: 7 | on_success: never 8 | on_failure: always 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Giovanni Jiayi Hu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pretty algorithms 2 | 3 | [![travis](https://travis-ci.org/jiayihu/pretty-algorithms.svg?branch=master)](https://travis-ci.org/jiayihu/pretty-algorithms) 4 | 5 | Common useful algorithms written in modern, pretty and easy-to-understand Javascript along with [real-world usage](#real-world-usage) examples. Implementations are in standard ES6 Javascript with the addition of Typescript type annotations for better clarity. 6 | 7 | All the algorithms are also tested using [Jest](http://facebook.github.io/jest/) with the help of custom beautiful [snapshots](https://facebook.github.io/jest/docs/snapshot-testing.html). 8 | 9 | ![Jest](assets/jest-1.png) 10 | 11 | ## Note 12 | 13 | The purpose of this repository is to show algorithms written using declarative and intuitive code as much as possible. It's not meant to be used as production. Clarity and simplicity is favored over performance. 14 | 15 | If you need something absolutely performant in production try checking [felipernb/algorithms.js](https://github.com/felipernb/algorithms.js) with low-level optimisations. 16 | 17 | ## Content 18 | 19 | ### Miscellaneous 20 | 21 | - [Activity selection](algorithms/misc/activity-selection/activity-selection.ts) 22 | - [Coins change making](algorithms/misc/change-making/change-making.ts) 23 | - [Huffman coding](algorithms/misc/huffman/huffman.ts) 24 | - [Inversion count](algorithms/misc/inversions-count/inversions-count.ts) 25 | - [Longest common subsequence](algorithms/misc/longest-common-subsequence/longest-common-subsequence.ts) 26 | - [Maximum subarray](algorithms/misc/maximum-subarray/maximum-subarray.ts) 27 | - [Priority queue](algorithms/misc/priority-queue/priority-queue.ts) 28 | - [Rod cutting](algorithms/misc/rod-cutting/rod-cutting.ts) 29 | 30 | ### Search 31 | 32 | - [Binary search](algorithms/search/binary-search/binary-search.ts) 33 | - [Binary search tree](algorithms/search/binary-search-tree/binary-search-tree.ts) 34 | 35 | ### Sort 36 | 37 | - [Counting sort](algorithms/sort/counting-sort/counting-sort.ts) 38 | - [Heap sort](algorithms/sort/heap-sort/heap-sort.ts) 39 | - [Insertion sort](algorithms/sort/insertion-sort/insertion-sort.ts) 40 | - [Merge sort](algorithms/sort/merge-sort/merge-sort.ts) 41 | - [Merge and insertion sort](algorithms/sort/merge-and-insertion-sort/merge-and-insertion-sort.ts) 42 | - [Quick sort](algorithms/sort/quick-sort/quick-sort.ts) 43 | - [Selection sort](algorithms/sort/selection-sort/selection-sort.ts) 44 | 45 | ## Usage 46 | 47 | You can play around with the code cloning the repo and running the following commands: 48 | 49 | ```bash 50 | npm install 51 | npm test 52 | ``` 53 | 54 | Play around with the source code, the tests and learn algorithms! You can also run the following command to put tests in watch mode and auto-run with changes. [Jest](http://facebook.github.io/jest/) CLI output is awesome! 55 | 56 | ```bash 57 | npm run test -- --watch 58 | ``` 59 | 60 | ![Jest](assets/jest.png) 61 | 62 | ## Real-world usage 63 | 64 | Some real-world usage of the algorithms to show when they can be applied. 65 | 66 | ### Activity selection 📆 67 | 68 | > The activity selection problem is the selection of non-conflicting activities to perform within a given time frame, given a set of activities each marked by a start time (s[i]) and finish time (f[i]). 69 | 70 | A classic application of this problem is in scheduling a room for multiple competing events, each having its own time requirements (start and end time), and many more arise within the framework of operations research. [Source](https://en.wikipedia.org/wiki/Activity_selection_problem) 71 | 72 | ### Change making 💰 73 | 74 | > The change-making problem addresses the question of finding the minimum number of coins (of certain denominations) that add up to a given amount of money. 75 | 76 | The change-making problem is a [knapsack type problem](https://en.wikipedia.org/wiki/Knapsack_problem), and has applications wider than just currency. 77 | It can be used whenever there is the need to calculate the minimum set of items to add up to a value. 78 | 79 | An application of change-making problem can be found in computing the ways one can make a *nine dart finish* in a game of darts. [Source](https://en.wikipedia.org/wiki/Change-making_problem#Non-currency_examples) 80 | 81 | ### Huffman coding 🔡 82 | 83 | > A Huffman code is a particular type of optimal prefix code that is commonly used for lossless data compression. 84 | 85 | The `Huffman coding` is often used as a "back-end" to other compression methods. DEFLATE (PKZIP's algorithm) and multimedia codecs such as JPEG and MP3 have a front-end model and quantization followed by the use of prefix codes. [Source](https://en.wikipedia.org/wiki/Huffman_coding#Applications) 86 | 87 | ### Longest common subsequence 📐 88 | 89 | > The longest common subsequence (LCS) problem is the problem of finding the longest subsequence common to two sequences. 90 | It differs from problems of finding common substrings since subsequences are not required to occupy consecutive positions within the original sequences. 91 | 92 | The `longest common subsequence` problem is the basis of data comparison programs such as the diff utility and has applications in bioinformatics (sequences of DNA). 93 | It is also widely used by revision control systems such as *Git* for reconciling multiple changes made to a revision-controlled collection of files. 94 | [Source](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) 95 | 96 | The LCS problem is also the base of the [edit-distance problem](https://en.wikipedia.org/wiki/Edit_distance), which quantifies how dissimilar two strings are to one another. 97 | An application of the latter could avoid some security problems, as happened to NPM: [`crossenv` malware on the npm registry](http://blog.npmjs.org/post/163723642530/crossenv-malware-on-the-npm-registry). 98 | 99 | ### Maximum subarray 📈 100 | 101 | > Find the contiguous subarray within an array of numbers which has the largest sum. 102 | 103 | The `Maximum subarray` problem is useful to find the range of maximum in a period of events, such as the best moment to buy and sell stock assets knowing their value in a period of time. Another example: 104 | 105 | *You have a list of income details for each month of the company ACME for a year of 2016…you have to find out in which part of year the company earns more income and how much it earns.* [Source](https://www.quora.com/What-are-some-applications-of-maximum-subarray-problems) 106 | 107 | This algorithm also has been applied to radio telescope images acquired for the Australian square kilometer array pathfinder project. This paper provides an overview of the maximum subarray algorithm and shows how this can be utilized for optical and radio telescope applications. [Source](http://spie.org/Publications/Proceedings/Paper/10.1117/12.928318) 108 | 109 | ### Priority-queues 🎢 110 | 111 | > A priority queue is an abstract data type which is like a regular queue or stack data structure, but where additionally each element has a "priority" associated with it. In a priority queue, an element with high priority is served before an element with low priority. 112 | 113 | A `priority queue` can be used for Bandwidth management, Discrete event simulation, Dijkstra's algorithm and so on. Open the 114 | [source](https://en.wikipedia.org/wiki/Priority_queue#Applications) for more details. 115 | 116 | ### Rod cutting 💸 117 | 118 | > Find the best way to cut a rod of length `n`, assuming that each length has a price. Find best set of cuts to get maximum price. 119 | 120 | The `Rod cutting` problem can be used to maximize a profit whenever the resources can be divided into minor quantities and sold separately. Useful, isn't it? 121 | 122 | ### Binary search (tree) 🌳 123 | 124 | > Binary search is a search algorithm that finds the position of a target value within a sorted collection. 125 | 126 | Some applications of `Binary search`: 127 | 128 | - Fast autocomplete/dictionary. [Source](https://www.weheartswift.com/binary-search-applications/) 129 | 130 | - `Set` and `Map` implementation of many standard language libraries. [Source](https://stackoverflow.com/a/540191/6860493) 131 | 132 | ### Sorting 🤔 133 | 134 | > A sorting algorithm is an algorithm that puts elements of a list in a certain order 135 | 136 | Many computer scientists consider sorting to be the most fundamental problem in the study of algorithms. There are several reasons: 137 | 138 | - Sometimes an application inherently needs to sort information. For example, in order to prepare customer statements, banks need to sort checks by check number. 139 | 140 | - Algorithms often use sorting as a key subroutine. For example, a program that renders graphical objects which are layered on top of each other might have to sort the objects according to an “above” relation so that it can draw these objects from bottom to top. We shall see numerous algorithms in this text that use sorting as a subroutine. 141 | 142 | - We can draw from among a wide variety of sorting algorithms, and they employ a rich set of techniques. In fact, many important techniques used throughout algorithm design appear in the body of sorting algorithms that have been developed over the years. In this way, sorting is also a problem of historical interest. 143 | 144 | [Source](https://mitpress.mit.edu/books/introduction-algorithms). 145 | 146 | Check instead [this article about pros and cons of each sorting algorithms](http://www.brucemerry.org.za/manual/algorithms/sorting.html). 147 | 148 | ## TODO 149 | 150 | - Add more real-world examples 151 | - Add benchmarks 152 | -------------------------------------------------------------------------------- /algorithms/misc/activity-selection/activity-selection.spec.ts: -------------------------------------------------------------------------------- 1 | import { activitySelector, Activity } from './activity-selection'; 2 | 3 | describe('activitySelector', () => { 4 | it('should return a selection of non-conflicting activities', () => { 5 | const activities: Activity[] = [ 6 | { start: 1, finish: 4 }, 7 | { start: 3, finish: 5 }, 8 | { start: 0, finish: 6 }, 9 | { start: 5, finish: 7 }, 10 | { start: 3, finish: 9 }, 11 | { start: 5, finish: 9 }, 12 | { start: 6, finish: 10 }, 13 | { start: 8, finish: 11 }, 14 | { start: 8, finish: 12 }, 15 | { start: 2, finish: 14 }, 16 | { start: 12, finish: 16 }, 17 | ]; 18 | const selected = activitySelector(activities); 19 | 20 | expect(selected).toEqual([ 21 | { start: 1, finish: 4 }, 22 | { start: 5, finish: 7 }, 23 | { start: 8, finish: 11 }, 24 | { start: 12, finish: 16 }, 25 | ]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /algorithms/misc/activity-selection/activity-selection.ts: -------------------------------------------------------------------------------- 1 | import { range } from '../../utils'; 2 | 3 | /** 4 | * The activity selection problem is the selection of non-conflicting activities to 5 | * perform within a given time frame, given a set of activities each marked by 6 | * a start time (s[i]) and finish time (f[i]). 7 | * 8 | * The problem is to select the maximum number of activities that can be performed. 9 | * 10 | * The solution is a greedy algorithm. 11 | * @url https://en.wikipedia.org/wiki/Greedy_algorithm 12 | */ 13 | 14 | export interface Activity { 15 | start: number; 16 | finish: number; 17 | } 18 | 19 | /** 20 | * Return the array of non-conflicting activies within the time frame defined by 21 | * the input activities array. 22 | * @NOTE: all input arrays are assumed ordered by ascending finish time, for instance 23 | * using a quick-sort in P(n*lg(n)) time. 24 | * 25 | * Time complexity: O(n) 26 | * @param activities Array of activities which can be performed in the time frame. 27 | * activities[0].start - activities[activities.length - 1].finish defines the 28 | * time frame. 29 | */ 30 | export function activitySelector(activities: T[]): T[] { 31 | // The first activity always gets selected 32 | const selected = [activities[0]]; 33 | let lastActivity: Activity = activities[0]; 34 | 35 | /** 36 | * Always select the first activity which starts right after the last one. It's 37 | * also the one which finishes before any other since the input list is ordered 38 | * by finish time. 39 | * 40 | * Proof of optimality can be found here: 41 | * @url https://en.wikipedia.org/wiki/Activity_selection_problem#Proof_of_optimality 42 | */ 43 | range(1, activities.length - 1).forEach(index => { 44 | const currentActivity = activities[index]; 45 | 46 | if (currentActivity.start >= lastActivity.finish) { 47 | selected.push(currentActivity); 48 | lastActivity = currentActivity; 49 | } 50 | }); 51 | 52 | return selected; 53 | } 54 | -------------------------------------------------------------------------------- /algorithms/misc/change-making/change-making.spec.ts: -------------------------------------------------------------------------------- 1 | import { changeMaking } from './change-making'; 2 | 3 | describe('changeMaking', () => { 4 | it('should return the minimum number of coins for a given value', () => { 5 | const coins = [25, 10, 5]; 6 | const result = changeMaking(coins, 30); 7 | 8 | expect(result).toBe(2); // 25 + 5 9 | }); 10 | 11 | it('should return the minimum number of coins for a given value', () => { 12 | const coins = [9, 6, 5, 1]; 13 | const result = changeMaking(coins, 11); 14 | 15 | expect(result).toBe(2); // 6 + 5 16 | }); 17 | 18 | it('should return 1 if the amount is available as coin', () => { 19 | const coins = [9, 6, 5, 1]; 20 | 21 | expect(changeMaking(coins, 9)).toBe(1); 22 | expect(changeMaking(coins, 6)).toBe(1); 23 | expect(changeMaking(coins, 5)).toBe(1); 24 | expect(changeMaking(coins, 1)).toBe(1); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /algorithms/misc/change-making/change-making.ts: -------------------------------------------------------------------------------- 1 | import { range } from '../../utils'; 2 | 3 | /** 4 | * Problem: find the minimum number of coins (of certain denominations) that add 5 | * up to a given amount of money. 6 | * @url https://en.wikipedia.org/wiki/Change-making_problem 7 | * 8 | * The solution uses dynamic-programming with top-down strategy instead of bottom-up 9 | * to avoid resolution of every sub-problem, which is not needed for this problem. 10 | * @url https://en.wikipedia.org/wiki/Dynamic_programming 11 | */ 12 | 13 | /** 14 | * Return the minimum of coins that add up to a given amount of money. 15 | * Time complexity: O(m*n) where m = coins.length, n = amount 16 | * @param coins The available coins 17 | * @param amount The value to add up to 18 | */ 19 | export function changeMaking(coins: number[], amount: number): number { 20 | // Memoization array used to store best results for problems up to `amount` dimension 21 | const results: number[] = new Array(amount + 1); 22 | results.fill(-Infinity); 23 | 24 | // Zero coins are needed for amount 0 25 | results[0] = 0; 26 | // Only one coin is needed if the amount is equal to one of the coins 27 | coins.forEach(coin => (results[coin] = 1)); 28 | 29 | return minCoins(coins, results, amount); 30 | } 31 | 32 | function minCoins(coins: number[], results: number[], amount: number): number { 33 | if (results[amount] >= 0) return results[amount]; 34 | 35 | let result: number = Infinity; 36 | 37 | coins.filter(coin => coin <= amount).forEach(coin => { 38 | result = Math.min(result, 1 + minCoins(coins, results, amount - coin)); 39 | }); 40 | 41 | results[amount] = result; 42 | 43 | return result; 44 | } 45 | -------------------------------------------------------------------------------- /algorithms/misc/huffman/__snapshots__/huffman.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Huffman coding tree 1`] = ` 4 | │ ┌── d:16 5 | │ ┌── 30 6 | │ │ │ ┌── e:9 7 | │ │ └── 14 8 | │ │ └── f:5 9 | │ ┌── 55 10 | │ │ │ ┌── b:13 11 | │ │ └── 25 12 | │ │ └── c:12 13 | └── 100 14 | └── a:45 15 | 16 | `; 17 | -------------------------------------------------------------------------------- /algorithms/misc/huffman/huffman.spec.ts: -------------------------------------------------------------------------------- 1 | import { huffman, Frequency } from './huffman'; 2 | import { toSerializableTree } from '../../utils'; 3 | 4 | describe('huffman', () => { 5 | it('should return the tree of prefix codes', () => { 6 | const frequences: Frequency[] = [ 7 | { char: 'a', frequency: 45 }, 8 | { char: 'b', frequency: 13 }, 9 | { char: 'c', frequency: 12 }, 10 | { char: 'd', frequency: 16 }, 11 | { char: 'e', frequency: 9 }, 12 | { char: 'f', frequency: 5 }, 13 | ]; 14 | const tree = huffman(frequences); 15 | 16 | // Convert the Huffman tree 17 | const serializable = toSerializableTree(tree, node => { 18 | const key = node.char ? `${node.char}:${node.frequency}` : node.frequency; 19 | 20 | return { key, left: node.left, right: node.right }; 21 | }); 22 | 23 | expect(tree).toMatchSnapshot('Huffman coding tree'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /algorithms/misc/huffman/huffman.ts: -------------------------------------------------------------------------------- 1 | const MinHeap = require('min-heap'); 2 | import { range } from '../../utils'; 3 | 4 | export interface Frequency { 5 | char: string; 6 | frequency: number; 7 | } 8 | 9 | /** 10 | * Return a Huffman Tree for the prefix codes. See the snapshot in `__snapshots` 11 | * to have a visual rappresentation. 12 | * @url https://en.wikipedia.org/wiki/Huffman_coding 13 | * 14 | * Time complexity: O(n*lg(n)) 15 | * @param frequences Characters frequencies 16 | */ 17 | export function huffman(frequences: Frequency[]) { 18 | /** 19 | * Create a min priority queue with min-heap. An almost identical implementation 20 | * can be found in 'algorithms/misc/priority-queue' but for max priority. 21 | */ 22 | const queue = new MinHeap((a: Frequency, b: Frequency) => a.frequency - b.frequency); 23 | frequences.forEach(freq => queue.insert(freq)); 24 | 25 | range(0, frequences.length - 2).forEach(() => { 26 | const left: Frequency = queue.removeHead(); 27 | const right: Frequency = queue.removeHead(); 28 | const merged = { 29 | frequency: left.frequency + right.frequency, 30 | left, 31 | right, 32 | }; 33 | 34 | queue.insert(merged); 35 | }); 36 | 37 | return queue.removeHead(); 38 | } 39 | -------------------------------------------------------------------------------- /algorithms/misc/inversions-count/inversions-count.spec.ts: -------------------------------------------------------------------------------- 1 | import { countInversions } from './inversions-count'; 2 | 3 | describe('countInversions', () => { 4 | it('should count the number of inversions', () => { 5 | const input = [2, 3, 8, 6, 1]; 6 | const count = countInversions(input); 7 | 8 | expect(count).toBe(5); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /algorithms/misc/inversions-count/inversions-count.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Given array A[1... n], for every i < j, find all inversion pairs such that A[i] > A[j]. 3 | * Solution must have complexity O(n*lg(n)). 4 | * 5 | * Tip: modify merge-sort 6 | */ 7 | 8 | import { range } from '../../utils'; 9 | import head from 'lodash/head'; 10 | 11 | /** 12 | * Divide and sort merges two subarrays of given array, like in merge-sort, but 13 | * count also the number of inversions in the merged array during the process. 14 | * Time complexity: O(n) 15 | * @param input The array which subarrays should be sorted 16 | * @param start Start of the first array 17 | * @param mid End of first array, not included 18 | * @param end End of second array, not including 19 | */ 20 | function merge(input: number[], start: number, mid: number, end: number): number { 21 | const left = input.slice(start, mid); 22 | const right = input.slice(mid, end); 23 | 24 | left[left.length] = -Infinity as any; 25 | right[right.length] = -Infinity as any; 26 | 27 | let inversionCount = 0; 28 | 29 | range(start, end - 1).forEach(index => { 30 | if (head(left) > head(right)) { 31 | inversionCount += right.length - 1; // Do not include Infinity in the count 32 | input[index] = left.shift(); 33 | } else { 34 | input[index] = right.shift(); 35 | } 36 | }); 37 | 38 | return inversionCount; 39 | } 40 | 41 | /** 42 | * Count the number of inversions 43 | * Time complexity: O(n*lg(n)). 44 | * @param input The array which should be sorted 45 | * @param start Left side of the subarray 46 | * @param end Right side of the subarray, not included 47 | */ 48 | export function countInversions( 49 | input: number[], 50 | start: number = 0, 51 | end: number = input.length 52 | ): number { 53 | if (end - start <= 1) return 0; 54 | 55 | const mid = Math.floor((start + end) / 2); 56 | const leftCount = countInversions(input, start, mid); 57 | const rightCount = countInversions(input, mid, end); 58 | 59 | return leftCount + rightCount + merge(input, start, mid, end); 60 | } 61 | -------------------------------------------------------------------------------- /algorithms/misc/longest-common-subsequence/__snapshots__/longest-common-subsequence.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`LCS subsequences lengths 1`] = ` 4 | 0 1 2 3 4 5 6 5 | B D C A B A 6 | ______________ 7 | 0 | 0 0 0 0 0 0 0 8 | 1 A| 0 0 0 0 1 1 1 9 | 2 B| 0 1 1 1 1 2 2 10 | 3 C| 0 1 1 2 2 2 2 11 | 4 B| 0 1 1 2 2 3 3 12 | 5 D| 0 1 2 2 2 3 3 13 | 6 A| 0 1 2 2 3 3 4 14 | 7 B| 0 1 2 2 3 4 4 15 | 16 | `; 17 | -------------------------------------------------------------------------------- /algorithms/misc/longest-common-subsequence/longest-common-subsequence.spec.ts: -------------------------------------------------------------------------------- 1 | import { lcsLengths, findLCS } from './longest-common-subsequence'; 2 | 3 | describe('lcsLengths', () => { 4 | it('should return the table of common subsequences lengths', () => { 5 | const seqA = 'ABCBDAB'; 6 | const seqB = 'BDCABA'; 7 | const lengths = lcsLengths(seqA, seqB); 8 | 9 | // Add sequences to the matrix for prettier snapshot 10 | (lengths as any).y = ' ' + seqA; 11 | (lengths as any).x = ' ' + seqB; 12 | 13 | expect(lengths).toMatchSnapshot('LCS subsequences lengths'); 14 | }); 15 | }); 16 | 17 | describe('findLCS', () => { 18 | it('should return the LCS for two sequences', () => { 19 | const seqA = 'ABCBDAB'; 20 | const seqB = 'BDCABA'; 21 | const lcs = findLCS(seqA, seqB); 22 | 23 | expect(lcs).toBe('BCBA'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /algorithms/misc/longest-common-subsequence/longest-common-subsequence.ts: -------------------------------------------------------------------------------- 1 | import { fill, range } from '../../utils'; 2 | 3 | /** 4 | * The longest common subsequence (LCS) problem is the problem of finding the 5 | * longest subsequence common to two sequences. 6 | * 7 | * It differs from problems of finding common substrings since subsequences are 8 | * not required to occupy consecutive positions within the original sequences. 9 | * 10 | * The solution uses dynamic-programming. 11 | * @url https://en.wikipedia.org/wiki/Dynamic_programming 12 | */ 13 | 14 | /** 15 | * Return the table of common subsequences lengths. See the snapshot in 16 | * `__snapshots` to have a visual rappresentation. 17 | * Time complexity: O(seqA.length * seqB.length) 18 | * @param seqA First sequence 19 | * @param seqB Second sequence 20 | */ 21 | export function lcsLengths(seqA: string, seqB: string): number[][] { 22 | const lengthA = seqA.length; 23 | const lengthB = seqB.length; 24 | 25 | const lengths: number[][] = new Array(lengthA + 1); 26 | fill(lengths, () => new Array(lengthB + 1)); 27 | 28 | range(0, lengthA).forEach(i => (lengths[i][0] = 0)); 29 | range(0, lengthB).forEach(i => (lengths[0][i] = 0)); 30 | 31 | range(0, lengthA - 1).forEach(indexA => { 32 | range(0, lengthB - 1).forEach(indexB => { 33 | const charA = seqA[indexA]; 34 | const charB = seqB[indexB]; 35 | 36 | if (charA === charB) { 37 | lengths[indexA + 1][indexB + 1] = lengths[indexA][indexB] + 1; 38 | } else { 39 | const subSeqALength = lengths[indexA][indexB + 1]; 40 | const subSeqBLength = lengths[indexA + 1][indexB]; 41 | lengths[indexA + 1][indexB + 1] = Math.max(subSeqALength, subSeqBLength); 42 | } 43 | }); 44 | }); 45 | 46 | return lengths; 47 | } 48 | 49 | /** 50 | * Return the LCS of two sequences using the table of lengths 51 | * Time complexity: O(seqA.length + seqB.length) 52 | * @param lengths The table of common subsequences lengths returned by `lcsLengths` 53 | * @param seqA First sequence 54 | * @param seqB Second sequence 55 | * @param indexA seqA index in the reverse LCS walk 56 | * @param indexB seqB index in the reverse LCS walk 57 | */ 58 | function walkLCS( 59 | lengths: number[][], 60 | seqA: string, 61 | seqB: string, 62 | indexA: number, 63 | indexB: number 64 | ): string { 65 | if (indexA === 0 || indexB === 0) return ''; 66 | 67 | if (seqA[indexA - 1] === seqB[indexB - 1]) { 68 | const subLCS = walkLCS(lengths, seqA, seqB, indexA - 1, indexB - 1); 69 | return subLCS + seqA[indexA - 1]; 70 | } else if (lengths[indexA - 1][indexB] >= lengths[indexA][indexB - 1]) { 71 | return walkLCS(lengths, seqA, seqB, indexA - 1, indexB); 72 | } else { 73 | return walkLCS(lengths, seqA, seqB, indexA, indexB - 1); 74 | } 75 | } 76 | 77 | /** 78 | * Return the longest common subsequence (LCS) 79 | * Time complexity: O(seqA.length * seqB.length) 80 | * @param seqA First sequence 81 | * @param seqB Second sequence 82 | */ 83 | export function findLCS(seqA: string, seqB: string): string { 84 | const lengths = lcsLengths(seqA, seqB); 85 | const lcs = walkLCS(lengths, seqA, seqB, seqA.length, seqB.length); 86 | 87 | return lcs; 88 | } 89 | -------------------------------------------------------------------------------- /algorithms/misc/maximum-subarray/maximum-subarray.spec.ts: -------------------------------------------------------------------------------- 1 | import { maxCrossSubarray, maxSubarray } from './maximum-subarray'; 2 | 3 | describe('maxCrossSubarray', () => { 4 | it('should find the maximum cross-subarray', () => { 5 | const input = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]; 6 | const result = maxCrossSubarray(input, 0, 9, input.length - 1); 7 | 8 | expect(result).toEqual({ 9 | start: 7, 10 | end: 10, 11 | sum: 43, 12 | }); 13 | }); 14 | }); 15 | 16 | describe('maxSubarray', () => { 17 | it('should find the maximum subarray', () => { 18 | const input = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]; 19 | const result = maxSubarray(input, 0, input.length - 1); 20 | 21 | expect(result).toEqual({ 22 | start: 7, 23 | end: 10, 24 | sum: 43, 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /algorithms/misc/maximum-subarray/maximum-subarray.ts: -------------------------------------------------------------------------------- 1 | import { range, reverseRange } from '../../utils'; 2 | 3 | /** 4 | * Find the best maximum subarray crossing the mid 5 | * Time complexity: O(n) 6 | * @param input The input array 7 | * @param start Start of the first array 8 | * @param mid End of first array 9 | * @param end End of second array 10 | */ 11 | export function maxCrossSubarray( 12 | input: number[], 13 | start: number, 14 | mid: number, 15 | end: number 16 | ): { start: number; end: number; sum: number } { 17 | let leftIndex = -1; 18 | let leftMaxSum = -Infinity; 19 | let sum = 0; 20 | 21 | reverseRange(mid, start).forEach(index => { 22 | sum += input[index]; 23 | if (sum > leftMaxSum) { 24 | leftMaxSum = sum; 25 | leftIndex = index; 26 | } 27 | }); 28 | 29 | let rightIndex = -1; 30 | let rightMaxSum = -Infinity; 31 | sum = 0; 32 | range(mid + 1, end).forEach(index => { 33 | sum += input[index]; 34 | if (sum > rightMaxSum) { 35 | rightMaxSum = sum; 36 | rightIndex = index; 37 | } 38 | }); 39 | 40 | return { 41 | start: leftIndex, 42 | end: rightIndex, 43 | sum: leftMaxSum + rightMaxSum, 44 | }; 45 | } 46 | 47 | /** 48 | * Returns the contiguous subarray within an array of numbers which has the largest 49 | * sum. 50 | * Time complexity: O(n*lg(n)). 51 | * @NOTE: there is also solution with O(n) time complexity. 52 | * @param input The input array 53 | * @param start Left side of the subarray 54 | * @param end Right side of the subarray 55 | */ 56 | export function maxSubarray( 57 | input: number[], 58 | start: number, 59 | end: number 60 | ): { start: number; end: number; sum: number } { 61 | if (end - start === 0) return { start, end, sum: input[start] }; 62 | 63 | const mid = Math.floor((start + end) / 2); 64 | const leftMax = maxSubarray(input, start, mid); 65 | const rightMax = maxSubarray(input, mid + 1, end); 66 | const crossMax = maxCrossSubarray(input, start, mid, end); 67 | 68 | if (leftMax.sum >= rightMax.sum && leftMax.sum >= crossMax.sum) { 69 | return leftMax; 70 | } else if (rightMax.sum >= leftMax.sum && rightMax.sum >= crossMax.sum) { 71 | return rightMax; 72 | } else { 73 | return crossMax; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /algorithms/misc/priority-queue/priority-queue.spec.ts: -------------------------------------------------------------------------------- 1 | import { extractMax, increasePriority, insert } from './priority-queue'; 2 | 3 | describe('extractMax', () => { 4 | it('should extract the maximum priority from the queue', () => { 5 | const queue = [5, 2, 4, 0, 1, 3]; 6 | const max = extractMax(queue); 7 | 8 | expect(max).toBe(5); 9 | expect(queue).toEqual([4, 2, 3, 0, 1]); 10 | }); 11 | }); 12 | 13 | describe('increasePriority', () => { 14 | it('should increase the priority of an item in the queue', () => { 15 | const queue = [5, 2, 4, 0, 1, 3]; 16 | increasePriority(queue, 2, 2); 17 | 18 | expect(queue).toEqual([6, 2, 5, 0, 1, 3]); 19 | }); 20 | }); 21 | 22 | describe('insert', () => { 23 | it('should allow creation of a queue', () => { 24 | const queue = []; 25 | insert(queue, 5); 26 | insert(queue, 2); 27 | insert(queue, 4); 28 | insert(queue, 0); 29 | insert(queue, 1); 30 | insert(queue, 3); 31 | 32 | expect(queue).toEqual([5, 2, 4, 0, 1, 3]); 33 | }); 34 | 35 | it('should add a priority in the queue', () => { 36 | const queue = [5, 2, 4, 0, 1, 3]; 37 | insert(queue, 6); 38 | 39 | expect(queue).toEqual([6, 2, 5, 0, 1, 3, 4]); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /algorithms/misc/priority-queue/priority-queue.ts: -------------------------------------------------------------------------------- 1 | import head from 'lodash/head'; 2 | import last from 'lodash/last'; 3 | import { parent, maxHeapify } from '../../sort/heap-sort/heap-sort'; 4 | import { setHead, swap } from '../../utils'; 5 | 6 | /** 7 | * A priority queue implementation based on max-heap. Time complexity of every operation 8 | * is O(lg(n)) at most. 9 | */ 10 | 11 | /** 12 | * Return the maximum priority of the queue 13 | * Time complexity: O(1) 14 | * @param queue Max-heap queue 15 | */ 16 | export function maximum(queue: number[]): number { 17 | return head(queue); 18 | } 19 | 20 | /** 21 | * Extract and return the maximum priority of the queue 22 | * Time complexity: O(lg(n)) 23 | * @param queue Max-heap queue 24 | */ 25 | export function extractMax(queue: number[]): number { 26 | const max = maximum(queue); 27 | 28 | setHead(queue, last(queue)); 29 | queue.pop(); 30 | maxHeapify(queue, 0, queue.length); 31 | 32 | return max; 33 | } 34 | 35 | /** 36 | * Return whether the parent follows the max-heap rule 37 | * Time complexity: O(1) 38 | */ 39 | function isParentInvalid(queue: number[], index: number): boolean { 40 | return queue[parent(index)] < queue[index]; 41 | } 42 | 43 | /** 44 | * Increase the priority of an item in the queue 45 | * Time complexity: O(lg(n)) 46 | * @param queue Max-heap queue 47 | * @param index Index of the priority to increase 48 | * @param increase Increase amount 49 | */ 50 | export function increasePriority(queue: number[], index: number, increase: number): number[] { 51 | queue[index] += increase; 52 | 53 | // Ensure the queue is still a valid max-heap from the index to the root 54 | let validHeapIndex = index; 55 | while (isParentInvalid(queue, validHeapIndex) && validHeapIndex !== 0) { 56 | swap(queue, validHeapIndex, parent(validHeapIndex)); 57 | validHeapIndex = parent(validHeapIndex); 58 | } 59 | 60 | return queue; 61 | } 62 | 63 | /** 64 | * Add a new priority in the queue 65 | * Time complexity: O(lg(n)) 66 | * @param queue Max-heap queue 67 | * @param value New priority to add 68 | */ 69 | export function insert(queue: number[], value: number): number[] { 70 | queue.push(0); 71 | increasePriority(queue, queue.length - 1, value); 72 | 73 | return queue; 74 | } 75 | -------------------------------------------------------------------------------- /algorithms/misc/rod-cutting/rod-cutting.spec.ts: -------------------------------------------------------------------------------- 1 | import { topDownCutRod, bottomUpCutRod, cutRod } from './rod-cutting'; 2 | 3 | describe('topDownCutRod', () => { 4 | it('should return the maximum prices for a rod of given length', () => { 5 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 6 | 7 | const { bestPrices } = topDownCutRod(prices, 4); 8 | 9 | expect(bestPrices[4]).toBe(10); 10 | expect(bestPrices[3]).toBe(8); 11 | expect(bestPrices[2]).toBe(5); 12 | expect(bestPrices[1]).toBe(1); 13 | expect(bestPrices[0]).toBe(0); 14 | }); 15 | 16 | it('should consider the result with no cut at all', () => { 17 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 18 | 19 | expect(topDownCutRod(prices, 10).bestPrices[10]).toBe(30); 20 | }); 21 | }); 22 | 23 | describe('bottomUpCutRod', () => { 24 | it('should return the maximum prices for a rod of given length', () => { 25 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 26 | 27 | const { bestPrices } = bottomUpCutRod(prices, 4); 28 | 29 | expect(bestPrices[4]).toBe(10); 30 | expect(bestPrices[3]).toBe(8); 31 | expect(bestPrices[2]).toBe(5); 32 | expect(bestPrices[1]).toBe(1); 33 | expect(bestPrices[0]).toBe(0); 34 | }); 35 | 36 | it('should consider the result with no cut at all', () => { 37 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 38 | 39 | expect(bottomUpCutRod(prices, 10).bestPrices[10]).toBe(30); 40 | }); 41 | }); 42 | 43 | describe('cutRod', () => { 44 | it('should return the best cuts length for a rod of given length', () => { 45 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 46 | const bestCuts = cutRod(prices, 7); 47 | 48 | expect(bestCuts).toEqual([1, 6]); 49 | }); 50 | 51 | it('should return the same result despite the chosen strategy', () => { 52 | const prices = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]; 53 | const bottomUp = cutRod(prices, 7, 'bottomUp'); 54 | const topDown = cutRod(prices, 7, 'topDown'); 55 | 56 | expect(bottomUp).toEqual(topDown); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /algorithms/misc/rod-cutting/rod-cutting.ts: -------------------------------------------------------------------------------- 1 | import { range } from '../../utils'; 2 | 3 | /** 4 | * Problem: Find the best way to cut a rod of length n, assuming that each length 5 | * has a price. 6 | * 7 | * Find best set of cuts to get maximum price. Each cut is integer length and can 8 | * use any number of cuts, from 0 to n−1. 9 | * 10 | * The solution uses dynamic-programming and both strategies (top-down & bottom-up) 11 | * are provided. 12 | * @url https://en.wikipedia.org/wiki/Dynamic_programming 13 | */ 14 | 15 | export interface BestResults { 16 | bestPrices: number[]; 17 | bestFirstCuts: number[]; 18 | } 19 | 20 | // 21 | // ─── TOP-DOWN MEMOIZED SOLUTION ────────────────────────────────────────────────── 22 | // 23 | 24 | /** 25 | * Return the maximum prices and best first cuts up to then given rod length 26 | * Time complexity: O(n^2). It has worse constants than the following `bottomUpCutRod` 27 | * but it's more elegant and it's recursive. 28 | * @param prices List of prices for each rod length 29 | * @param length Length of the full rod 30 | */ 31 | export function topDownCutRod(prices: number[], length: number): BestResults { 32 | const bestPrices: number[] = new Array(length + 1); 33 | bestPrices.fill(-Infinity); 34 | 35 | const bestFirstCuts: number[] = new Array(length + 1); 36 | 37 | return topDownCutRodAux(prices, length, bestPrices, bestFirstCuts); 38 | } 39 | 40 | function topDownCutRodAux( 41 | prices: number[], 42 | length: number, 43 | bestPrices: number[], 44 | bestFirstCuts: number[] 45 | ): BestResults { 46 | if (bestPrices[length] >= 0) return { bestPrices, bestFirstCuts }; 47 | 48 | let maxCutPrice = -Infinity; 49 | let bestFirstCut: number = -1; 50 | 51 | if (length === 0) maxCutPrice = 0; 52 | else { 53 | range(1, length).forEach(firstCut => { 54 | const remainingRod = topDownCutRodAux(prices, length - firstCut, bestPrices, bestFirstCuts); 55 | const cutPrice = prices[firstCut] + remainingRod.bestPrices[length - firstCut]; 56 | 57 | if (cutPrice > maxCutPrice) { 58 | maxCutPrice = cutPrice; 59 | bestFirstCut = firstCut; 60 | } 61 | }); 62 | } 63 | 64 | bestPrices[length] = maxCutPrice; 65 | bestFirstCuts[length] = bestFirstCut; 66 | 67 | return { 68 | bestPrices, 69 | bestFirstCuts, 70 | }; 71 | } 72 | 73 | // 74 | // ─── BOTTOM-UP MEMOIZED SOLUTION ───────────────────────────────────────────────── 75 | // 76 | 77 | /** 78 | * Return the maximum prices and best first cuts up to then given rod length 79 | * Time complexity: O(n^2) but has better constants than memoizedCutRod, which is 80 | * recursive. 81 | * @param prices List of prices for each rod length 82 | * @param length Length of the full rod 83 | */ 84 | export function bottomUpCutRod(prices: number[], length: number): BestResults { 85 | const bestPrices: number[] = new Array(length + 1); 86 | const bestFirstCuts: number[] = new Array(length + 1); 87 | 88 | bestPrices.fill(-Infinity); 89 | // The price of rod of length 0 is 0 90 | bestPrices[0] = 0; 91 | 92 | range(1, length).forEach(subLength => { 93 | let maxCutPrice = -Infinity; 94 | 95 | range(1, subLength).forEach(firstCut => { 96 | const cutPrice = prices[firstCut] + bestPrices[subLength - firstCut]; 97 | if (cutPrice > maxCutPrice) { 98 | maxCutPrice = cutPrice; 99 | 100 | bestPrices[subLength] = maxCutPrice; 101 | bestFirstCuts[subLength] = firstCut; 102 | } 103 | }); 104 | }); 105 | 106 | return { 107 | bestPrices, 108 | bestFirstCuts, 109 | }; 110 | } 111 | 112 | /** 113 | * Return best cuts lengths for a rod of given length 114 | * Time complexity: O(n^2). It has better constants than memoizedCutRod, which is 115 | * recursive. 116 | * @param prices List of prices for each rod length 117 | * @param length Length of the full rod 118 | * @param strategy Whether to use 'bottomUp' or 'topDown' strategy. Usually the 119 | * former is better. 120 | */ 121 | export function cutRod( 122 | prices: number[], 123 | length: number, 124 | strategy: 'bottomUp' | 'topDown' = 'bottomUp' 125 | ): number[] { 126 | const { bestFirstCuts } = 127 | strategy === 'bottomUp' ? bottomUpCutRod(prices, length) : topDownCutRod(prices, length); 128 | 129 | let remainingRod = length; 130 | const bestCuts: number[] = []; 131 | 132 | while (remainingRod) { 133 | bestCuts.push(bestFirstCuts[remainingRod]); 134 | remainingRod -= bestFirstCuts[remainingRod]; 135 | } 136 | 137 | return bestCuts; 138 | } 139 | -------------------------------------------------------------------------------- /algorithms/search/binary-search-tree/__snapshots__/binary-search-tree.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`BST insertion 1`] = ` 4 | │ ┌── 19 5 | │ ┌── 18 6 | │ │ │ ┌── 17 7 | │ │ └── 15 8 | │ │ └── 13 9 | └── 12 10 | │ ┌── 9 11 | └── 5 12 | └── 2 13 | 14 | `; 15 | 16 | exports[`createBST 1`] = ` 17 | │ ┌── 20 18 | │ ┌── 18 19 | │ │ └── 17 20 | └── 15 21 | │ ┌── 13 22 | │ │ └── 9 23 | │ ┌── 7 24 | └── 6 25 | │ ┌── 4 26 | └── 3 27 | └── 2 28 | 29 | `; 30 | -------------------------------------------------------------------------------- /algorithms/search/binary-search-tree/binary-search-tree.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Node, 3 | Tree, 4 | createNode, 5 | inOrderWalk, 6 | search, 7 | minimum, 8 | maximum, 9 | successor, 10 | predecessor, 11 | insert, 12 | transplant, 13 | remove, 14 | } from './binary-search-tree'; 15 | 16 | /** 17 | * Create a BST for testing. The visual rappresentation is in the __snapshots__ 18 | * folder. 19 | */ 20 | function createBST(): Node { 21 | return createNode( 22 | 15, 23 | createNode( 24 | 6, 25 | createNode(3, createNode(2), createNode(4)), 26 | createNode(7, null, createNode(13, createNode(9))) 27 | ), 28 | createNode(18, createNode(17), createNode(20)) 29 | ); 30 | } 31 | 32 | describe('createBST', () => { 33 | it('should create a correct BST', () => { 34 | expect(createBST()).toMatchSnapshot('createBST'); 35 | }); 36 | }); 37 | 38 | describe('search', () => { 39 | it('should find the node with a given key', () => { 40 | const tree = createBST(); 41 | const node = search(tree, 3); 42 | 43 | expect(node.key).toBe(3); 44 | expect(node.left.key).toBe(2); 45 | expect(node.right.key).toBe(4); 46 | }); 47 | }); 48 | 49 | describe('minimum', () => { 50 | it('should find the node with minimum key', () => { 51 | const tree = createBST(); 52 | const minimumNode = minimum(tree); 53 | 54 | expect(minimumNode.key).toBe(2); 55 | }); 56 | }); 57 | 58 | describe('maximum', () => { 59 | it('should find the node with maximum key', () => { 60 | const tree = createBST(); 61 | const maximumNode = maximum(tree); 62 | 63 | expect(maximumNode.key).toBe(20); 64 | }); 65 | }); 66 | 67 | describe('successor', () => { 68 | it('should find the successor node on right if available', () => { 69 | const tree = createBST(); 70 | const successorNode = successor(tree); 71 | 72 | expect(successorNode.key).toBe(17); 73 | }); 74 | 75 | it('should find the ancestor successor node if not available on right', () => { 76 | const tree = createBST(); 77 | const node13 = search(tree, 13); 78 | const successorNode = successor(node13); 79 | 80 | expect(successorNode.key).toBe(15); 81 | }); 82 | }); 83 | 84 | describe('predecessor', () => { 85 | it('should find the predecessor node on left if available', () => { 86 | const tree = createBST(); 87 | const predecessorNode = predecessor(tree); 88 | 89 | expect(predecessorNode.key).toBe(6); 90 | }); 91 | 92 | it('should find the ancestor predecessor node if not available on left', () => { 93 | const tree = createBST(); 94 | const node9 = search(tree, 9); 95 | const predecessorNode = predecessor(node9); 96 | 97 | expect(predecessorNode.key).toBe(7); 98 | }); 99 | }); 100 | 101 | describe('insert', () => { 102 | it('should insert a node', () => { 103 | const tree: Tree = { root: createNode(3) }; 104 | const leaf = createNode(2); 105 | insert(tree, leaf); 106 | 107 | expect(tree.root.left.key).toBe(2); 108 | expect(leaf.parent).toEqual(tree.root); 109 | }); 110 | 111 | it('should insert a node if the tree is empty', () => { 112 | const tree: Tree = { root: null }; 113 | const leaf = createNode(2); 114 | insert(tree, leaf); 115 | 116 | expect(tree.root).toEqual(tree.root); 117 | expect(leaf.parent).toBe(null); 118 | }); 119 | 120 | it('should allow creation of a Binary Search Tree', () => { 121 | const tree: Tree = { root: null }; 122 | insert(tree, createNode(12)); 123 | insert(tree, createNode(5)); 124 | insert(tree, createNode(2)); 125 | insert(tree, createNode(9)); 126 | insert(tree, createNode(18)); 127 | insert(tree, createNode(15)); 128 | insert(tree, createNode(13)); 129 | insert(tree, createNode(17)); 130 | insert(tree, createNode(19)); 131 | 132 | expect(tree.root).toMatchSnapshot('BST insertion'); 133 | }); 134 | }); 135 | 136 | describe('remove', () => { 137 | it('should have a working transplant utility', () => { 138 | const tree: Tree = { 139 | root: createBST(), 140 | }; 141 | const node20 = tree.root.right.right; 142 | const replacement = createNode(21); 143 | transplant(tree, node20, replacement); 144 | 145 | expect(tree.root.right.right.key).toBe(21); 146 | expect(tree.root.right.right.parent.key).toBe(18); 147 | }); 148 | 149 | it('should remove a leaf from the BST', () => { 150 | const tree: Tree = { 151 | root: createBST(), 152 | }; 153 | const node20 = tree.root.right.right; 154 | remove(tree, node20); 155 | 156 | expect(tree.root.right.right).toBe(null); 157 | }); 158 | 159 | it('should remove an internal node from the BST and replace with the right child', () => { 160 | const tree: Tree = { 161 | root: createBST(), 162 | }; 163 | const node18 = tree.root.right; 164 | remove(tree, node18); 165 | 166 | expect(tree.root.right.key).toBe(20); 167 | }); 168 | 169 | it('should remove an internal node from the BST and replace with the minimum right child', () => { 170 | const tree: Tree = { 171 | root: createBST(), 172 | }; 173 | remove(tree, tree.root); 174 | 175 | expect(tree.root.key).toBe(17); 176 | expect(tree.root.right.left).toBe(null); 177 | }); 178 | }); 179 | -------------------------------------------------------------------------------- /algorithms/search/binary-search-tree/binary-search-tree.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Binary Search Tree (BST) implementation 3 | */ 4 | 5 | export interface Node { 6 | parent?: Node; 7 | key: number; 8 | left?: Node; 9 | right?: Node; 10 | } 11 | 12 | export interface Tree { 13 | root: Node; 14 | } 15 | 16 | /** 17 | * Create a tree node. Used to build a tree in tests. 18 | */ 19 | export function createNode(key: number, left: Node = null, right: Node = null): Node { 20 | const node = { 21 | key, 22 | left, 23 | right, 24 | parent: null, 25 | }; 26 | 27 | if (left) left.parent = node; 28 | if (right) right.parent = node; 29 | 30 | return node; 31 | } 32 | 33 | /** 34 | * Print a BST in order. 35 | * Time complexity: O(n) 36 | */ 37 | export function inOrderWalk(node: Node) { 38 | if (!node) return; 39 | 40 | inOrderWalk(node.left); 41 | console.log(node); 42 | inOrderWalk(node.right); 43 | } 44 | 45 | /** 46 | * Search a key in the BST 47 | * Time complexity: O(lg(n)) 48 | * @param node BST root node 49 | * @param key Key to look for 50 | */ 51 | export function search(node: Node, key: number): Node { 52 | if (!node) return null; 53 | 54 | if (node.key === key) return node; 55 | else if (node.key < key) return search(node.right, key); 56 | else return search(node.left, key); 57 | } 58 | 59 | /** 60 | * Return the minimum key of the BST 61 | * Time complexity: O(lg(n)) 62 | * @param node BST root node 63 | */ 64 | export function minimum(node: Node): Node { 65 | let leftMost: Node = node; 66 | while (leftMost !== null && leftMost.left !== null) { 67 | leftMost = leftMost.left; 68 | } 69 | 70 | return leftMost; 71 | } 72 | 73 | /** 74 | * Return the maximum key of the BST 75 | * Time complexity: O(lg(n)) 76 | * @param node BST root node 77 | */ 78 | export function maximum(node: Node): Node { 79 | let rightMost: Node = node; 80 | while (rightMost !== null && rightMost.right !== null) { 81 | rightMost = rightMost.right; 82 | } 83 | 84 | return rightMost; 85 | } 86 | 87 | /** 88 | * Return the successor node in a in-order walk 89 | * Time complexity: O(lg(n)) 90 | * @param node BST root node 91 | */ 92 | export function successor(node: Node): Node { 93 | if (node.right !== null) return minimum(node.right); 94 | 95 | let parent = node.parent; 96 | let current = node; 97 | while (parent !== null && parent.right === current) { 98 | current = parent; 99 | parent = parent.parent; 100 | } 101 | 102 | return parent; 103 | } 104 | 105 | /** 106 | * Return the predessor node in a in-order walk 107 | * Time complexity: O(lg(n)) 108 | * @param node BST root node 109 | */ 110 | export function predecessor(node: Node): Node { 111 | if (node.left !== null) return node.left; 112 | 113 | let parent = node.parent; 114 | let current = node; 115 | while (parent !== null && parent.left === current) { 116 | current = parent; 117 | parent = parent.parent; 118 | } 119 | 120 | return parent; 121 | } 122 | 123 | /** 124 | * Insert a leaf node in a BST 125 | * Time complexity: O(lg(n)) 126 | * @param tree BST tree 127 | * @param leaf New leaf node to add 128 | */ 129 | export function insert(tree: Tree, leaf: Node) { 130 | let parent: Node = null; 131 | let current = tree.root; 132 | 133 | while (current !== null) { 134 | parent = current; 135 | 136 | if (leaf.key >= current.key) { 137 | current = current.right; 138 | } else { 139 | current = current.left; 140 | } 141 | } 142 | 143 | if (parent === null) tree.root = leaf; 144 | else if (leaf.key >= parent.key) parent.right = leaf; 145 | else parent.left = leaf; 146 | 147 | leaf.parent = parent; 148 | } 149 | 150 | /** 151 | * Replace a node with a new one in a BST 152 | * @NOTE: it does not update the childs nor does it check if the BST is still 153 | * valid. 154 | * Time complexity: O(1) 155 | * @param tree BST root node 156 | * @param oldNode Node to be replaced. It cannot be null. 157 | * @param newNode Replacement node 158 | */ 159 | export function transplant(tree: Tree, oldNode: Node, newNode: Node) { 160 | if (oldNode.parent === null) tree.root = newNode; 161 | else if (oldNode.parent.left === oldNode) oldNode.parent.left = newNode; 162 | else oldNode.parent.right = newNode; 163 | 164 | if (newNode !== null) newNode.parent = oldNode.parent; 165 | } 166 | 167 | /** 168 | * Remove a node from a BST. 169 | * Time complexity: O(lg(n)) 170 | * @param tree BST root node 171 | * @param removed Node to be removed 172 | */ 173 | export function remove(tree: Tree, removed: Node) { 174 | if (removed.left === null) transplant(tree, removed, removed.right); 175 | else if (removed.right === null) transplant(tree, removed, removed.left); 176 | else { 177 | const minRight = minimum(removed.right); 178 | 179 | if (minRight.parent !== removed) { 180 | transplant(tree, minRight, minRight.right); 181 | // Attach the removed node right subtree to minRight 182 | minRight.right = removed.right; 183 | minRight.right.parent = minRight; 184 | } 185 | 186 | transplant(tree, removed, minRight); 187 | // Attach the removed node left subtree to minRight 188 | minRight.left = removed.left; 189 | minRight.left.parent = minRight; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.spec.ts: -------------------------------------------------------------------------------- 1 | import { binarySearch } from './binary-search'; 2 | 3 | describe('binarySearch', () => { 4 | it('should find the index of the value', () => { 5 | const input = [1, 2, 3, 4, 5, 6]; 6 | const right = binarySearch(input, 5, 0, input.length - 1); 7 | const left = binarySearch(input, 2, 0, input.length - 1); 8 | 9 | expect(right).toEqual(4); 10 | expect(left).toEqual(1); 11 | }); 12 | 13 | it('should find the index of the value at the edges', () => { 14 | const input = [1, 2, 3, 4, 5, 6]; 15 | const right = binarySearch(input, 6, 0, input.length - 1); 16 | const left = binarySearch(input, 1, 0, input.length - 1); 17 | 18 | expect(right).toEqual(5); 19 | expect(left).toEqual(0); 20 | }); 21 | 22 | it('should return NULL if the value is not present', () => { 23 | const input = [1, 2, 3, 4, 5, 6]; 24 | const right = binarySearch(input, 7, 0, input.length - 1); 25 | const left = binarySearch(input, -1, 0, input.length - 1); 26 | 27 | expect(right).toEqual(null); 28 | expect(left).toEqual(null); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Return the index of the value in the input 3 | * Time complexity: O(lg(n)). 4 | * @param input An ordered array where to find the value 5 | * @param value Value to find 6 | * @param start Initial index 7 | * @param end Ending index 8 | */ 9 | export function binarySearch(input: number[], value: number, start: number, end: number): number { 10 | if (start > end || value < input[start] || value > input[end]) return null; 11 | 12 | const mid = Math.floor((end + start) / 2); 13 | if (input[mid] === value) return mid; 14 | else if (input[mid] < value) return binarySearch(input, value, mid + 1, end); 15 | else return binarySearch(input, value, start, mid - 1); 16 | } 17 | -------------------------------------------------------------------------------- /algorithms/sort/counting-sort/counting-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import max from 'lodash/max'; 2 | import { countingSort } from './counting-sort'; 3 | 4 | describe('Counting sort', function() { 5 | test('It should sort the items', function() { 6 | const input = [5, 2, 4, 6, 1, 3]; 7 | const result = countingSort(input, max(input)); 8 | 9 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /algorithms/sort/counting-sort/counting-sort.ts: -------------------------------------------------------------------------------- 1 | import forEachRight from 'lodash/forEachRight'; 2 | import { increaseOfPrevious, range } from '../../utils'; 3 | 4 | /** 5 | * Sort the input with counting sort. 6 | * Time complexity: O(n). 7 | * @param input The array which should be sorted 8 | * @param max The max number between the values 9 | */ 10 | export function countingSort(input: number[], max: number): number[] { 11 | const result = []; 12 | const counter = new Array(max + 1); 13 | counter.fill(0); 14 | 15 | input.forEach(value => (counter[value] += 1)); 16 | 17 | range(1, max).forEach(index => increaseOfPrevious(counter, index)); 18 | 19 | forEachRight(input, value => { 20 | counter[value] -= 1; 21 | 22 | const position = counter[value]; 23 | result[position] = value; 24 | }); 25 | 26 | return result; 27 | } 28 | -------------------------------------------------------------------------------- /algorithms/sort/heap-sort/heap-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import { left, right, maxHeapify, buildMaxHeap, heapSort } from './heap-sort'; 2 | 3 | describe('Utilities', function() { 4 | test('left', function() { 5 | expect(left(0)).toEqual(1); 6 | }); 7 | 8 | test('right', function () { 9 | expect(right(0)).toEqual(2); 10 | }); 11 | }); 12 | 13 | describe('maxHeapify', function() { 14 | test('It should move the item to the right position', function() { 15 | const input = [0, 5, 4, 2, 1, 3]; 16 | const result = maxHeapify(input, 0, input.length); 17 | 18 | expect(result).toEqual([5, 2, 4, 0, 1, 3]); 19 | }); 20 | }); 21 | 22 | describe('buildMaxHeap', function() { 23 | test('It should build a max heap from given input', function() { 24 | const input = [5, 2, 4, 6, 1, 3]; 25 | const result = buildMaxHeap(input); 26 | 27 | expect(result).toEqual([6, 5, 4, 2, 1, 3]); 28 | }); 29 | }); 30 | 31 | describe('Heap sort', function() { 32 | test('It should sort the items', function() { 33 | const input = [5, 2, 4, 6, 1, 3]; 34 | const result = heapSort(input); 35 | 36 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /algorithms/sort/heap-sort/heap-sort.ts: -------------------------------------------------------------------------------- 1 | import { reverseRange } from '../../utils'; 2 | import { swap } from '../../utils'; 3 | 4 | /** 5 | * Return the index of the parent in the heap. 6 | * Time complexity: O(1) 7 | * @param index Index of the current node 8 | */ 9 | export function parent(index: number): number { 10 | return Math.floor((index - 1) / 2); 11 | } 12 | 13 | /** 14 | * Return the index of the left child in the heap. 15 | * Time complexity: O(1) 16 | * @param index Index of the current node 17 | */ 18 | export function left(index: number): number { 19 | return 2 * index + 1; 20 | } 21 | 22 | /** 23 | * Return the index of the right child in the heap. 24 | * Time complexity: O(1) 25 | * @param index Index of the current node 26 | */ 27 | export function right(index: number): number { 28 | return 2 * (index + 1); 29 | } 30 | 31 | function isInHeap(index: number, heapSize: number): boolean { 32 | return index < heapSize; 33 | } 34 | 35 | /** 36 | * Place the element in the right position of the max-heap. It assumes child nodes 37 | * are valid heaps. 38 | * Time complexity: O(lg(n)) 39 | * @param input Array rappresented by the heap 40 | * @param index Index of the element to place 41 | * @param heapSize Size of the heap 42 | */ 43 | export function maxHeapify(input: number[], index: number, heapSize: number): number[] { 44 | const leftChild = left(index); 45 | const rightChild = right(index); 46 | let maxIndex = index; 47 | 48 | if (isInHeap(leftChild, heapSize) && input[leftChild] > input[index]) { 49 | maxIndex = leftChild; 50 | } 51 | 52 | if (isInHeap(rightChild, heapSize) && input[rightChild] > input[maxIndex]) { 53 | maxIndex = rightChild; 54 | } 55 | 56 | if (maxIndex !== index) { 57 | swap(input, index, maxIndex); 58 | // Repeat max-heap check for the subtree 59 | maxHeapify(input, maxIndex, heapSize); 60 | } 61 | 62 | return input; 63 | } 64 | 65 | /** 66 | * Build max-heap from input. 67 | * Time complexity: O(n) 68 | * @param input Array to build the max-heap from 69 | */ 70 | export function buildMaxHeap(input: number[]): number[] { 71 | // All nodes from (input.length / 2) + 1 are leaves 72 | const firstLeaf = Math.floor((input.length - 1) / 2); 73 | 74 | reverseRange(firstLeaf).forEach(index => { 75 | maxHeapify(input, index, input.length); 76 | }); 77 | 78 | return input; 79 | } 80 | 81 | /** 82 | * Sort the input with heap sort. 83 | * Time complexity: O(n * lg(n)). 84 | * @param input The array which should bo sorted 85 | */ 86 | export function heapSort(input: number[]): number[] { 87 | buildMaxHeap(input); 88 | 89 | reverseRange(input.length - 1).forEach(heapEnd => { 90 | swap(input, 0, heapEnd); 91 | maxHeapify(input, 0, heapEnd); 92 | }); 93 | 94 | return input; 95 | } 96 | -------------------------------------------------------------------------------- /algorithms/sort/insertion-sort/insertion-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import { insertionSort } from './insertion-sort'; 2 | 3 | describe('Insertion sort', function() { 4 | test('It should sort the items', function() { 5 | const input = [5, 2, 4, 6, 1, 3]; 6 | const result = insertionSort(input); 7 | 8 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /algorithms/sort/insertion-sort/insertion-sort.ts: -------------------------------------------------------------------------------- 1 | import { moveRight } from '../../utils'; 2 | 3 | /** 4 | * Sort the array with insertion sort. 5 | * Time complexity: O(n^2). 6 | * @param input The array which should be sorted 7 | */ 8 | export function insertionSort(input: number[]): number[] { 9 | input.forEach((pivot, pivotIndex) => { 10 | let compareIndex = pivotIndex - 1; 11 | 12 | while (compareIndex > -1 && input[compareIndex] > pivot) { 13 | moveRight(input, compareIndex); 14 | compareIndex -= 1; 15 | } 16 | 17 | input[compareIndex + 1] = pivot; 18 | }); 19 | 20 | return input; 21 | } 22 | -------------------------------------------------------------------------------- /algorithms/sort/merge-and-insertion-sort/merge-and-insertion-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import { mergeAndInsertionSort } from './merge-and-insertion-sort'; 2 | 3 | describe('Insertion sort', function() { 4 | test('It should sort the items', function() { 5 | const input = [5, 2, 4, 6, 1, 3]; 6 | const result = mergeAndInsertionSort(input); 7 | 8 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /algorithms/sort/merge-and-insertion-sort/merge-and-insertion-sort.ts: -------------------------------------------------------------------------------- 1 | import { insertionSort } from '../insertion-sort/insertion-sort'; 2 | import { merge } from '../merge-sort/merge-sort'; 3 | 4 | /** 5 | * Sort the array with a combination of merge and insertion sort. 6 | * 7 | * Reason: 8 | * @url https://stackoverflow.com/questions/736920/is-there-ever-a-good-reason-to-use-insertion-sort 9 | * 10 | * Although it is one of the elementary sorting algorithms with O(n2) worst-case 11 | * time, insertion sort is the algorithm of choice either when the data is nearly 12 | * sorted (because it is adaptive) or when the problem size is small (because it 13 | * has low overhead). 14 | * 15 | * For these reasons, and because it is also stable, insertion sort is often used 16 | * as the recursive base case (when the problem size is small) for higher overhead 17 | * divide-and-conquer sorting algorithms, such as merge sort or quick sort. 18 | * Time complexity: O(n*lg(n/k)). 19 | * @param input The array which should be sorted 20 | * @param start Left side of the subarray 21 | * @param end Right side of the subarray, not included 22 | * @param threshold Threshold below each sorting is better with insertion sort 23 | */ 24 | export function mergeAndInsertionSort( 25 | input: number[], 26 | start = 0, 27 | end = input.length, 28 | threshold = 10 29 | ): number[] { 30 | if (end - start <= 1) return []; 31 | 32 | if (end - start <= threshold) return insertionSort(input); 33 | 34 | // Continue classic merge-sort otherwise 35 | const mid = Math.floor((start + end) / 2); 36 | 37 | mergeAndInsertionSort(input, start, mid); 38 | mergeAndInsertionSort(input, mid, end); 39 | 40 | return merge(input, start, mid, end); 41 | } 42 | -------------------------------------------------------------------------------- /algorithms/sort/merge-sort/merge-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import { merge, mergeSort } from './merge-sort'; 2 | 3 | describe('Merge', function() { 4 | test('It should merge the two ordered sub-arrays with final result ordered', function() { 5 | const input = [4, 5, 6, 1, 2, 3]; 6 | const result = merge(input, 0, 3, 6); 7 | 8 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 9 | }); 10 | }); 11 | 12 | describe('Merge sort', function() { 13 | test('It should sort the items', function() { 14 | const input = [5, 2, 4, 6, 1, 3]; 15 | const result = mergeSort(input); 16 | 17 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /algorithms/sort/merge-sort/merge-sort.ts: -------------------------------------------------------------------------------- 1 | import head from 'lodash/head'; 2 | import { range } from '../../utils'; 3 | 4 | /** 5 | * Divide and sort merges two subarrays of given array 6 | * Time complexity: O(n) 7 | * @param input The array which subarrays should be sorted 8 | * @param start Start of the first array 9 | * @param mid End of first array, not included 10 | * @param end End of second array, not including 11 | */ 12 | export function merge(input: number[], start: number, mid: number, end: number) { 13 | // Make a copy of the two subarrays 14 | const left = input.slice(start, mid); 15 | const right = input.slice(mid, end); 16 | 17 | left[left.length] = Infinity as any; 18 | right[right.length] = Infinity as any; 19 | 20 | range(start, end - 1).forEach(index => { 21 | if (head(left) <= head(right)) input[index] = left.shift(); 22 | else input[index] = right.shift(); 23 | }); 24 | 25 | return input; 26 | } 27 | 28 | /** 29 | * Sort the input with merge sort. 30 | * Time complexity: O(n * lg(n)). 31 | * @param input The array which should be sorted 32 | * @param start Left side of the subarray 33 | * @param end Right side of the subarray, not included 34 | */ 35 | export function mergeSort(input: number[], start = 0, end = input.length): number[] { 36 | if (end - start <= 1) return []; 37 | 38 | const mid = Math.floor((start + end) / 2); 39 | 40 | mergeSort(input, start, mid); 41 | mergeSort(input, mid, end); 42 | 43 | return merge(input, start, mid, end); 44 | } 45 | -------------------------------------------------------------------------------- /algorithms/sort/quick-sort/quick-sort.spec.ts: -------------------------------------------------------------------------------- 1 | const last = require('lodash/last'); 2 | import { partition, quickSort } from './quick-sort'; 3 | 4 | describe('Quick sort partition', function() { 5 | test('It should move the pivot to the correct position', function() { 6 | const input = [5, 2, 4, 6, 1, 3]; 7 | const pivotIndex = partition(input, 0, input.length - 1, false); 8 | expect(pivotIndex).toBe(2); 9 | }); 10 | 11 | test('It should move the pivot to the correct position when randomized', function() { 12 | const input = [5, 2, 4, 6, 1, 3]; 13 | const pivotIndex = partition(input, 0, input.length - 1, true); 14 | const pivot = input[pivotIndex]; 15 | input.forEach((value, index) => { 16 | if (index < pivotIndex) expect(value).toBeLessThanOrEqual(pivot); 17 | else if (index > pivotIndex) expect(value).toBeGreaterThan(pivot); 18 | else expect(value).toBe(pivot); 19 | }); 20 | }); 21 | 22 | test('Smaller numbers should be at pivot left', function() { 23 | const input = [5, 2, 4, 6, 1, 3]; 24 | const pivot = last(input); 25 | const pivotIndex = partition(input, 0, input.length - 1, false); 26 | const smaller = input.slice(0, pivotIndex); 27 | smaller.forEach(value => expect(value).toBeLessThanOrEqual(pivot)); 28 | }); 29 | 30 | test('Bigger numbers should be at pivot right', function() { 31 | const input = [5, 2, 4, 6, 1, 3]; 32 | const pivot = last(input); 33 | const pivotIndex = partition(input, 0, input.length - 1, false); 34 | const bigger = input.slice(pivotIndex + 1); 35 | bigger.forEach(value => expect(value).toBeGreaterThan(pivot)); 36 | }); 37 | }); 38 | 39 | describe('Quick sort', function() { 40 | test('It should sort the items', function() { 41 | const input = [5, 2, 4, 6, 1, 3]; 42 | const result = quickSort(input); 43 | 44 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 45 | }); 46 | 47 | test('It should sort the items in randomized mode', function() { 48 | const input = [5, 2, 4, 6, 1, 3]; 49 | const result = quickSort(input, 0, input.length - 1, true); 50 | 51 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /algorithms/sort/quick-sort/quick-sort.ts: -------------------------------------------------------------------------------- 1 | import random from 'lodash/random'; 2 | import { range } from '../../utils'; 3 | import { swap } from '../../utils'; 4 | 5 | /** 6 | * Partition the subarray for the quicksort 7 | * Time complexity: O(n) 8 | * @param input The array which subarrays should be sorted 9 | * @param left The start of the subarray 10 | * @param right The end of the subarray 11 | */ 12 | export function partition( 13 | input: number[], 14 | left: number, 15 | right: number, 16 | randomized: boolean 17 | ): number { 18 | if (randomized) swap(input, random(left, right), right); 19 | 20 | const pivot = input[right]; 21 | 22 | let minEdge = left - 1; 23 | 24 | range(left, right - 1).forEach(current => { 25 | if (input[current] <= pivot) { 26 | minEdge += 1; 27 | swap(input, minEdge, current); 28 | } 29 | }); 30 | 31 | swap(input, minEdge + 1, right); 32 | 33 | return minEdge + 1; 34 | } 35 | 36 | /** 37 | * Sort the input with quick sort. 38 | * Time complexity: O(n * lg(n)). 39 | * @param input The array which should be sorted 40 | * @param start The start of the subarray which should be handled 41 | * @param end The end of the subarray which should be handled 42 | * @param randomized Run the randomized version of quick sort 43 | */ 44 | export function quickSort( 45 | input: number[], 46 | start = 0, 47 | end = input.length - 1, 48 | randomized = false 49 | ): number[] { 50 | if (start >= end) return input; 51 | 52 | const mid = partition(input, start, end, randomized); 53 | quickSort(input, start, mid - 1); 54 | quickSort(input, mid + 1, end); 55 | 56 | return input; 57 | } 58 | -------------------------------------------------------------------------------- /algorithms/sort/selection-sort/selection-sort.spec.ts: -------------------------------------------------------------------------------- 1 | import { selectionSort } from './selection-sort'; 2 | 3 | describe('Insertion sort', function() { 4 | test('It should sort the items', function() { 5 | const input = [5, 2, 4, 6, 1, 3]; 6 | const result = selectionSort(input); 7 | 8 | expect(result).toEqual([1, 2, 3, 4, 5, 6]); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /algorithms/sort/selection-sort/selection-sort.ts: -------------------------------------------------------------------------------- 1 | import { moveRight, range, swap } from '../../utils'; 2 | 3 | /** 4 | * Sort the array with selection sort. 5 | * Time complexity: O(n^2). 6 | * @param input The array which should be sorted 7 | */ 8 | export function selectionSort(input: number[]): number[] { 9 | // The last iteration can be avoided because it will already be the greatest value 10 | range(0, input.length - 2).forEach(pivotIndex => { 11 | let min = input[pivotIndex]; 12 | let minIndex = pivotIndex; 13 | 14 | for (let i = pivotIndex + 1; i < input.length; i++) { 15 | if (input[i] < min) { 16 | min = input[i]; 17 | minIndex = i; 18 | } 19 | } 20 | 21 | swap(input, minIndex, pivotIndex); 22 | }); 23 | 24 | return input; 25 | } 26 | -------------------------------------------------------------------------------- /algorithms/utils.ts: -------------------------------------------------------------------------------- 1 | import baseRange from 'lodash/range'; 2 | import baseRangeRight from 'lodash/rangeRight'; 3 | 4 | export function fill(array: T[], valueFn: (index: number) => any): T[] { 5 | for (let i = 0; i < array.length; i++) array[i] = valueFn(i); 6 | 7 | return array; 8 | } 9 | 10 | export function increaseOfPrevious(array: number[], index: number) { 11 | array[index] += array[index - 1]; 12 | } 13 | 14 | /** 15 | * Move the item at given index to the right 16 | */ 17 | export function moveRight(input, index) { 18 | input[index + 1] = input[index]; 19 | } 20 | 21 | /** 22 | * Creates an array of numbers from start to end, both included. 23 | */ 24 | export function range(from: number, to: number): number[] { 25 | return baseRange(from, to + 1); 26 | } 27 | 28 | /** 29 | * Creates an array of numbers in descending order from start to end, both included. 30 | */ 31 | export function reverseRange(from: number, to: number = 0): number[] { 32 | return baseRangeRight(to, from + 1); 33 | } 34 | 35 | export interface Node { 36 | left: Node; 37 | right: Node; 38 | } 39 | 40 | /** 41 | * Convert a tree to serializable Binary Tree for Jest snapshots 42 | */ 43 | export function toSerializableTree(root: Node, nodeConverter: (node: any) => Node): Node { 44 | if (!root) return; 45 | 46 | toSerializableTree(root.left, nodeConverter); 47 | Object.assign(root, nodeConverter(root)); 48 | toSerializableTree(root.right, nodeConverter); 49 | 50 | return root; 51 | } 52 | 53 | export function setHead(input: number[], value: number): number[] { 54 | input[0] = value; 55 | return input; 56 | } 57 | 58 | /** 59 | * Swap two items in an array 60 | * @param array Input array, whose elements are swapped 61 | * @param from From index 62 | * @param to Destination index 63 | */ 64 | export function swap(input: number[], from: number, to: number): number[] { 65 | const temp = input[from]; 66 | input[from] = input[to]; 67 | input[to] = temp; 68 | 69 | return input; 70 | } 71 | -------------------------------------------------------------------------------- /assets/jest-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayihu/pretty-algorithms/6970a9d8cbf97f4d7b8be3d905fb7e0e137adef8/assets/jest-1.png -------------------------------------------------------------------------------- /assets/jest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayihu/pretty-algorithms/6970a9d8cbf97f4d7b8be3d905fb7e0e137adef8/assets/jest.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pretty-sort", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/jest": { 8 | "version": "19.2.4", 9 | "resolved": "https://registry.npmjs.org/@types/jest/-/jest-19.2.4.tgz", 10 | "integrity": "sha512-w9nmNHHkl9lNeOorjz1a7BLUd6zTa3pakNx2qkKCVtYS44L7taPcJB8l1kQWVOIa7kN08qwlyS11A1nz2yUvWQ==", 11 | "dev": true 12 | }, 13 | "@types/lodash": { 14 | "version": "4.14.71", 15 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.71.tgz", 16 | "integrity": "sha512-x9E8HYuhmcQJPjhTd+t0oRXiQCJXoRPSzCOgYKggxtvNb/kGw8RrbdZzCXrQ6i/i4o0TettxyouY7UdbqkS4AQ==", 17 | "dev": true 18 | }, 19 | "@types/node": { 20 | "version": "7.0.39", 21 | "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.39.tgz", 22 | "integrity": "sha512-KQHAZeVsk4UIT9XaR6cn4WpHZzimK6UBD1UomQKfQQFmTlUHaNBzeuov+TM4+kigLO0IJt4I5OOsshcCyA9gSA==", 23 | "dev": true 24 | }, 25 | "abab": { 26 | "version": "1.0.3", 27 | "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz", 28 | "integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=", 29 | "dev": true 30 | }, 31 | "abbrev": { 32 | "version": "1.0.9", 33 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", 34 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", 35 | "dev": true 36 | }, 37 | "acorn": { 38 | "version": "4.0.13", 39 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", 40 | "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", 41 | "dev": true 42 | }, 43 | "acorn-globals": { 44 | "version": "3.1.0", 45 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", 46 | "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", 47 | "dev": true, 48 | "requires": { 49 | "acorn": "4.0.13" 50 | } 51 | }, 52 | "ajv": { 53 | "version": "4.11.8", 54 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", 55 | "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", 56 | "dev": true, 57 | "requires": { 58 | "co": "4.6.0", 59 | "json-stable-stringify": "1.0.1" 60 | } 61 | }, 62 | "align-text": { 63 | "version": "0.1.4", 64 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 65 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 66 | "dev": true, 67 | "requires": { 68 | "kind-of": "3.2.2", 69 | "longest": "1.0.1", 70 | "repeat-string": "1.6.1" 71 | } 72 | }, 73 | "amdefine": { 74 | "version": "1.0.1", 75 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 76 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 77 | "dev": true 78 | }, 79 | "ansi-escapes": { 80 | "version": "1.4.0", 81 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", 82 | "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", 83 | "dev": true 84 | }, 85 | "ansi-regex": { 86 | "version": "2.1.1", 87 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 88 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 89 | "dev": true 90 | }, 91 | "ansi-styles": { 92 | "version": "2.2.1", 93 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 94 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 95 | "dev": true 96 | }, 97 | "anymatch": { 98 | "version": "1.3.2", 99 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", 100 | "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", 101 | "dev": true, 102 | "requires": { 103 | "micromatch": "2.3.11", 104 | "normalize-path": "2.1.1" 105 | } 106 | }, 107 | "append-transform": { 108 | "version": "0.4.0", 109 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", 110 | "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", 111 | "dev": true, 112 | "requires": { 113 | "default-require-extensions": "1.0.0" 114 | } 115 | }, 116 | "argparse": { 117 | "version": "1.0.9", 118 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", 119 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", 120 | "dev": true, 121 | "requires": { 122 | "sprintf-js": "1.0.3" 123 | } 124 | }, 125 | "arr-diff": { 126 | "version": "2.0.0", 127 | "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", 128 | "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", 129 | "dev": true, 130 | "requires": { 131 | "arr-flatten": "1.1.0" 132 | } 133 | }, 134 | "arr-flatten": { 135 | "version": "1.1.0", 136 | "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", 137 | "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", 138 | "dev": true 139 | }, 140 | "array-differ": { 141 | "version": "1.0.0", 142 | "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", 143 | "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", 144 | "dev": true 145 | }, 146 | "array-equal": { 147 | "version": "1.0.0", 148 | "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", 149 | "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", 150 | "dev": true 151 | }, 152 | "array-find-index": { 153 | "version": "1.0.2", 154 | "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", 155 | "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", 156 | "dev": true 157 | }, 158 | "array-uniq": { 159 | "version": "1.0.3", 160 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 161 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 162 | "dev": true 163 | }, 164 | "array-unique": { 165 | "version": "0.2.1", 166 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", 167 | "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", 168 | "dev": true 169 | }, 170 | "arrify": { 171 | "version": "1.0.1", 172 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 173 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", 174 | "dev": true 175 | }, 176 | "asn1": { 177 | "version": "0.2.3", 178 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 179 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", 180 | "dev": true 181 | }, 182 | "assert-plus": { 183 | "version": "0.2.0", 184 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", 185 | "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", 186 | "dev": true 187 | }, 188 | "async": { 189 | "version": "2.5.0", 190 | "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", 191 | "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", 192 | "dev": true, 193 | "requires": { 194 | "lodash": "4.17.4" 195 | } 196 | }, 197 | "asynckit": { 198 | "version": "0.4.0", 199 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 200 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 201 | "dev": true 202 | }, 203 | "aws-sign2": { 204 | "version": "0.6.0", 205 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", 206 | "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", 207 | "dev": true 208 | }, 209 | "aws4": { 210 | "version": "1.6.0", 211 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 212 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", 213 | "dev": true 214 | }, 215 | "babel-code-frame": { 216 | "version": "6.22.0", 217 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", 218 | "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", 219 | "dev": true, 220 | "requires": { 221 | "chalk": "1.1.3", 222 | "esutils": "2.0.2", 223 | "js-tokens": "3.0.2" 224 | } 225 | }, 226 | "babel-core": { 227 | "version": "6.25.0", 228 | "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", 229 | "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", 230 | "dev": true, 231 | "requires": { 232 | "babel-code-frame": "6.22.0", 233 | "babel-generator": "6.25.0", 234 | "babel-helpers": "6.24.1", 235 | "babel-messages": "6.23.0", 236 | "babel-register": "6.24.1", 237 | "babel-runtime": "6.25.0", 238 | "babel-template": "6.25.0", 239 | "babel-traverse": "6.25.0", 240 | "babel-types": "6.25.0", 241 | "babylon": "6.17.4", 242 | "convert-source-map": "1.5.0", 243 | "debug": "2.6.8", 244 | "json5": "0.5.1", 245 | "lodash": "4.17.4", 246 | "minimatch": "3.0.4", 247 | "path-is-absolute": "1.0.1", 248 | "private": "0.1.7", 249 | "slash": "1.0.0", 250 | "source-map": "0.5.6" 251 | } 252 | }, 253 | "babel-generator": { 254 | "version": "6.25.0", 255 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", 256 | "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", 257 | "dev": true, 258 | "requires": { 259 | "babel-messages": "6.23.0", 260 | "babel-runtime": "6.25.0", 261 | "babel-types": "6.25.0", 262 | "detect-indent": "4.0.0", 263 | "jsesc": "1.3.0", 264 | "lodash": "4.17.4", 265 | "source-map": "0.5.6", 266 | "trim-right": "1.0.1" 267 | } 268 | }, 269 | "babel-helpers": { 270 | "version": "6.24.1", 271 | "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", 272 | "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", 273 | "dev": true, 274 | "requires": { 275 | "babel-runtime": "6.25.0", 276 | "babel-template": "6.25.0" 277 | } 278 | }, 279 | "babel-jest": { 280 | "version": "19.0.0", 281 | "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-19.0.0.tgz", 282 | "integrity": "sha1-WTI87ZmjqE01naIZyogQdP/Gzj8=", 283 | "dev": true, 284 | "requires": { 285 | "babel-core": "6.25.0", 286 | "babel-plugin-istanbul": "4.1.4", 287 | "babel-preset-jest": "19.0.0" 288 | } 289 | }, 290 | "babel-messages": { 291 | "version": "6.23.0", 292 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", 293 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 294 | "dev": true, 295 | "requires": { 296 | "babel-runtime": "6.25.0" 297 | } 298 | }, 299 | "babel-plugin-istanbul": { 300 | "version": "4.1.4", 301 | "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.4.tgz", 302 | "integrity": "sha1-GN3oS/POMp/d8/QQP66SFFbY5Yc=", 303 | "dev": true, 304 | "requires": { 305 | "find-up": "2.1.0", 306 | "istanbul-lib-instrument": "1.7.4", 307 | "test-exclude": "4.1.1" 308 | } 309 | }, 310 | "babel-plugin-jest-hoist": { 311 | "version": "19.0.0", 312 | "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-19.0.0.tgz", 313 | "integrity": "sha1-SuKgTqYSpuc2UfP95SwXiZEwS+o=", 314 | "dev": true 315 | }, 316 | "babel-plugin-transform-es2015-modules-commonjs": { 317 | "version": "6.24.1", 318 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", 319 | "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", 320 | "dev": true, 321 | "requires": { 322 | "babel-plugin-transform-strict-mode": "6.24.1", 323 | "babel-runtime": "6.25.0", 324 | "babel-template": "6.25.0", 325 | "babel-types": "6.25.0" 326 | } 327 | }, 328 | "babel-plugin-transform-strict-mode": { 329 | "version": "6.24.1", 330 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", 331 | "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", 332 | "dev": true, 333 | "requires": { 334 | "babel-runtime": "6.25.0", 335 | "babel-types": "6.25.0" 336 | } 337 | }, 338 | "babel-preset-jest": { 339 | "version": "19.0.0", 340 | "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-19.0.0.tgz", 341 | "integrity": "sha1-ItZyAdAjJKGVgRKI6zgpS7PKw5Y=", 342 | "dev": true, 343 | "requires": { 344 | "babel-plugin-jest-hoist": "19.0.0" 345 | } 346 | }, 347 | "babel-register": { 348 | "version": "6.24.1", 349 | "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", 350 | "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", 351 | "dev": true, 352 | "requires": { 353 | "babel-core": "6.25.0", 354 | "babel-runtime": "6.25.0", 355 | "core-js": "2.4.1", 356 | "home-or-tmp": "2.0.0", 357 | "lodash": "4.17.4", 358 | "mkdirp": "0.5.1", 359 | "source-map-support": "0.4.15" 360 | } 361 | }, 362 | "babel-runtime": { 363 | "version": "6.25.0", 364 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz", 365 | "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=", 366 | "dev": true, 367 | "requires": { 368 | "core-js": "2.4.1", 369 | "regenerator-runtime": "0.10.5" 370 | } 371 | }, 372 | "babel-template": { 373 | "version": "6.25.0", 374 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", 375 | "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", 376 | "dev": true, 377 | "requires": { 378 | "babel-runtime": "6.25.0", 379 | "babel-traverse": "6.25.0", 380 | "babel-types": "6.25.0", 381 | "babylon": "6.17.4", 382 | "lodash": "4.17.4" 383 | } 384 | }, 385 | "babel-traverse": { 386 | "version": "6.25.0", 387 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", 388 | "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", 389 | "dev": true, 390 | "requires": { 391 | "babel-code-frame": "6.22.0", 392 | "babel-messages": "6.23.0", 393 | "babel-runtime": "6.25.0", 394 | "babel-types": "6.25.0", 395 | "babylon": "6.17.4", 396 | "debug": "2.6.8", 397 | "globals": "9.18.0", 398 | "invariant": "2.2.2", 399 | "lodash": "4.17.4" 400 | } 401 | }, 402 | "babel-types": { 403 | "version": "6.25.0", 404 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", 405 | "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", 406 | "dev": true, 407 | "requires": { 408 | "babel-runtime": "6.25.0", 409 | "esutils": "2.0.2", 410 | "lodash": "4.17.4", 411 | "to-fast-properties": "1.0.3" 412 | } 413 | }, 414 | "babylon": { 415 | "version": "6.17.4", 416 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", 417 | "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", 418 | "dev": true 419 | }, 420 | "balanced-match": { 421 | "version": "1.0.0", 422 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 423 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 424 | "dev": true 425 | }, 426 | "bcrypt-pbkdf": { 427 | "version": "1.0.1", 428 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 429 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 430 | "dev": true, 431 | "optional": true, 432 | "requires": { 433 | "tweetnacl": "0.14.5" 434 | } 435 | }, 436 | "beeper": { 437 | "version": "1.1.1", 438 | "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", 439 | "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", 440 | "dev": true 441 | }, 442 | "boom": { 443 | "version": "2.10.1", 444 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", 445 | "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", 446 | "dev": true, 447 | "requires": { 448 | "hoek": "2.16.3" 449 | } 450 | }, 451 | "brace-expansion": { 452 | "version": "1.1.8", 453 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 454 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 455 | "dev": true, 456 | "requires": { 457 | "balanced-match": "1.0.0", 458 | "concat-map": "0.0.1" 459 | } 460 | }, 461 | "braces": { 462 | "version": "1.8.5", 463 | "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", 464 | "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", 465 | "dev": true, 466 | "requires": { 467 | "expand-range": "1.8.2", 468 | "preserve": "0.2.0", 469 | "repeat-element": "1.1.2" 470 | } 471 | }, 472 | "browser-resolve": { 473 | "version": "1.11.2", 474 | "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", 475 | "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", 476 | "dev": true, 477 | "requires": { 478 | "resolve": "1.1.7" 479 | }, 480 | "dependencies": { 481 | "resolve": { 482 | "version": "1.1.7", 483 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 484 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 485 | "dev": true 486 | } 487 | } 488 | }, 489 | "bser": { 490 | "version": "2.0.0", 491 | "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", 492 | "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", 493 | "dev": true, 494 | "requires": { 495 | "node-int64": "0.4.0" 496 | } 497 | }, 498 | "builtin-modules": { 499 | "version": "1.1.1", 500 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 501 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", 502 | "dev": true 503 | }, 504 | "callsites": { 505 | "version": "2.0.0", 506 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", 507 | "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", 508 | "dev": true 509 | }, 510 | "camelcase": { 511 | "version": "1.2.1", 512 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 513 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 514 | "dev": true, 515 | "optional": true 516 | }, 517 | "camelcase-keys": { 518 | "version": "2.1.0", 519 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", 520 | "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", 521 | "dev": true, 522 | "requires": { 523 | "camelcase": "2.1.1", 524 | "map-obj": "1.0.1" 525 | }, 526 | "dependencies": { 527 | "camelcase": { 528 | "version": "2.1.1", 529 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 530 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", 531 | "dev": true 532 | } 533 | } 534 | }, 535 | "caseless": { 536 | "version": "0.12.0", 537 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 538 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 539 | "dev": true 540 | }, 541 | "center-align": { 542 | "version": "0.1.3", 543 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 544 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 545 | "dev": true, 546 | "optional": true, 547 | "requires": { 548 | "align-text": "0.1.4", 549 | "lazy-cache": "1.0.4" 550 | } 551 | }, 552 | "chalk": { 553 | "version": "1.1.3", 554 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 555 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 556 | "dev": true, 557 | "requires": { 558 | "ansi-styles": "2.2.1", 559 | "escape-string-regexp": "1.0.5", 560 | "has-ansi": "2.0.0", 561 | "strip-ansi": "3.0.1", 562 | "supports-color": "2.0.0" 563 | } 564 | }, 565 | "ci-info": { 566 | "version": "1.0.0", 567 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", 568 | "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", 569 | "dev": true 570 | }, 571 | "cliui": { 572 | "version": "2.1.0", 573 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 574 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 575 | "dev": true, 576 | "optional": true, 577 | "requires": { 578 | "center-align": "0.1.3", 579 | "right-align": "0.1.3", 580 | "wordwrap": "0.0.2" 581 | }, 582 | "dependencies": { 583 | "wordwrap": { 584 | "version": "0.0.2", 585 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 586 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 587 | "dev": true, 588 | "optional": true 589 | } 590 | } 591 | }, 592 | "clone": { 593 | "version": "1.0.2", 594 | "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", 595 | "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", 596 | "dev": true 597 | }, 598 | "clone-stats": { 599 | "version": "0.0.1", 600 | "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", 601 | "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", 602 | "dev": true 603 | }, 604 | "co": { 605 | "version": "4.6.0", 606 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 607 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 608 | "dev": true 609 | }, 610 | "code-point-at": { 611 | "version": "1.1.0", 612 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 613 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 614 | "dev": true 615 | }, 616 | "color-convert": { 617 | "version": "1.9.0", 618 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", 619 | "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", 620 | "dev": true, 621 | "requires": { 622 | "color-name": "1.1.3" 623 | } 624 | }, 625 | "color-name": { 626 | "version": "1.1.3", 627 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 628 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 629 | "dev": true 630 | }, 631 | "colors": { 632 | "version": "1.1.2", 633 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", 634 | "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", 635 | "dev": true 636 | }, 637 | "combined-stream": { 638 | "version": "1.0.5", 639 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", 640 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", 641 | "dev": true, 642 | "requires": { 643 | "delayed-stream": "1.0.0" 644 | } 645 | }, 646 | "commander": { 647 | "version": "2.11.0", 648 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 649 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", 650 | "dev": true 651 | }, 652 | "concat-map": { 653 | "version": "0.0.1", 654 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 655 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 656 | "dev": true 657 | }, 658 | "content-type-parser": { 659 | "version": "1.0.1", 660 | "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", 661 | "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", 662 | "dev": true 663 | }, 664 | "convert-source-map": { 665 | "version": "1.5.0", 666 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", 667 | "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", 668 | "dev": true 669 | }, 670 | "core-js": { 671 | "version": "2.4.1", 672 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", 673 | "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", 674 | "dev": true 675 | }, 676 | "core-util-is": { 677 | "version": "1.0.2", 678 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 679 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 680 | "dev": true 681 | }, 682 | "cryptiles": { 683 | "version": "2.0.5", 684 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", 685 | "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", 686 | "dev": true, 687 | "requires": { 688 | "boom": "2.10.1" 689 | } 690 | }, 691 | "cssom": { 692 | "version": "0.3.2", 693 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", 694 | "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", 695 | "dev": true 696 | }, 697 | "cssstyle": { 698 | "version": "0.2.37", 699 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", 700 | "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", 701 | "dev": true, 702 | "requires": { 703 | "cssom": "0.3.2" 704 | } 705 | }, 706 | "currently-unhandled": { 707 | "version": "0.4.1", 708 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", 709 | "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", 710 | "dev": true, 711 | "requires": { 712 | "array-find-index": "1.0.2" 713 | } 714 | }, 715 | "dashdash": { 716 | "version": "1.14.1", 717 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 718 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 719 | "dev": true, 720 | "requires": { 721 | "assert-plus": "1.0.0" 722 | }, 723 | "dependencies": { 724 | "assert-plus": { 725 | "version": "1.0.0", 726 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 727 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 728 | "dev": true 729 | } 730 | } 731 | }, 732 | "dateformat": { 733 | "version": "1.0.12", 734 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", 735 | "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", 736 | "dev": true, 737 | "requires": { 738 | "get-stdin": "4.0.1", 739 | "meow": "3.7.0" 740 | } 741 | }, 742 | "debug": { 743 | "version": "2.6.8", 744 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", 745 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", 746 | "dev": true, 747 | "requires": { 748 | "ms": "2.0.0" 749 | } 750 | }, 751 | "decamelize": { 752 | "version": "1.2.0", 753 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 754 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 755 | "dev": true 756 | }, 757 | "deep-is": { 758 | "version": "0.1.3", 759 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 760 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 761 | "dev": true 762 | }, 763 | "default-require-extensions": { 764 | "version": "1.0.0", 765 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", 766 | "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", 767 | "dev": true, 768 | "requires": { 769 | "strip-bom": "2.0.0" 770 | } 771 | }, 772 | "delayed-stream": { 773 | "version": "1.0.0", 774 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 775 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 776 | "dev": true 777 | }, 778 | "detect-indent": { 779 | "version": "4.0.0", 780 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", 781 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", 782 | "dev": true, 783 | "requires": { 784 | "repeating": "2.0.1" 785 | } 786 | }, 787 | "diff": { 788 | "version": "3.3.0", 789 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz", 790 | "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==", 791 | "dev": true 792 | }, 793 | "duplexer2": { 794 | "version": "0.0.2", 795 | "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", 796 | "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", 797 | "dev": true, 798 | "requires": { 799 | "readable-stream": "1.1.14" 800 | } 801 | }, 802 | "ecc-jsbn": { 803 | "version": "0.1.1", 804 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 805 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 806 | "dev": true, 807 | "optional": true, 808 | "requires": { 809 | "jsbn": "0.1.1" 810 | } 811 | }, 812 | "errno": { 813 | "version": "0.1.4", 814 | "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", 815 | "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", 816 | "dev": true, 817 | "requires": { 818 | "prr": "0.0.0" 819 | } 820 | }, 821 | "error-ex": { 822 | "version": "1.3.1", 823 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 824 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 825 | "dev": true, 826 | "requires": { 827 | "is-arrayish": "0.2.1" 828 | } 829 | }, 830 | "escape-string-regexp": { 831 | "version": "1.0.5", 832 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 833 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 834 | "dev": true 835 | }, 836 | "escodegen": { 837 | "version": "1.8.1", 838 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", 839 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 840 | "dev": true, 841 | "requires": { 842 | "esprima": "2.7.3", 843 | "estraverse": "1.9.3", 844 | "esutils": "2.0.2", 845 | "optionator": "0.8.2", 846 | "source-map": "0.2.0" 847 | }, 848 | "dependencies": { 849 | "esprima": { 850 | "version": "2.7.3", 851 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 852 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 853 | "dev": true 854 | }, 855 | "source-map": { 856 | "version": "0.2.0", 857 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", 858 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 859 | "dev": true, 860 | "optional": true, 861 | "requires": { 862 | "amdefine": "1.0.1" 863 | } 864 | } 865 | } 866 | }, 867 | "esprima": { 868 | "version": "4.0.0", 869 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", 870 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", 871 | "dev": true 872 | }, 873 | "estraverse": { 874 | "version": "1.9.3", 875 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", 876 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 877 | "dev": true 878 | }, 879 | "esutils": { 880 | "version": "2.0.2", 881 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 882 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 883 | "dev": true 884 | }, 885 | "exec-sh": { 886 | "version": "0.2.0", 887 | "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.0.tgz", 888 | "integrity": "sha1-FPdd4/INKG75MwmbLOUKkDWc7xA=", 889 | "dev": true, 890 | "requires": { 891 | "merge": "1.2.0" 892 | } 893 | }, 894 | "expand-brackets": { 895 | "version": "0.1.5", 896 | "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", 897 | "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", 898 | "dev": true, 899 | "requires": { 900 | "is-posix-bracket": "0.1.1" 901 | } 902 | }, 903 | "expand-range": { 904 | "version": "1.8.2", 905 | "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", 906 | "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", 907 | "dev": true, 908 | "requires": { 909 | "fill-range": "2.2.3" 910 | } 911 | }, 912 | "extend": { 913 | "version": "3.0.1", 914 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 915 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", 916 | "dev": true 917 | }, 918 | "extglob": { 919 | "version": "0.3.2", 920 | "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", 921 | "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", 922 | "dev": true, 923 | "requires": { 924 | "is-extglob": "1.0.0" 925 | } 926 | }, 927 | "extsprintf": { 928 | "version": "1.3.0", 929 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 930 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 931 | "dev": true 932 | }, 933 | "fancy-log": { 934 | "version": "1.3.0", 935 | "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", 936 | "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", 937 | "dev": true, 938 | "requires": { 939 | "chalk": "1.1.3", 940 | "time-stamp": "1.1.0" 941 | } 942 | }, 943 | "fast-levenshtein": { 944 | "version": "2.0.6", 945 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 946 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 947 | "dev": true 948 | }, 949 | "fb-watchman": { 950 | "version": "2.0.0", 951 | "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", 952 | "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", 953 | "dev": true, 954 | "requires": { 955 | "bser": "2.0.0" 956 | } 957 | }, 958 | "filename-regex": { 959 | "version": "2.0.1", 960 | "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", 961 | "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", 962 | "dev": true 963 | }, 964 | "fileset": { 965 | "version": "2.0.3", 966 | "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", 967 | "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", 968 | "dev": true, 969 | "requires": { 970 | "glob": "7.1.2", 971 | "minimatch": "3.0.4" 972 | } 973 | }, 974 | "fill-range": { 975 | "version": "2.2.3", 976 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", 977 | "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", 978 | "dev": true, 979 | "requires": { 980 | "is-number": "2.1.0", 981 | "isobject": "2.1.0", 982 | "randomatic": "1.1.7", 983 | "repeat-element": "1.1.2", 984 | "repeat-string": "1.6.1" 985 | } 986 | }, 987 | "find-up": { 988 | "version": "2.1.0", 989 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 990 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 991 | "dev": true, 992 | "requires": { 993 | "locate-path": "2.0.0" 994 | } 995 | }, 996 | "for-in": { 997 | "version": "1.0.2", 998 | "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", 999 | "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", 1000 | "dev": true 1001 | }, 1002 | "for-own": { 1003 | "version": "0.1.5", 1004 | "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", 1005 | "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", 1006 | "dev": true, 1007 | "requires": { 1008 | "for-in": "1.0.2" 1009 | } 1010 | }, 1011 | "forever-agent": { 1012 | "version": "0.6.1", 1013 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 1014 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 1015 | "dev": true 1016 | }, 1017 | "form-data": { 1018 | "version": "2.1.4", 1019 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", 1020 | "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", 1021 | "dev": true, 1022 | "requires": { 1023 | "asynckit": "0.4.0", 1024 | "combined-stream": "1.0.5", 1025 | "mime-types": "2.1.16" 1026 | } 1027 | }, 1028 | "fs-extra": { 1029 | "version": "2.1.2", 1030 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", 1031 | "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", 1032 | "dev": true, 1033 | "requires": { 1034 | "graceful-fs": "4.1.11", 1035 | "jsonfile": "2.4.0" 1036 | } 1037 | }, 1038 | "fs.realpath": { 1039 | "version": "1.0.0", 1040 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1041 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1042 | "dev": true 1043 | }, 1044 | "get-caller-file": { 1045 | "version": "1.0.2", 1046 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", 1047 | "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", 1048 | "dev": true 1049 | }, 1050 | "get-stdin": { 1051 | "version": "4.0.1", 1052 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", 1053 | "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", 1054 | "dev": true 1055 | }, 1056 | "getpass": { 1057 | "version": "0.1.7", 1058 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 1059 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 1060 | "dev": true, 1061 | "requires": { 1062 | "assert-plus": "1.0.0" 1063 | }, 1064 | "dependencies": { 1065 | "assert-plus": { 1066 | "version": "1.0.0", 1067 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1068 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1069 | "dev": true 1070 | } 1071 | } 1072 | }, 1073 | "glob": { 1074 | "version": "7.1.2", 1075 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 1076 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1077 | "dev": true, 1078 | "requires": { 1079 | "fs.realpath": "1.0.0", 1080 | "inflight": "1.0.6", 1081 | "inherits": "2.0.3", 1082 | "minimatch": "3.0.4", 1083 | "once": "1.4.0", 1084 | "path-is-absolute": "1.0.1" 1085 | } 1086 | }, 1087 | "glob-all": { 1088 | "version": "3.1.0", 1089 | "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz", 1090 | "integrity": "sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=", 1091 | "dev": true, 1092 | "requires": { 1093 | "glob": "7.1.2", 1094 | "yargs": "1.2.6" 1095 | }, 1096 | "dependencies": { 1097 | "minimist": { 1098 | "version": "0.1.0", 1099 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", 1100 | "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", 1101 | "dev": true 1102 | }, 1103 | "yargs": { 1104 | "version": "1.2.6", 1105 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", 1106 | "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", 1107 | "dev": true, 1108 | "requires": { 1109 | "minimist": "0.1.0" 1110 | } 1111 | } 1112 | } 1113 | }, 1114 | "glob-base": { 1115 | "version": "0.3.0", 1116 | "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", 1117 | "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", 1118 | "dev": true, 1119 | "requires": { 1120 | "glob-parent": "2.0.0", 1121 | "is-glob": "2.0.1" 1122 | } 1123 | }, 1124 | "glob-parent": { 1125 | "version": "2.0.0", 1126 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", 1127 | "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", 1128 | "dev": true, 1129 | "requires": { 1130 | "is-glob": "2.0.1" 1131 | } 1132 | }, 1133 | "globals": { 1134 | "version": "9.18.0", 1135 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", 1136 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", 1137 | "dev": true 1138 | }, 1139 | "glogg": { 1140 | "version": "1.0.0", 1141 | "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", 1142 | "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", 1143 | "dev": true, 1144 | "requires": { 1145 | "sparkles": "1.0.0" 1146 | } 1147 | }, 1148 | "graceful-fs": { 1149 | "version": "4.1.11", 1150 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 1151 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", 1152 | "dev": true 1153 | }, 1154 | "growly": { 1155 | "version": "1.3.0", 1156 | "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", 1157 | "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", 1158 | "dev": true 1159 | }, 1160 | "gulp-util": { 1161 | "version": "3.0.7", 1162 | "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.7.tgz", 1163 | "integrity": "sha1-eJJcS4+LSQBawBoBHFV+YhiUHLs=", 1164 | "dev": true, 1165 | "requires": { 1166 | "array-differ": "1.0.0", 1167 | "array-uniq": "1.0.3", 1168 | "beeper": "1.1.1", 1169 | "chalk": "1.1.3", 1170 | "dateformat": "1.0.12", 1171 | "fancy-log": "1.3.0", 1172 | "gulplog": "1.0.0", 1173 | "has-gulplog": "0.1.0", 1174 | "lodash._reescape": "3.0.0", 1175 | "lodash._reevaluate": "3.0.0", 1176 | "lodash._reinterpolate": "3.0.0", 1177 | "lodash.template": "3.6.2", 1178 | "minimist": "1.2.0", 1179 | "multipipe": "0.1.2", 1180 | "object-assign": "3.0.0", 1181 | "replace-ext": "0.0.1", 1182 | "through2": "2.0.1", 1183 | "vinyl": "0.5.3" 1184 | }, 1185 | "dependencies": { 1186 | "minimist": { 1187 | "version": "1.2.0", 1188 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1189 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 1190 | "dev": true 1191 | }, 1192 | "object-assign": { 1193 | "version": "3.0.0", 1194 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", 1195 | "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", 1196 | "dev": true 1197 | } 1198 | } 1199 | }, 1200 | "gulplog": { 1201 | "version": "1.0.0", 1202 | "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", 1203 | "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", 1204 | "dev": true, 1205 | "requires": { 1206 | "glogg": "1.0.0" 1207 | } 1208 | }, 1209 | "handlebars": { 1210 | "version": "4.0.10", 1211 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", 1212 | "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", 1213 | "dev": true, 1214 | "requires": { 1215 | "async": "1.5.2", 1216 | "optimist": "0.6.1", 1217 | "source-map": "0.4.4", 1218 | "uglify-js": "2.8.29" 1219 | }, 1220 | "dependencies": { 1221 | "async": { 1222 | "version": "1.5.2", 1223 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 1224 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 1225 | "dev": true 1226 | }, 1227 | "source-map": { 1228 | "version": "0.4.4", 1229 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 1230 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 1231 | "dev": true, 1232 | "requires": { 1233 | "amdefine": "1.0.1" 1234 | } 1235 | } 1236 | } 1237 | }, 1238 | "har-schema": { 1239 | "version": "1.0.5", 1240 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", 1241 | "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", 1242 | "dev": true 1243 | }, 1244 | "har-validator": { 1245 | "version": "4.2.1", 1246 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", 1247 | "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", 1248 | "dev": true, 1249 | "requires": { 1250 | "ajv": "4.11.8", 1251 | "har-schema": "1.0.5" 1252 | } 1253 | }, 1254 | "has-ansi": { 1255 | "version": "2.0.0", 1256 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 1257 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1258 | "dev": true, 1259 | "requires": { 1260 | "ansi-regex": "2.1.1" 1261 | } 1262 | }, 1263 | "has-flag": { 1264 | "version": "1.0.0", 1265 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 1266 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", 1267 | "dev": true 1268 | }, 1269 | "has-gulplog": { 1270 | "version": "0.1.0", 1271 | "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", 1272 | "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", 1273 | "dev": true, 1274 | "requires": { 1275 | "sparkles": "1.0.0" 1276 | } 1277 | }, 1278 | "hawk": { 1279 | "version": "3.1.3", 1280 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", 1281 | "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", 1282 | "dev": true, 1283 | "requires": { 1284 | "boom": "2.10.1", 1285 | "cryptiles": "2.0.5", 1286 | "hoek": "2.16.3", 1287 | "sntp": "1.0.9" 1288 | } 1289 | }, 1290 | "hoek": { 1291 | "version": "2.16.3", 1292 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", 1293 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", 1294 | "dev": true 1295 | }, 1296 | "home-or-tmp": { 1297 | "version": "2.0.0", 1298 | "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", 1299 | "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", 1300 | "dev": true, 1301 | "requires": { 1302 | "os-homedir": "1.0.2", 1303 | "os-tmpdir": "1.0.2" 1304 | } 1305 | }, 1306 | "hosted-git-info": { 1307 | "version": "2.5.0", 1308 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", 1309 | "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", 1310 | "dev": true 1311 | }, 1312 | "html-encoding-sniffer": { 1313 | "version": "1.0.1", 1314 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", 1315 | "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", 1316 | "dev": true, 1317 | "requires": { 1318 | "whatwg-encoding": "1.0.1" 1319 | } 1320 | }, 1321 | "http-signature": { 1322 | "version": "1.1.1", 1323 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", 1324 | "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", 1325 | "dev": true, 1326 | "requires": { 1327 | "assert-plus": "0.2.0", 1328 | "jsprim": "1.4.1", 1329 | "sshpk": "1.13.1" 1330 | } 1331 | }, 1332 | "iconv-lite": { 1333 | "version": "0.4.13", 1334 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", 1335 | "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", 1336 | "dev": true 1337 | }, 1338 | "indent-string": { 1339 | "version": "2.1.0", 1340 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", 1341 | "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", 1342 | "dev": true, 1343 | "requires": { 1344 | "repeating": "2.0.1" 1345 | } 1346 | }, 1347 | "inflight": { 1348 | "version": "1.0.6", 1349 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1350 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1351 | "dev": true, 1352 | "requires": { 1353 | "once": "1.4.0", 1354 | "wrappy": "1.0.2" 1355 | } 1356 | }, 1357 | "inherits": { 1358 | "version": "2.0.3", 1359 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1360 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 1361 | "dev": true 1362 | }, 1363 | "invariant": { 1364 | "version": "2.2.2", 1365 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", 1366 | "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", 1367 | "dev": true, 1368 | "requires": { 1369 | "loose-envify": "1.3.1" 1370 | } 1371 | }, 1372 | "invert-kv": { 1373 | "version": "1.0.0", 1374 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 1375 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", 1376 | "dev": true 1377 | }, 1378 | "is-arrayish": { 1379 | "version": "0.2.1", 1380 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1381 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 1382 | "dev": true 1383 | }, 1384 | "is-buffer": { 1385 | "version": "1.1.5", 1386 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", 1387 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", 1388 | "dev": true 1389 | }, 1390 | "is-builtin-module": { 1391 | "version": "1.0.0", 1392 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 1393 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 1394 | "dev": true, 1395 | "requires": { 1396 | "builtin-modules": "1.1.1" 1397 | } 1398 | }, 1399 | "is-ci": { 1400 | "version": "1.0.10", 1401 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", 1402 | "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", 1403 | "dev": true, 1404 | "requires": { 1405 | "ci-info": "1.0.0" 1406 | } 1407 | }, 1408 | "is-dotfile": { 1409 | "version": "1.0.3", 1410 | "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", 1411 | "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", 1412 | "dev": true 1413 | }, 1414 | "is-equal-shallow": { 1415 | "version": "0.1.3", 1416 | "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", 1417 | "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", 1418 | "dev": true, 1419 | "requires": { 1420 | "is-primitive": "2.0.0" 1421 | } 1422 | }, 1423 | "is-extendable": { 1424 | "version": "0.1.1", 1425 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", 1426 | "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", 1427 | "dev": true 1428 | }, 1429 | "is-extglob": { 1430 | "version": "1.0.0", 1431 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", 1432 | "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", 1433 | "dev": true 1434 | }, 1435 | "is-finite": { 1436 | "version": "1.0.2", 1437 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1438 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1439 | "dev": true, 1440 | "requires": { 1441 | "number-is-nan": "1.0.1" 1442 | } 1443 | }, 1444 | "is-fullwidth-code-point": { 1445 | "version": "1.0.0", 1446 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 1447 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 1448 | "dev": true, 1449 | "requires": { 1450 | "number-is-nan": "1.0.1" 1451 | } 1452 | }, 1453 | "is-glob": { 1454 | "version": "2.0.1", 1455 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", 1456 | "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", 1457 | "dev": true, 1458 | "requires": { 1459 | "is-extglob": "1.0.0" 1460 | } 1461 | }, 1462 | "is-number": { 1463 | "version": "2.1.0", 1464 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", 1465 | "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", 1466 | "dev": true, 1467 | "requires": { 1468 | "kind-of": "3.2.2" 1469 | } 1470 | }, 1471 | "is-posix-bracket": { 1472 | "version": "0.1.1", 1473 | "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", 1474 | "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", 1475 | "dev": true 1476 | }, 1477 | "is-primitive": { 1478 | "version": "2.0.0", 1479 | "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", 1480 | "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", 1481 | "dev": true 1482 | }, 1483 | "is-typedarray": { 1484 | "version": "1.0.0", 1485 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1486 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1487 | "dev": true 1488 | }, 1489 | "is-utf8": { 1490 | "version": "0.2.1", 1491 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1492 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", 1493 | "dev": true 1494 | }, 1495 | "isarray": { 1496 | "version": "1.0.0", 1497 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1498 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 1499 | "dev": true 1500 | }, 1501 | "isexe": { 1502 | "version": "2.0.0", 1503 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1504 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1505 | "dev": true 1506 | }, 1507 | "isobject": { 1508 | "version": "2.1.0", 1509 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", 1510 | "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", 1511 | "dev": true, 1512 | "requires": { 1513 | "isarray": "1.0.0" 1514 | } 1515 | }, 1516 | "isstream": { 1517 | "version": "0.1.2", 1518 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1519 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 1520 | "dev": true 1521 | }, 1522 | "istanbul": { 1523 | "version": "0.4.5", 1524 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", 1525 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", 1526 | "dev": true, 1527 | "requires": { 1528 | "abbrev": "1.0.9", 1529 | "async": "1.5.2", 1530 | "escodegen": "1.8.1", 1531 | "esprima": "2.7.3", 1532 | "glob": "5.0.15", 1533 | "handlebars": "4.0.10", 1534 | "js-yaml": "3.9.1", 1535 | "mkdirp": "0.5.1", 1536 | "nopt": "3.0.6", 1537 | "once": "1.4.0", 1538 | "resolve": "1.1.7", 1539 | "supports-color": "3.2.3", 1540 | "which": "1.3.0", 1541 | "wordwrap": "1.0.0" 1542 | }, 1543 | "dependencies": { 1544 | "async": { 1545 | "version": "1.5.2", 1546 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 1547 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 1548 | "dev": true 1549 | }, 1550 | "esprima": { 1551 | "version": "2.7.3", 1552 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 1553 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 1554 | "dev": true 1555 | }, 1556 | "glob": { 1557 | "version": "5.0.15", 1558 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 1559 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 1560 | "dev": true, 1561 | "requires": { 1562 | "inflight": "1.0.6", 1563 | "inherits": "2.0.3", 1564 | "minimatch": "3.0.4", 1565 | "once": "1.4.0", 1566 | "path-is-absolute": "1.0.1" 1567 | } 1568 | }, 1569 | "resolve": { 1570 | "version": "1.1.7", 1571 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 1572 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 1573 | "dev": true 1574 | }, 1575 | "supports-color": { 1576 | "version": "3.2.3", 1577 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 1578 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 1579 | "dev": true, 1580 | "requires": { 1581 | "has-flag": "1.0.0" 1582 | } 1583 | }, 1584 | "wordwrap": { 1585 | "version": "1.0.0", 1586 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 1587 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 1588 | "dev": true 1589 | } 1590 | } 1591 | }, 1592 | "istanbul-api": { 1593 | "version": "1.1.11", 1594 | "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.11.tgz", 1595 | "integrity": "sha1-/MC0YeKzvaceMFFVE4I4doJX2d4=", 1596 | "dev": true, 1597 | "requires": { 1598 | "async": "2.5.0", 1599 | "fileset": "2.0.3", 1600 | "istanbul-lib-coverage": "1.1.1", 1601 | "istanbul-lib-hook": "1.0.7", 1602 | "istanbul-lib-instrument": "1.7.4", 1603 | "istanbul-lib-report": "1.1.1", 1604 | "istanbul-lib-source-maps": "1.2.1", 1605 | "istanbul-reports": "1.1.1", 1606 | "js-yaml": "3.9.1", 1607 | "mkdirp": "0.5.1", 1608 | "once": "1.4.0" 1609 | } 1610 | }, 1611 | "istanbul-lib-coverage": { 1612 | "version": "1.1.1", 1613 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", 1614 | "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", 1615 | "dev": true 1616 | }, 1617 | "istanbul-lib-hook": { 1618 | "version": "1.0.7", 1619 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", 1620 | "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", 1621 | "dev": true, 1622 | "requires": { 1623 | "append-transform": "0.4.0" 1624 | } 1625 | }, 1626 | "istanbul-lib-instrument": { 1627 | "version": "1.7.4", 1628 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz", 1629 | "integrity": "sha1-6f2SDkdn89Ge3HZeLWs/XMvQ7qg=", 1630 | "dev": true, 1631 | "requires": { 1632 | "babel-generator": "6.25.0", 1633 | "babel-template": "6.25.0", 1634 | "babel-traverse": "6.25.0", 1635 | "babel-types": "6.25.0", 1636 | "babylon": "6.17.4", 1637 | "istanbul-lib-coverage": "1.1.1", 1638 | "semver": "5.4.1" 1639 | } 1640 | }, 1641 | "istanbul-lib-report": { 1642 | "version": "1.1.1", 1643 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", 1644 | "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", 1645 | "dev": true, 1646 | "requires": { 1647 | "istanbul-lib-coverage": "1.1.1", 1648 | "mkdirp": "0.5.1", 1649 | "path-parse": "1.0.5", 1650 | "supports-color": "3.2.3" 1651 | }, 1652 | "dependencies": { 1653 | "supports-color": { 1654 | "version": "3.2.3", 1655 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 1656 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 1657 | "dev": true, 1658 | "requires": { 1659 | "has-flag": "1.0.0" 1660 | } 1661 | } 1662 | } 1663 | }, 1664 | "istanbul-lib-source-maps": { 1665 | "version": "1.2.1", 1666 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", 1667 | "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", 1668 | "dev": true, 1669 | "requires": { 1670 | "debug": "2.6.8", 1671 | "istanbul-lib-coverage": "1.1.1", 1672 | "mkdirp": "0.5.1", 1673 | "rimraf": "2.6.1", 1674 | "source-map": "0.5.6" 1675 | } 1676 | }, 1677 | "istanbul-reports": { 1678 | "version": "1.1.1", 1679 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.1.tgz", 1680 | "integrity": "sha512-P8G873A0kW24XRlxHVGhMJBhQ8gWAec+dae7ZxOBzxT4w+a9ATSPvRVK3LB1RAJ9S8bg2tOyWHAGW40Zd2dKfw==", 1681 | "dev": true, 1682 | "requires": { 1683 | "handlebars": "4.0.10" 1684 | } 1685 | }, 1686 | "jest": { 1687 | "version": "19.0.2", 1688 | "resolved": "https://registry.npmjs.org/jest/-/jest-19.0.2.tgz", 1689 | "integrity": "sha1-t5T6r4/0Yec4jyi+71WaVPILLBA=", 1690 | "dev": true, 1691 | "requires": { 1692 | "jest-cli": "19.0.2" 1693 | }, 1694 | "dependencies": { 1695 | "jest-cli": { 1696 | "version": "19.0.2", 1697 | "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-19.0.2.tgz", 1698 | "integrity": "sha1-zDYgtirKxfLZOlSMtu9pfU7IVEM=", 1699 | "dev": true, 1700 | "requires": { 1701 | "ansi-escapes": "1.4.0", 1702 | "callsites": "2.0.0", 1703 | "chalk": "1.1.3", 1704 | "graceful-fs": "4.1.11", 1705 | "is-ci": "1.0.10", 1706 | "istanbul-api": "1.1.11", 1707 | "istanbul-lib-coverage": "1.1.1", 1708 | "istanbul-lib-instrument": "1.7.4", 1709 | "jest-changed-files": "19.0.2", 1710 | "jest-config": "19.0.4", 1711 | "jest-environment-jsdom": "19.0.2", 1712 | "jest-haste-map": "19.0.2", 1713 | "jest-jasmine2": "19.0.2", 1714 | "jest-message-util": "19.0.0", 1715 | "jest-regex-util": "19.0.0", 1716 | "jest-resolve-dependencies": "19.0.0", 1717 | "jest-runtime": "19.0.4", 1718 | "jest-snapshot": "19.0.2", 1719 | "jest-util": "19.0.2", 1720 | "micromatch": "2.3.11", 1721 | "node-notifier": "5.1.2", 1722 | "slash": "1.0.0", 1723 | "string-length": "1.0.1", 1724 | "throat": "3.2.0", 1725 | "which": "1.3.0", 1726 | "worker-farm": "1.4.1", 1727 | "yargs": "6.6.0" 1728 | } 1729 | } 1730 | } 1731 | }, 1732 | "jest-changed-files": { 1733 | "version": "19.0.2", 1734 | "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-19.0.2.tgz", 1735 | "integrity": "sha1-FsVMhMMnC+QI4G0uivPz43qIWCQ=", 1736 | "dev": true 1737 | }, 1738 | "jest-config": { 1739 | "version": "19.0.4", 1740 | "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-19.0.4.tgz", 1741 | "integrity": "sha1-QpgCEdRkF+kcp6v/0IbCcCNPc/0=", 1742 | "dev": true, 1743 | "requires": { 1744 | "chalk": "1.1.3", 1745 | "jest-environment-jsdom": "19.0.2", 1746 | "jest-environment-node": "19.0.2", 1747 | "jest-jasmine2": "19.0.2", 1748 | "jest-regex-util": "19.0.0", 1749 | "jest-resolve": "19.0.2", 1750 | "jest-validate": "19.0.2", 1751 | "pretty-format": "19.0.0" 1752 | } 1753 | }, 1754 | "jest-diff": { 1755 | "version": "19.0.0", 1756 | "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-19.0.0.tgz", 1757 | "integrity": "sha1-0VY8/FbItgIymI+8BdTRbtkPBjw=", 1758 | "dev": true, 1759 | "requires": { 1760 | "chalk": "1.1.3", 1761 | "diff": "3.3.0", 1762 | "jest-matcher-utils": "19.0.0", 1763 | "pretty-format": "19.0.0" 1764 | } 1765 | }, 1766 | "jest-environment-jsdom": { 1767 | "version": "19.0.2", 1768 | "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-19.0.2.tgz", 1769 | "integrity": "sha1-ztqFnEpLlKs15N59q1S5JvKT5KM=", 1770 | "dev": true, 1771 | "requires": { 1772 | "jest-mock": "19.0.0", 1773 | "jest-util": "19.0.2", 1774 | "jsdom": "9.12.0" 1775 | } 1776 | }, 1777 | "jest-environment-node": { 1778 | "version": "19.0.2", 1779 | "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-19.0.2.tgz", 1780 | "integrity": "sha1-boQHnbh+0h0MBeH5Zp8gexFv6Zs=", 1781 | "dev": true, 1782 | "requires": { 1783 | "jest-mock": "19.0.0", 1784 | "jest-util": "19.0.2" 1785 | } 1786 | }, 1787 | "jest-file-exists": { 1788 | "version": "19.0.0", 1789 | "resolved": "https://registry.npmjs.org/jest-file-exists/-/jest-file-exists-19.0.0.tgz", 1790 | "integrity": "sha1-zKLlh6EeyS4kz+qz+KlNZX8/zrg=", 1791 | "dev": true 1792 | }, 1793 | "jest-haste-map": { 1794 | "version": "19.0.2", 1795 | "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-19.0.2.tgz", 1796 | "integrity": "sha1-KGSEw6Fuhtp4crCHfDXc4ww9bwc=", 1797 | "dev": true, 1798 | "requires": { 1799 | "fb-watchman": "2.0.0", 1800 | "graceful-fs": "4.1.11", 1801 | "micromatch": "2.3.11", 1802 | "sane": "1.5.0", 1803 | "worker-farm": "1.4.1" 1804 | } 1805 | }, 1806 | "jest-jasmine2": { 1807 | "version": "19.0.2", 1808 | "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-19.0.2.tgz", 1809 | "integrity": "sha1-FnmRrIJZgfsagArxJug6/MqDLHM=", 1810 | "dev": true, 1811 | "requires": { 1812 | "graceful-fs": "4.1.11", 1813 | "jest-matcher-utils": "19.0.0", 1814 | "jest-matchers": "19.0.0", 1815 | "jest-message-util": "19.0.0", 1816 | "jest-snapshot": "19.0.2" 1817 | } 1818 | }, 1819 | "jest-matcher-utils": { 1820 | "version": "19.0.0", 1821 | "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz", 1822 | "integrity": "sha1-Xs2bY1ZdKwAfYfv37Ex/U3lkVk0=", 1823 | "dev": true, 1824 | "requires": { 1825 | "chalk": "1.1.3", 1826 | "pretty-format": "19.0.0" 1827 | } 1828 | }, 1829 | "jest-matchers": { 1830 | "version": "19.0.0", 1831 | "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-19.0.0.tgz", 1832 | "integrity": "sha1-x07Mbr/sBvOEdnuk1vpKQtZ1V1Q=", 1833 | "dev": true, 1834 | "requires": { 1835 | "jest-diff": "19.0.0", 1836 | "jest-matcher-utils": "19.0.0", 1837 | "jest-message-util": "19.0.0", 1838 | "jest-regex-util": "19.0.0" 1839 | } 1840 | }, 1841 | "jest-message-util": { 1842 | "version": "19.0.0", 1843 | "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-19.0.0.tgz", 1844 | "integrity": "sha1-cheWuJwOTXYWBvm6jLgoo7YkZBY=", 1845 | "dev": true, 1846 | "requires": { 1847 | "chalk": "1.1.3", 1848 | "micromatch": "2.3.11" 1849 | } 1850 | }, 1851 | "jest-mock": { 1852 | "version": "19.0.0", 1853 | "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-19.0.0.tgz", 1854 | "integrity": "sha1-ZwOGQelgerLOCOxKjLg6q7yJnQE=", 1855 | "dev": true 1856 | }, 1857 | "jest-regex-util": { 1858 | "version": "19.0.0", 1859 | "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-19.0.0.tgz", 1860 | "integrity": "sha1-t3VFhxEq7eFFZRC7H2r+dO9ZhpE=", 1861 | "dev": true 1862 | }, 1863 | "jest-resolve": { 1864 | "version": "19.0.2", 1865 | "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-19.0.2.tgz", 1866 | "integrity": "sha1-V5NXXeTweuwy99f/DGwYGWPu+zw=", 1867 | "dev": true, 1868 | "requires": { 1869 | "browser-resolve": "1.11.2", 1870 | "jest-haste-map": "19.0.2", 1871 | "resolve": "1.4.0" 1872 | } 1873 | }, 1874 | "jest-resolve-dependencies": { 1875 | "version": "19.0.0", 1876 | "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-19.0.0.tgz", 1877 | "integrity": "sha1-p0GtH6CUFA5k7PJkKlBPg07OIu4=", 1878 | "dev": true, 1879 | "requires": { 1880 | "jest-file-exists": "19.0.0" 1881 | } 1882 | }, 1883 | "jest-runtime": { 1884 | "version": "19.0.4", 1885 | "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-19.0.4.tgz", 1886 | "integrity": "sha1-8WfZ8TR3UvICc2EGeSZIU0n8wkU=", 1887 | "dev": true, 1888 | "requires": { 1889 | "babel-core": "6.25.0", 1890 | "babel-jest": "19.0.0", 1891 | "babel-plugin-istanbul": "4.1.4", 1892 | "chalk": "1.1.3", 1893 | "graceful-fs": "4.1.11", 1894 | "jest-config": "19.0.4", 1895 | "jest-file-exists": "19.0.0", 1896 | "jest-haste-map": "19.0.2", 1897 | "jest-regex-util": "19.0.0", 1898 | "jest-resolve": "19.0.2", 1899 | "jest-util": "19.0.2", 1900 | "json-stable-stringify": "1.0.1", 1901 | "micromatch": "2.3.11", 1902 | "strip-bom": "3.0.0", 1903 | "yargs": "6.6.0" 1904 | }, 1905 | "dependencies": { 1906 | "strip-bom": { 1907 | "version": "3.0.0", 1908 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1909 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 1910 | "dev": true 1911 | } 1912 | } 1913 | }, 1914 | "jest-snapshot": { 1915 | "version": "19.0.2", 1916 | "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-19.0.2.tgz", 1917 | "integrity": "sha1-nBshYhT3GHw4v9XHCx76sWsP9Qs=", 1918 | "dev": true, 1919 | "requires": { 1920 | "chalk": "1.1.3", 1921 | "jest-diff": "19.0.0", 1922 | "jest-file-exists": "19.0.0", 1923 | "jest-matcher-utils": "19.0.0", 1924 | "jest-util": "19.0.2", 1925 | "natural-compare": "1.4.0", 1926 | "pretty-format": "19.0.0" 1927 | } 1928 | }, 1929 | "jest-util": { 1930 | "version": "19.0.2", 1931 | "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-19.0.2.tgz", 1932 | "integrity": "sha1-4KAjKiq55rK1Nmi9s1NMK1l37UE=", 1933 | "dev": true, 1934 | "requires": { 1935 | "chalk": "1.1.3", 1936 | "graceful-fs": "4.1.11", 1937 | "jest-file-exists": "19.0.0", 1938 | "jest-message-util": "19.0.0", 1939 | "jest-mock": "19.0.0", 1940 | "jest-validate": "19.0.2", 1941 | "leven": "2.1.0", 1942 | "mkdirp": "0.5.1" 1943 | } 1944 | }, 1945 | "jest-validate": { 1946 | "version": "19.0.2", 1947 | "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-19.0.2.tgz", 1948 | "integrity": "sha1-3FNN9fEnjVtj3zKxQkHU2/ckTAw=", 1949 | "dev": true, 1950 | "requires": { 1951 | "chalk": "1.1.3", 1952 | "jest-matcher-utils": "19.0.0", 1953 | "leven": "2.1.0", 1954 | "pretty-format": "19.0.0" 1955 | } 1956 | }, 1957 | "js-tokens": { 1958 | "version": "3.0.2", 1959 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1960 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 1961 | "dev": true 1962 | }, 1963 | "js-yaml": { 1964 | "version": "3.9.1", 1965 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", 1966 | "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", 1967 | "dev": true, 1968 | "requires": { 1969 | "argparse": "1.0.9", 1970 | "esprima": "4.0.0" 1971 | } 1972 | }, 1973 | "jsbn": { 1974 | "version": "0.1.1", 1975 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1976 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 1977 | "dev": true, 1978 | "optional": true 1979 | }, 1980 | "jsdom": { 1981 | "version": "9.12.0", 1982 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", 1983 | "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", 1984 | "dev": true, 1985 | "requires": { 1986 | "abab": "1.0.3", 1987 | "acorn": "4.0.13", 1988 | "acorn-globals": "3.1.0", 1989 | "array-equal": "1.0.0", 1990 | "content-type-parser": "1.0.1", 1991 | "cssom": "0.3.2", 1992 | "cssstyle": "0.2.37", 1993 | "escodegen": "1.8.1", 1994 | "html-encoding-sniffer": "1.0.1", 1995 | "nwmatcher": "1.4.1", 1996 | "parse5": "1.5.1", 1997 | "request": "2.81.0", 1998 | "sax": "1.2.4", 1999 | "symbol-tree": "3.2.2", 2000 | "tough-cookie": "2.3.2", 2001 | "webidl-conversions": "4.0.1", 2002 | "whatwg-encoding": "1.0.1", 2003 | "whatwg-url": "4.8.0", 2004 | "xml-name-validator": "2.0.1" 2005 | } 2006 | }, 2007 | "jsesc": { 2008 | "version": "1.3.0", 2009 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", 2010 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", 2011 | "dev": true 2012 | }, 2013 | "json-schema": { 2014 | "version": "0.2.3", 2015 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 2016 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 2017 | "dev": true 2018 | }, 2019 | "json-stable-stringify": { 2020 | "version": "1.0.1", 2021 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", 2022 | "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", 2023 | "dev": true, 2024 | "requires": { 2025 | "jsonify": "0.0.0" 2026 | } 2027 | }, 2028 | "json-stringify-safe": { 2029 | "version": "5.0.1", 2030 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 2031 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 2032 | "dev": true 2033 | }, 2034 | "json5": { 2035 | "version": "0.5.1", 2036 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", 2037 | "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", 2038 | "dev": true 2039 | }, 2040 | "jsonfile": { 2041 | "version": "2.4.0", 2042 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", 2043 | "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", 2044 | "dev": true, 2045 | "requires": { 2046 | "graceful-fs": "4.1.11" 2047 | } 2048 | }, 2049 | "jsonify": { 2050 | "version": "0.0.0", 2051 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", 2052 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", 2053 | "dev": true 2054 | }, 2055 | "jsprim": { 2056 | "version": "1.4.1", 2057 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 2058 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 2059 | "dev": true, 2060 | "requires": { 2061 | "assert-plus": "1.0.0", 2062 | "extsprintf": "1.3.0", 2063 | "json-schema": "0.2.3", 2064 | "verror": "1.10.0" 2065 | }, 2066 | "dependencies": { 2067 | "assert-plus": { 2068 | "version": "1.0.0", 2069 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 2070 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 2071 | "dev": true 2072 | } 2073 | } 2074 | }, 2075 | "kind-of": { 2076 | "version": "3.2.2", 2077 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 2078 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 2079 | "dev": true, 2080 | "requires": { 2081 | "is-buffer": "1.1.5" 2082 | } 2083 | }, 2084 | "lazy-cache": { 2085 | "version": "1.0.4", 2086 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 2087 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 2088 | "dev": true, 2089 | "optional": true 2090 | }, 2091 | "lcid": { 2092 | "version": "1.0.0", 2093 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 2094 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", 2095 | "dev": true, 2096 | "requires": { 2097 | "invert-kv": "1.0.0" 2098 | } 2099 | }, 2100 | "leven": { 2101 | "version": "2.1.0", 2102 | "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", 2103 | "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", 2104 | "dev": true 2105 | }, 2106 | "levn": { 2107 | "version": "0.3.0", 2108 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 2109 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 2110 | "dev": true, 2111 | "requires": { 2112 | "prelude-ls": "1.1.2", 2113 | "type-check": "0.3.2" 2114 | } 2115 | }, 2116 | "load-json-file": { 2117 | "version": "1.1.0", 2118 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", 2119 | "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", 2120 | "dev": true, 2121 | "requires": { 2122 | "graceful-fs": "4.1.11", 2123 | "parse-json": "2.2.0", 2124 | "pify": "2.3.0", 2125 | "pinkie-promise": "2.0.1", 2126 | "strip-bom": "2.0.0" 2127 | } 2128 | }, 2129 | "locate-path": { 2130 | "version": "2.0.0", 2131 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 2132 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 2133 | "dev": true, 2134 | "requires": { 2135 | "p-locate": "2.0.0", 2136 | "path-exists": "3.0.0" 2137 | } 2138 | }, 2139 | "lodash": { 2140 | "version": "4.17.4", 2141 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 2142 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 2143 | }, 2144 | "lodash._basecopy": { 2145 | "version": "3.0.1", 2146 | "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", 2147 | "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", 2148 | "dev": true 2149 | }, 2150 | "lodash._basetostring": { 2151 | "version": "3.0.1", 2152 | "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", 2153 | "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", 2154 | "dev": true 2155 | }, 2156 | "lodash._basevalues": { 2157 | "version": "3.0.0", 2158 | "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", 2159 | "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", 2160 | "dev": true 2161 | }, 2162 | "lodash._getnative": { 2163 | "version": "3.9.1", 2164 | "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", 2165 | "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", 2166 | "dev": true 2167 | }, 2168 | "lodash._isiterateecall": { 2169 | "version": "3.0.9", 2170 | "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", 2171 | "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", 2172 | "dev": true 2173 | }, 2174 | "lodash._reescape": { 2175 | "version": "3.0.0", 2176 | "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", 2177 | "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", 2178 | "dev": true 2179 | }, 2180 | "lodash._reevaluate": { 2181 | "version": "3.0.0", 2182 | "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", 2183 | "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", 2184 | "dev": true 2185 | }, 2186 | "lodash._reinterpolate": { 2187 | "version": "3.0.0", 2188 | "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", 2189 | "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", 2190 | "dev": true 2191 | }, 2192 | "lodash._root": { 2193 | "version": "3.0.1", 2194 | "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", 2195 | "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", 2196 | "dev": true 2197 | }, 2198 | "lodash.assign": { 2199 | "version": "4.2.0", 2200 | "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", 2201 | "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", 2202 | "dev": true 2203 | }, 2204 | "lodash.escape": { 2205 | "version": "3.2.0", 2206 | "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", 2207 | "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", 2208 | "dev": true, 2209 | "requires": { 2210 | "lodash._root": "3.0.1" 2211 | } 2212 | }, 2213 | "lodash.includes": { 2214 | "version": "4.3.0", 2215 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 2216 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=", 2217 | "dev": true 2218 | }, 2219 | "lodash.isarguments": { 2220 | "version": "3.1.0", 2221 | "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", 2222 | "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", 2223 | "dev": true 2224 | }, 2225 | "lodash.isarray": { 2226 | "version": "3.0.4", 2227 | "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", 2228 | "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", 2229 | "dev": true 2230 | }, 2231 | "lodash.keys": { 2232 | "version": "3.1.2", 2233 | "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", 2234 | "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", 2235 | "dev": true, 2236 | "requires": { 2237 | "lodash._getnative": "3.9.1", 2238 | "lodash.isarguments": "3.1.0", 2239 | "lodash.isarray": "3.0.4" 2240 | } 2241 | }, 2242 | "lodash.partition": { 2243 | "version": "4.6.0", 2244 | "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz", 2245 | "integrity": "sha1-o45GtzRp4EILDaEhLmbUFL42S6Q=", 2246 | "dev": true 2247 | }, 2248 | "lodash.pickby": { 2249 | "version": "4.6.0", 2250 | "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", 2251 | "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", 2252 | "dev": true 2253 | }, 2254 | "lodash.restparam": { 2255 | "version": "3.6.1", 2256 | "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", 2257 | "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", 2258 | "dev": true 2259 | }, 2260 | "lodash.template": { 2261 | "version": "3.6.2", 2262 | "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", 2263 | "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", 2264 | "dev": true, 2265 | "requires": { 2266 | "lodash._basecopy": "3.0.1", 2267 | "lodash._basetostring": "3.0.1", 2268 | "lodash._basevalues": "3.0.0", 2269 | "lodash._isiterateecall": "3.0.9", 2270 | "lodash._reinterpolate": "3.0.0", 2271 | "lodash.escape": "3.2.0", 2272 | "lodash.keys": "3.1.2", 2273 | "lodash.restparam": "3.6.1", 2274 | "lodash.templatesettings": "3.1.1" 2275 | } 2276 | }, 2277 | "lodash.templatesettings": { 2278 | "version": "3.1.1", 2279 | "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", 2280 | "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", 2281 | "dev": true, 2282 | "requires": { 2283 | "lodash._reinterpolate": "3.0.0", 2284 | "lodash.escape": "3.2.0" 2285 | } 2286 | }, 2287 | "longest": { 2288 | "version": "1.0.1", 2289 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 2290 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 2291 | "dev": true 2292 | }, 2293 | "loose-envify": { 2294 | "version": "1.3.1", 2295 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 2296 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 2297 | "dev": true, 2298 | "requires": { 2299 | "js-tokens": "3.0.2" 2300 | } 2301 | }, 2302 | "loud-rejection": { 2303 | "version": "1.6.0", 2304 | "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", 2305 | "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", 2306 | "dev": true, 2307 | "requires": { 2308 | "currently-unhandled": "0.4.1", 2309 | "signal-exit": "3.0.2" 2310 | } 2311 | }, 2312 | "make-error": { 2313 | "version": "1.3.0", 2314 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", 2315 | "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", 2316 | "dev": true 2317 | }, 2318 | "makeerror": { 2319 | "version": "1.0.11", 2320 | "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", 2321 | "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", 2322 | "dev": true, 2323 | "requires": { 2324 | "tmpl": "1.0.4" 2325 | } 2326 | }, 2327 | "map-obj": { 2328 | "version": "1.0.1", 2329 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 2330 | "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", 2331 | "dev": true 2332 | }, 2333 | "meow": { 2334 | "version": "3.7.0", 2335 | "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", 2336 | "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", 2337 | "dev": true, 2338 | "requires": { 2339 | "camelcase-keys": "2.1.0", 2340 | "decamelize": "1.2.0", 2341 | "loud-rejection": "1.6.0", 2342 | "map-obj": "1.0.1", 2343 | "minimist": "1.2.0", 2344 | "normalize-package-data": "2.4.0", 2345 | "object-assign": "4.1.1", 2346 | "read-pkg-up": "1.0.1", 2347 | "redent": "1.0.0", 2348 | "trim-newlines": "1.0.0" 2349 | }, 2350 | "dependencies": { 2351 | "minimist": { 2352 | "version": "1.2.0", 2353 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 2354 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 2355 | "dev": true 2356 | } 2357 | } 2358 | }, 2359 | "merge": { 2360 | "version": "1.2.0", 2361 | "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", 2362 | "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", 2363 | "dev": true 2364 | }, 2365 | "micromatch": { 2366 | "version": "2.3.11", 2367 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", 2368 | "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", 2369 | "dev": true, 2370 | "requires": { 2371 | "arr-diff": "2.0.0", 2372 | "array-unique": "0.2.1", 2373 | "braces": "1.8.5", 2374 | "expand-brackets": "0.1.5", 2375 | "extglob": "0.3.2", 2376 | "filename-regex": "2.0.1", 2377 | "is-extglob": "1.0.0", 2378 | "is-glob": "2.0.1", 2379 | "kind-of": "3.2.2", 2380 | "normalize-path": "2.1.1", 2381 | "object.omit": "2.0.1", 2382 | "parse-glob": "3.0.4", 2383 | "regex-cache": "0.4.3" 2384 | } 2385 | }, 2386 | "mime-db": { 2387 | "version": "1.29.0", 2388 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", 2389 | "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=", 2390 | "dev": true 2391 | }, 2392 | "mime-types": { 2393 | "version": "2.1.16", 2394 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", 2395 | "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", 2396 | "dev": true, 2397 | "requires": { 2398 | "mime-db": "1.29.0" 2399 | } 2400 | }, 2401 | "min-heap": { 2402 | "version": "0.2.3", 2403 | "resolved": "https://registry.npmjs.org/min-heap/-/min-heap-0.2.3.tgz", 2404 | "integrity": "sha1-Hr7ffMU0fWpZfRoVGWyXwiMATiQ=" 2405 | }, 2406 | "minimatch": { 2407 | "version": "3.0.4", 2408 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2409 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2410 | "dev": true, 2411 | "requires": { 2412 | "brace-expansion": "1.1.8" 2413 | } 2414 | }, 2415 | "minimist": { 2416 | "version": "0.0.8", 2417 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 2418 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 2419 | "dev": true 2420 | }, 2421 | "mkdirp": { 2422 | "version": "0.5.1", 2423 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 2424 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 2425 | "dev": true, 2426 | "requires": { 2427 | "minimist": "0.0.8" 2428 | } 2429 | }, 2430 | "ms": { 2431 | "version": "2.0.0", 2432 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2433 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 2434 | "dev": true 2435 | }, 2436 | "multipipe": { 2437 | "version": "0.1.2", 2438 | "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", 2439 | "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", 2440 | "dev": true, 2441 | "requires": { 2442 | "duplexer2": "0.0.2" 2443 | } 2444 | }, 2445 | "natural-compare": { 2446 | "version": "1.4.0", 2447 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2448 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2449 | "dev": true 2450 | }, 2451 | "node-int64": { 2452 | "version": "0.4.0", 2453 | "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", 2454 | "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", 2455 | "dev": true 2456 | }, 2457 | "node-notifier": { 2458 | "version": "5.1.2", 2459 | "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", 2460 | "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", 2461 | "dev": true, 2462 | "requires": { 2463 | "growly": "1.3.0", 2464 | "semver": "5.4.1", 2465 | "shellwords": "0.1.0", 2466 | "which": "1.3.0" 2467 | } 2468 | }, 2469 | "nopt": { 2470 | "version": "3.0.6", 2471 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 2472 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 2473 | "dev": true, 2474 | "requires": { 2475 | "abbrev": "1.0.9" 2476 | } 2477 | }, 2478 | "normalize-package-data": { 2479 | "version": "2.4.0", 2480 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 2481 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 2482 | "dev": true, 2483 | "requires": { 2484 | "hosted-git-info": "2.5.0", 2485 | "is-builtin-module": "1.0.0", 2486 | "semver": "5.4.1", 2487 | "validate-npm-package-license": "3.0.1" 2488 | } 2489 | }, 2490 | "normalize-path": { 2491 | "version": "2.1.1", 2492 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", 2493 | "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", 2494 | "dev": true, 2495 | "requires": { 2496 | "remove-trailing-separator": "1.0.2" 2497 | } 2498 | }, 2499 | "number-is-nan": { 2500 | "version": "1.0.1", 2501 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 2502 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 2503 | "dev": true 2504 | }, 2505 | "nwmatcher": { 2506 | "version": "1.4.1", 2507 | "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.1.tgz", 2508 | "integrity": "sha1-eumwew6oBNt+JfBctf5Al9TklJ8=", 2509 | "dev": true 2510 | }, 2511 | "oauth-sign": { 2512 | "version": "0.8.2", 2513 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 2514 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", 2515 | "dev": true 2516 | }, 2517 | "object-assign": { 2518 | "version": "4.1.1", 2519 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2520 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 2521 | "dev": true 2522 | }, 2523 | "object.omit": { 2524 | "version": "2.0.1", 2525 | "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", 2526 | "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", 2527 | "dev": true, 2528 | "requires": { 2529 | "for-own": "0.1.5", 2530 | "is-extendable": "0.1.1" 2531 | } 2532 | }, 2533 | "once": { 2534 | "version": "1.4.0", 2535 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2536 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2537 | "dev": true, 2538 | "requires": { 2539 | "wrappy": "1.0.2" 2540 | } 2541 | }, 2542 | "optimist": { 2543 | "version": "0.6.1", 2544 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 2545 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 2546 | "dev": true, 2547 | "requires": { 2548 | "minimist": "0.0.8", 2549 | "wordwrap": "0.0.3" 2550 | } 2551 | }, 2552 | "optionator": { 2553 | "version": "0.8.2", 2554 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 2555 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 2556 | "dev": true, 2557 | "requires": { 2558 | "deep-is": "0.1.3", 2559 | "fast-levenshtein": "2.0.6", 2560 | "levn": "0.3.0", 2561 | "prelude-ls": "1.1.2", 2562 | "type-check": "0.3.2", 2563 | "wordwrap": "1.0.0" 2564 | }, 2565 | "dependencies": { 2566 | "wordwrap": { 2567 | "version": "1.0.0", 2568 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2569 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2570 | "dev": true 2571 | } 2572 | } 2573 | }, 2574 | "os-homedir": { 2575 | "version": "1.0.2", 2576 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 2577 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 2578 | "dev": true 2579 | }, 2580 | "os-locale": { 2581 | "version": "1.4.0", 2582 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", 2583 | "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", 2584 | "dev": true, 2585 | "requires": { 2586 | "lcid": "1.0.0" 2587 | } 2588 | }, 2589 | "os-tmpdir": { 2590 | "version": "1.0.2", 2591 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 2592 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 2593 | "dev": true 2594 | }, 2595 | "p-limit": { 2596 | "version": "1.1.0", 2597 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", 2598 | "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", 2599 | "dev": true 2600 | }, 2601 | "p-locate": { 2602 | "version": "2.0.0", 2603 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 2604 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 2605 | "dev": true, 2606 | "requires": { 2607 | "p-limit": "1.1.0" 2608 | } 2609 | }, 2610 | "parse-glob": { 2611 | "version": "3.0.4", 2612 | "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", 2613 | "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", 2614 | "dev": true, 2615 | "requires": { 2616 | "glob-base": "0.3.0", 2617 | "is-dotfile": "1.0.3", 2618 | "is-extglob": "1.0.0", 2619 | "is-glob": "2.0.1" 2620 | } 2621 | }, 2622 | "parse-json": { 2623 | "version": "2.2.0", 2624 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 2625 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 2626 | "dev": true, 2627 | "requires": { 2628 | "error-ex": "1.3.1" 2629 | } 2630 | }, 2631 | "parse5": { 2632 | "version": "1.5.1", 2633 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", 2634 | "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", 2635 | "dev": true 2636 | }, 2637 | "path-exists": { 2638 | "version": "3.0.0", 2639 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 2640 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 2641 | "dev": true 2642 | }, 2643 | "path-is-absolute": { 2644 | "version": "1.0.1", 2645 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2646 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2647 | "dev": true 2648 | }, 2649 | "path-parse": { 2650 | "version": "1.0.5", 2651 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 2652 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 2653 | "dev": true 2654 | }, 2655 | "path-type": { 2656 | "version": "1.1.0", 2657 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", 2658 | "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", 2659 | "dev": true, 2660 | "requires": { 2661 | "graceful-fs": "4.1.11", 2662 | "pify": "2.3.0", 2663 | "pinkie-promise": "2.0.1" 2664 | } 2665 | }, 2666 | "performance-now": { 2667 | "version": "0.2.0", 2668 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", 2669 | "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", 2670 | "dev": true 2671 | }, 2672 | "pify": { 2673 | "version": "2.3.0", 2674 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 2675 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 2676 | "dev": true 2677 | }, 2678 | "pinkie": { 2679 | "version": "2.0.4", 2680 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 2681 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 2682 | "dev": true 2683 | }, 2684 | "pinkie-promise": { 2685 | "version": "2.0.1", 2686 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 2687 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 2688 | "dev": true, 2689 | "requires": { 2690 | "pinkie": "2.0.4" 2691 | } 2692 | }, 2693 | "prelude-ls": { 2694 | "version": "1.1.2", 2695 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 2696 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 2697 | "dev": true 2698 | }, 2699 | "preserve": { 2700 | "version": "0.2.0", 2701 | "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", 2702 | "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", 2703 | "dev": true 2704 | }, 2705 | "pretty-format": { 2706 | "version": "19.0.0", 2707 | "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-19.0.0.tgz", 2708 | "integrity": "sha1-VlMNMqy5ij+khRxOK503tCBoTIQ=", 2709 | "dev": true, 2710 | "requires": { 2711 | "ansi-styles": "3.2.0" 2712 | }, 2713 | "dependencies": { 2714 | "ansi-styles": { 2715 | "version": "3.2.0", 2716 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", 2717 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", 2718 | "dev": true, 2719 | "requires": { 2720 | "color-convert": "1.9.0" 2721 | } 2722 | } 2723 | } 2724 | }, 2725 | "private": { 2726 | "version": "0.1.7", 2727 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", 2728 | "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", 2729 | "dev": true 2730 | }, 2731 | "process-nextick-args": { 2732 | "version": "1.0.7", 2733 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 2734 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", 2735 | "dev": true 2736 | }, 2737 | "prr": { 2738 | "version": "0.0.0", 2739 | "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", 2740 | "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", 2741 | "dev": true 2742 | }, 2743 | "punycode": { 2744 | "version": "1.4.1", 2745 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2746 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 2747 | "dev": true 2748 | }, 2749 | "qs": { 2750 | "version": "6.4.0", 2751 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", 2752 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", 2753 | "dev": true 2754 | }, 2755 | "randomatic": { 2756 | "version": "1.1.7", 2757 | "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", 2758 | "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", 2759 | "dev": true, 2760 | "requires": { 2761 | "is-number": "3.0.0", 2762 | "kind-of": "4.0.0" 2763 | }, 2764 | "dependencies": { 2765 | "is-number": { 2766 | "version": "3.0.0", 2767 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", 2768 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", 2769 | "dev": true, 2770 | "requires": { 2771 | "kind-of": "3.2.2" 2772 | }, 2773 | "dependencies": { 2774 | "kind-of": { 2775 | "version": "3.2.2", 2776 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 2777 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 2778 | "dev": true, 2779 | "requires": { 2780 | "is-buffer": "1.1.5" 2781 | } 2782 | } 2783 | } 2784 | }, 2785 | "kind-of": { 2786 | "version": "4.0.0", 2787 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", 2788 | "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", 2789 | "dev": true, 2790 | "requires": { 2791 | "is-buffer": "1.1.5" 2792 | } 2793 | } 2794 | } 2795 | }, 2796 | "read-pkg": { 2797 | "version": "1.1.0", 2798 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", 2799 | "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", 2800 | "dev": true, 2801 | "requires": { 2802 | "load-json-file": "1.1.0", 2803 | "normalize-package-data": "2.4.0", 2804 | "path-type": "1.1.0" 2805 | } 2806 | }, 2807 | "read-pkg-up": { 2808 | "version": "1.0.1", 2809 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", 2810 | "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", 2811 | "dev": true, 2812 | "requires": { 2813 | "find-up": "1.1.2", 2814 | "read-pkg": "1.1.0" 2815 | }, 2816 | "dependencies": { 2817 | "find-up": { 2818 | "version": "1.1.2", 2819 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 2820 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 2821 | "dev": true, 2822 | "requires": { 2823 | "path-exists": "2.1.0", 2824 | "pinkie-promise": "2.0.1" 2825 | } 2826 | }, 2827 | "path-exists": { 2828 | "version": "2.1.0", 2829 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 2830 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 2831 | "dev": true, 2832 | "requires": { 2833 | "pinkie-promise": "2.0.1" 2834 | } 2835 | } 2836 | } 2837 | }, 2838 | "readable-stream": { 2839 | "version": "1.1.14", 2840 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 2841 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 2842 | "dev": true, 2843 | "requires": { 2844 | "core-util-is": "1.0.2", 2845 | "inherits": "2.0.3", 2846 | "isarray": "0.0.1", 2847 | "string_decoder": "0.10.31" 2848 | }, 2849 | "dependencies": { 2850 | "isarray": { 2851 | "version": "0.0.1", 2852 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 2853 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 2854 | "dev": true 2855 | } 2856 | } 2857 | }, 2858 | "redent": { 2859 | "version": "1.0.0", 2860 | "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", 2861 | "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", 2862 | "dev": true, 2863 | "requires": { 2864 | "indent-string": "2.1.0", 2865 | "strip-indent": "1.0.1" 2866 | } 2867 | }, 2868 | "regenerator-runtime": { 2869 | "version": "0.10.5", 2870 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", 2871 | "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", 2872 | "dev": true 2873 | }, 2874 | "regex-cache": { 2875 | "version": "0.4.3", 2876 | "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", 2877 | "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", 2878 | "dev": true, 2879 | "requires": { 2880 | "is-equal-shallow": "0.1.3", 2881 | "is-primitive": "2.0.0" 2882 | } 2883 | }, 2884 | "remap-istanbul": { 2885 | "version": "0.9.5", 2886 | "resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.9.5.tgz", 2887 | "integrity": "sha1-oYYXsfMe7Fp9vud1OCmLd1YGqqg=", 2888 | "dev": true, 2889 | "requires": { 2890 | "amdefine": "1.0.1", 2891 | "gulp-util": "3.0.7", 2892 | "istanbul": "0.4.5", 2893 | "minimatch": "3.0.4", 2894 | "source-map": "0.5.6", 2895 | "through2": "2.0.1" 2896 | } 2897 | }, 2898 | "remove-trailing-separator": { 2899 | "version": "1.0.2", 2900 | "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", 2901 | "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", 2902 | "dev": true 2903 | }, 2904 | "repeat-element": { 2905 | "version": "1.1.2", 2906 | "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", 2907 | "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", 2908 | "dev": true 2909 | }, 2910 | "repeat-string": { 2911 | "version": "1.6.1", 2912 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 2913 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 2914 | "dev": true 2915 | }, 2916 | "repeating": { 2917 | "version": "2.0.1", 2918 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 2919 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 2920 | "dev": true, 2921 | "requires": { 2922 | "is-finite": "1.0.2" 2923 | } 2924 | }, 2925 | "replace-ext": { 2926 | "version": "0.0.1", 2927 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", 2928 | "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", 2929 | "dev": true 2930 | }, 2931 | "request": { 2932 | "version": "2.81.0", 2933 | "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", 2934 | "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", 2935 | "dev": true, 2936 | "requires": { 2937 | "aws-sign2": "0.6.0", 2938 | "aws4": "1.6.0", 2939 | "caseless": "0.12.0", 2940 | "combined-stream": "1.0.5", 2941 | "extend": "3.0.1", 2942 | "forever-agent": "0.6.1", 2943 | "form-data": "2.1.4", 2944 | "har-validator": "4.2.1", 2945 | "hawk": "3.1.3", 2946 | "http-signature": "1.1.1", 2947 | "is-typedarray": "1.0.0", 2948 | "isstream": "0.1.2", 2949 | "json-stringify-safe": "5.0.1", 2950 | "mime-types": "2.1.16", 2951 | "oauth-sign": "0.8.2", 2952 | "performance-now": "0.2.0", 2953 | "qs": "6.4.0", 2954 | "safe-buffer": "5.1.1", 2955 | "stringstream": "0.0.5", 2956 | "tough-cookie": "2.3.2", 2957 | "tunnel-agent": "0.6.0", 2958 | "uuid": "3.1.0" 2959 | } 2960 | }, 2961 | "require-directory": { 2962 | "version": "2.1.1", 2963 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2964 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 2965 | "dev": true 2966 | }, 2967 | "require-main-filename": { 2968 | "version": "1.0.1", 2969 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", 2970 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", 2971 | "dev": true 2972 | }, 2973 | "resolve": { 2974 | "version": "1.4.0", 2975 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 2976 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 2977 | "dev": true, 2978 | "requires": { 2979 | "path-parse": "1.0.5" 2980 | } 2981 | }, 2982 | "right-align": { 2983 | "version": "0.1.3", 2984 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 2985 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 2986 | "dev": true, 2987 | "optional": true, 2988 | "requires": { 2989 | "align-text": "0.1.4" 2990 | } 2991 | }, 2992 | "rimraf": { 2993 | "version": "2.6.1", 2994 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", 2995 | "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", 2996 | "dev": true, 2997 | "requires": { 2998 | "glob": "7.1.2" 2999 | } 3000 | }, 3001 | "safe-buffer": { 3002 | "version": "5.1.1", 3003 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 3004 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 3005 | "dev": true 3006 | }, 3007 | "sane": { 3008 | "version": "1.5.0", 3009 | "resolved": "https://registry.npmjs.org/sane/-/sane-1.5.0.tgz", 3010 | "integrity": "sha1-pK3q52TQSGIeyyfV+ez1ExAZOfM=", 3011 | "dev": true, 3012 | "requires": { 3013 | "anymatch": "1.3.2", 3014 | "exec-sh": "0.2.0", 3015 | "fb-watchman": "1.9.2", 3016 | "minimatch": "3.0.4", 3017 | "minimist": "1.2.0", 3018 | "walker": "1.0.7", 3019 | "watch": "0.10.0" 3020 | }, 3021 | "dependencies": { 3022 | "bser": { 3023 | "version": "1.0.2", 3024 | "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", 3025 | "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", 3026 | "dev": true, 3027 | "requires": { 3028 | "node-int64": "0.4.0" 3029 | } 3030 | }, 3031 | "fb-watchman": { 3032 | "version": "1.9.2", 3033 | "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", 3034 | "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", 3035 | "dev": true, 3036 | "requires": { 3037 | "bser": "1.0.2" 3038 | } 3039 | }, 3040 | "minimist": { 3041 | "version": "1.2.0", 3042 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 3043 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 3044 | "dev": true 3045 | } 3046 | } 3047 | }, 3048 | "sax": { 3049 | "version": "1.2.4", 3050 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", 3051 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", 3052 | "dev": true 3053 | }, 3054 | "semver": { 3055 | "version": "5.4.1", 3056 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 3057 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", 3058 | "dev": true 3059 | }, 3060 | "set-blocking": { 3061 | "version": "2.0.0", 3062 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 3063 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 3064 | "dev": true 3065 | }, 3066 | "shellwords": { 3067 | "version": "0.1.0", 3068 | "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", 3069 | "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=", 3070 | "dev": true 3071 | }, 3072 | "signal-exit": { 3073 | "version": "3.0.2", 3074 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 3075 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 3076 | "dev": true 3077 | }, 3078 | "slash": { 3079 | "version": "1.0.0", 3080 | "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", 3081 | "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", 3082 | "dev": true 3083 | }, 3084 | "sntp": { 3085 | "version": "1.0.9", 3086 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", 3087 | "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", 3088 | "dev": true, 3089 | "requires": { 3090 | "hoek": "2.16.3" 3091 | } 3092 | }, 3093 | "source-map": { 3094 | "version": "0.5.6", 3095 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", 3096 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", 3097 | "dev": true 3098 | }, 3099 | "source-map-support": { 3100 | "version": "0.4.15", 3101 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", 3102 | "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", 3103 | "dev": true, 3104 | "requires": { 3105 | "source-map": "0.5.6" 3106 | } 3107 | }, 3108 | "sparkles": { 3109 | "version": "1.0.0", 3110 | "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", 3111 | "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", 3112 | "dev": true 3113 | }, 3114 | "spdx-correct": { 3115 | "version": "1.0.2", 3116 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", 3117 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", 3118 | "dev": true, 3119 | "requires": { 3120 | "spdx-license-ids": "1.2.2" 3121 | } 3122 | }, 3123 | "spdx-expression-parse": { 3124 | "version": "1.0.4", 3125 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", 3126 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", 3127 | "dev": true 3128 | }, 3129 | "spdx-license-ids": { 3130 | "version": "1.2.2", 3131 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", 3132 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", 3133 | "dev": true 3134 | }, 3135 | "sprintf-js": { 3136 | "version": "1.0.3", 3137 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 3138 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 3139 | "dev": true 3140 | }, 3141 | "sshpk": { 3142 | "version": "1.13.1", 3143 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", 3144 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", 3145 | "dev": true, 3146 | "requires": { 3147 | "asn1": "0.2.3", 3148 | "assert-plus": "1.0.0", 3149 | "bcrypt-pbkdf": "1.0.1", 3150 | "dashdash": "1.14.1", 3151 | "ecc-jsbn": "0.1.1", 3152 | "getpass": "0.1.7", 3153 | "jsbn": "0.1.1", 3154 | "tweetnacl": "0.14.5" 3155 | }, 3156 | "dependencies": { 3157 | "assert-plus": { 3158 | "version": "1.0.0", 3159 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 3160 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 3161 | "dev": true 3162 | } 3163 | } 3164 | }, 3165 | "string_decoder": { 3166 | "version": "0.10.31", 3167 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 3168 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 3169 | "dev": true 3170 | }, 3171 | "string-length": { 3172 | "version": "1.0.1", 3173 | "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", 3174 | "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", 3175 | "dev": true, 3176 | "requires": { 3177 | "strip-ansi": "3.0.1" 3178 | } 3179 | }, 3180 | "string-width": { 3181 | "version": "1.0.2", 3182 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 3183 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 3184 | "dev": true, 3185 | "requires": { 3186 | "code-point-at": "1.1.0", 3187 | "is-fullwidth-code-point": "1.0.0", 3188 | "strip-ansi": "3.0.1" 3189 | } 3190 | }, 3191 | "stringstream": { 3192 | "version": "0.0.5", 3193 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 3194 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", 3195 | "dev": true 3196 | }, 3197 | "strip-ansi": { 3198 | "version": "3.0.1", 3199 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 3200 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 3201 | "dev": true, 3202 | "requires": { 3203 | "ansi-regex": "2.1.1" 3204 | } 3205 | }, 3206 | "strip-bom": { 3207 | "version": "2.0.0", 3208 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 3209 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 3210 | "dev": true, 3211 | "requires": { 3212 | "is-utf8": "0.2.1" 3213 | } 3214 | }, 3215 | "strip-indent": { 3216 | "version": "1.0.1", 3217 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", 3218 | "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", 3219 | "dev": true, 3220 | "requires": { 3221 | "get-stdin": "4.0.1" 3222 | } 3223 | }, 3224 | "strip-json-comments": { 3225 | "version": "2.0.1", 3226 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 3227 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 3228 | "dev": true 3229 | }, 3230 | "supports-color": { 3231 | "version": "2.0.0", 3232 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 3233 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 3234 | "dev": true 3235 | }, 3236 | "symbol-tree": { 3237 | "version": "3.2.2", 3238 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", 3239 | "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", 3240 | "dev": true 3241 | }, 3242 | "test-exclude": { 3243 | "version": "4.1.1", 3244 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", 3245 | "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", 3246 | "dev": true, 3247 | "requires": { 3248 | "arrify": "1.0.1", 3249 | "micromatch": "2.3.11", 3250 | "object-assign": "4.1.1", 3251 | "read-pkg-up": "1.0.1", 3252 | "require-main-filename": "1.0.1" 3253 | } 3254 | }, 3255 | "throat": { 3256 | "version": "3.2.0", 3257 | "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", 3258 | "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==", 3259 | "dev": true 3260 | }, 3261 | "through2": { 3262 | "version": "2.0.1", 3263 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz", 3264 | "integrity": "sha1-OE51MU1J8y3hLuu4E2uOtrXVnak=", 3265 | "dev": true, 3266 | "requires": { 3267 | "readable-stream": "2.0.6", 3268 | "xtend": "4.0.1" 3269 | }, 3270 | "dependencies": { 3271 | "readable-stream": { 3272 | "version": "2.0.6", 3273 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", 3274 | "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", 3275 | "dev": true, 3276 | "requires": { 3277 | "core-util-is": "1.0.2", 3278 | "inherits": "2.0.3", 3279 | "isarray": "1.0.0", 3280 | "process-nextick-args": "1.0.7", 3281 | "string_decoder": "0.10.31", 3282 | "util-deprecate": "1.0.2" 3283 | } 3284 | } 3285 | } 3286 | }, 3287 | "time-stamp": { 3288 | "version": "1.1.0", 3289 | "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", 3290 | "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", 3291 | "dev": true 3292 | }, 3293 | "tmpl": { 3294 | "version": "1.0.4", 3295 | "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", 3296 | "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", 3297 | "dev": true 3298 | }, 3299 | "to-fast-properties": { 3300 | "version": "1.0.3", 3301 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 3302 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", 3303 | "dev": true 3304 | }, 3305 | "tough-cookie": { 3306 | "version": "2.3.2", 3307 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", 3308 | "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", 3309 | "dev": true, 3310 | "requires": { 3311 | "punycode": "1.4.1" 3312 | } 3313 | }, 3314 | "tr46": { 3315 | "version": "0.0.3", 3316 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 3317 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", 3318 | "dev": true 3319 | }, 3320 | "trim-newlines": { 3321 | "version": "1.0.0", 3322 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", 3323 | "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", 3324 | "dev": true 3325 | }, 3326 | "trim-right": { 3327 | "version": "1.0.1", 3328 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", 3329 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", 3330 | "dev": true 3331 | }, 3332 | "ts-jest": { 3333 | "version": "19.0.14", 3334 | "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-19.0.14.tgz", 3335 | "integrity": "sha1-iGdLlW4Ej2GwqyjUIb/au7ZBvlw=", 3336 | "dev": true, 3337 | "requires": { 3338 | "babel-jest": "19.0.0", 3339 | "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", 3340 | "fs-extra": "2.1.2", 3341 | "glob-all": "3.1.0", 3342 | "istanbul-lib-instrument": "1.7.4", 3343 | "jest-config": "19.0.4", 3344 | "jest-util": "19.0.2", 3345 | "lodash.assign": "4.2.0", 3346 | "lodash.includes": "4.3.0", 3347 | "lodash.partition": "4.6.0", 3348 | "lodash.pickby": "4.6.0", 3349 | "remap-istanbul": "0.9.5", 3350 | "source-map-support": "0.4.15", 3351 | "tsconfig": "6.0.0", 3352 | "yargs": "7.1.0" 3353 | }, 3354 | "dependencies": { 3355 | "camelcase": { 3356 | "version": "3.0.0", 3357 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", 3358 | "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", 3359 | "dev": true 3360 | }, 3361 | "cliui": { 3362 | "version": "3.2.0", 3363 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 3364 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", 3365 | "dev": true, 3366 | "requires": { 3367 | "string-width": "1.0.2", 3368 | "strip-ansi": "3.0.1", 3369 | "wrap-ansi": "2.1.0" 3370 | } 3371 | }, 3372 | "yargs": { 3373 | "version": "7.1.0", 3374 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", 3375 | "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", 3376 | "dev": true, 3377 | "requires": { 3378 | "camelcase": "3.0.0", 3379 | "cliui": "3.2.0", 3380 | "decamelize": "1.2.0", 3381 | "get-caller-file": "1.0.2", 3382 | "os-locale": "1.4.0", 3383 | "read-pkg-up": "1.0.1", 3384 | "require-directory": "2.1.1", 3385 | "require-main-filename": "1.0.1", 3386 | "set-blocking": "2.0.0", 3387 | "string-width": "1.0.2", 3388 | "which-module": "1.0.0", 3389 | "y18n": "3.2.1", 3390 | "yargs-parser": "5.0.0" 3391 | } 3392 | }, 3393 | "yargs-parser": { 3394 | "version": "5.0.0", 3395 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", 3396 | "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", 3397 | "dev": true, 3398 | "requires": { 3399 | "camelcase": "3.0.0" 3400 | } 3401 | } 3402 | } 3403 | }, 3404 | "ts-node": { 3405 | "version": "3.3.0", 3406 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", 3407 | "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", 3408 | "dev": true, 3409 | "requires": { 3410 | "arrify": "1.0.1", 3411 | "chalk": "2.0.1", 3412 | "diff": "3.3.0", 3413 | "make-error": "1.3.0", 3414 | "minimist": "1.2.0", 3415 | "mkdirp": "0.5.1", 3416 | "source-map-support": "0.4.15", 3417 | "tsconfig": "6.0.0", 3418 | "v8flags": "3.0.0", 3419 | "yn": "2.0.0" 3420 | }, 3421 | "dependencies": { 3422 | "ansi-styles": { 3423 | "version": "3.2.0", 3424 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", 3425 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", 3426 | "dev": true, 3427 | "requires": { 3428 | "color-convert": "1.9.0" 3429 | } 3430 | }, 3431 | "chalk": { 3432 | "version": "2.0.1", 3433 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", 3434 | "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", 3435 | "dev": true, 3436 | "requires": { 3437 | "ansi-styles": "3.2.0", 3438 | "escape-string-regexp": "1.0.5", 3439 | "supports-color": "4.2.1" 3440 | } 3441 | }, 3442 | "has-flag": { 3443 | "version": "2.0.0", 3444 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 3445 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", 3446 | "dev": true 3447 | }, 3448 | "minimist": { 3449 | "version": "1.2.0", 3450 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 3451 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 3452 | "dev": true 3453 | }, 3454 | "supports-color": { 3455 | "version": "4.2.1", 3456 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", 3457 | "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", 3458 | "dev": true, 3459 | "requires": { 3460 | "has-flag": "2.0.0" 3461 | } 3462 | } 3463 | } 3464 | }, 3465 | "tsconfig": { 3466 | "version": "6.0.0", 3467 | "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", 3468 | "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", 3469 | "dev": true, 3470 | "requires": { 3471 | "strip-bom": "3.0.0", 3472 | "strip-json-comments": "2.0.1" 3473 | }, 3474 | "dependencies": { 3475 | "strip-bom": { 3476 | "version": "3.0.0", 3477 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 3478 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", 3479 | "dev": true 3480 | } 3481 | } 3482 | }, 3483 | "tslib": { 3484 | "version": "1.7.1", 3485 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.7.1.tgz", 3486 | "integrity": "sha1-vIAEFkaRkjp5/oN4u+s9ogF1OOw=", 3487 | "dev": true 3488 | }, 3489 | "tslint": { 3490 | "version": "5.5.0", 3491 | "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.5.0.tgz", 3492 | "integrity": "sha1-EOjas+MGH6YelELozuOYKs8gpqo=", 3493 | "dev": true, 3494 | "requires": { 3495 | "babel-code-frame": "6.22.0", 3496 | "colors": "1.1.2", 3497 | "commander": "2.11.0", 3498 | "diff": "3.3.0", 3499 | "glob": "7.1.2", 3500 | "minimatch": "3.0.4", 3501 | "resolve": "1.4.0", 3502 | "semver": "5.4.1", 3503 | "tslib": "1.7.1", 3504 | "tsutils": "2.8.0" 3505 | } 3506 | }, 3507 | "tsutils": { 3508 | "version": "2.8.0", 3509 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.0.tgz", 3510 | "integrity": "sha1-AWAXNymzvxOGKN0UoVN+AIUdgUo=", 3511 | "dev": true, 3512 | "requires": { 3513 | "tslib": "1.7.1" 3514 | } 3515 | }, 3516 | "tunnel-agent": { 3517 | "version": "0.6.0", 3518 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 3519 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 3520 | "dev": true, 3521 | "requires": { 3522 | "safe-buffer": "5.1.1" 3523 | } 3524 | }, 3525 | "tweetnacl": { 3526 | "version": "0.14.5", 3527 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 3528 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 3529 | "dev": true, 3530 | "optional": true 3531 | }, 3532 | "type-check": { 3533 | "version": "0.3.2", 3534 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 3535 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 3536 | "dev": true, 3537 | "requires": { 3538 | "prelude-ls": "1.1.2" 3539 | } 3540 | }, 3541 | "typescript": { 3542 | "version": "2.4.2", 3543 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz", 3544 | "integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=", 3545 | "dev": true 3546 | }, 3547 | "uglify-js": { 3548 | "version": "2.8.29", 3549 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 3550 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 3551 | "dev": true, 3552 | "optional": true, 3553 | "requires": { 3554 | "source-map": "0.5.6", 3555 | "uglify-to-browserify": "1.0.2", 3556 | "yargs": "3.10.0" 3557 | }, 3558 | "dependencies": { 3559 | "yargs": { 3560 | "version": "3.10.0", 3561 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 3562 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 3563 | "dev": true, 3564 | "optional": true, 3565 | "requires": { 3566 | "camelcase": "1.2.1", 3567 | "cliui": "2.1.0", 3568 | "decamelize": "1.2.0", 3569 | "window-size": "0.1.0" 3570 | } 3571 | } 3572 | } 3573 | }, 3574 | "uglify-to-browserify": { 3575 | "version": "1.0.2", 3576 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 3577 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 3578 | "dev": true, 3579 | "optional": true 3580 | }, 3581 | "user-home": { 3582 | "version": "1.1.1", 3583 | "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", 3584 | "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", 3585 | "dev": true 3586 | }, 3587 | "util-deprecate": { 3588 | "version": "1.0.2", 3589 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 3590 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 3591 | "dev": true 3592 | }, 3593 | "uuid": { 3594 | "version": "3.1.0", 3595 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", 3596 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", 3597 | "dev": true 3598 | }, 3599 | "v8flags": { 3600 | "version": "3.0.0", 3601 | "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.0.tgz", 3602 | "integrity": "sha512-AGl+C+4qpeSu2g3JxCD/mGFFOs/vVZ3XREkD3ibQXEqr4Y4zgIrPWW124/IKJFHOIVFIoH8miWrLf0o84HYjwA==", 3603 | "dev": true, 3604 | "requires": { 3605 | "user-home": "1.1.1" 3606 | } 3607 | }, 3608 | "validate-npm-package-license": { 3609 | "version": "3.0.1", 3610 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", 3611 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", 3612 | "dev": true, 3613 | "requires": { 3614 | "spdx-correct": "1.0.2", 3615 | "spdx-expression-parse": "1.0.4" 3616 | } 3617 | }, 3618 | "verror": { 3619 | "version": "1.10.0", 3620 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 3621 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 3622 | "dev": true, 3623 | "requires": { 3624 | "assert-plus": "1.0.0", 3625 | "core-util-is": "1.0.2", 3626 | "extsprintf": "1.3.0" 3627 | }, 3628 | "dependencies": { 3629 | "assert-plus": { 3630 | "version": "1.0.0", 3631 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 3632 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 3633 | "dev": true 3634 | } 3635 | } 3636 | }, 3637 | "vinyl": { 3638 | "version": "0.5.3", 3639 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", 3640 | "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", 3641 | "dev": true, 3642 | "requires": { 3643 | "clone": "1.0.2", 3644 | "clone-stats": "0.0.1", 3645 | "replace-ext": "0.0.1" 3646 | } 3647 | }, 3648 | "walker": { 3649 | "version": "1.0.7", 3650 | "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", 3651 | "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", 3652 | "dev": true, 3653 | "requires": { 3654 | "makeerror": "1.0.11" 3655 | } 3656 | }, 3657 | "watch": { 3658 | "version": "0.10.0", 3659 | "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", 3660 | "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=", 3661 | "dev": true 3662 | }, 3663 | "webidl-conversions": { 3664 | "version": "4.0.1", 3665 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.1.tgz", 3666 | "integrity": "sha1-gBWherg+fhsxFjhIas6B2mziBqA=", 3667 | "dev": true 3668 | }, 3669 | "whatwg-encoding": { 3670 | "version": "1.0.1", 3671 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", 3672 | "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", 3673 | "dev": true, 3674 | "requires": { 3675 | "iconv-lite": "0.4.13" 3676 | } 3677 | }, 3678 | "whatwg-url": { 3679 | "version": "4.8.0", 3680 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", 3681 | "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", 3682 | "dev": true, 3683 | "requires": { 3684 | "tr46": "0.0.3", 3685 | "webidl-conversions": "3.0.1" 3686 | }, 3687 | "dependencies": { 3688 | "webidl-conversions": { 3689 | "version": "3.0.1", 3690 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 3691 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", 3692 | "dev": true 3693 | } 3694 | } 3695 | }, 3696 | "which": { 3697 | "version": "1.3.0", 3698 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", 3699 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", 3700 | "dev": true, 3701 | "requires": { 3702 | "isexe": "2.0.0" 3703 | } 3704 | }, 3705 | "which-module": { 3706 | "version": "1.0.0", 3707 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", 3708 | "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", 3709 | "dev": true 3710 | }, 3711 | "window-size": { 3712 | "version": "0.1.0", 3713 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 3714 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 3715 | "dev": true, 3716 | "optional": true 3717 | }, 3718 | "wordwrap": { 3719 | "version": "0.0.3", 3720 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 3721 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 3722 | "dev": true 3723 | }, 3724 | "worker-farm": { 3725 | "version": "1.4.1", 3726 | "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.4.1.tgz", 3727 | "integrity": "sha512-tgFAtgOYLPutkAyzgpS6VJFL5HY+0ui1Tvua+fITgz8ByaJTMFGtazR6xxQfwfiAcbwE+2fLG/K49wc2TfwCNw==", 3728 | "dev": true, 3729 | "requires": { 3730 | "errno": "0.1.4", 3731 | "xtend": "4.0.1" 3732 | } 3733 | }, 3734 | "wrap-ansi": { 3735 | "version": "2.1.0", 3736 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 3737 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 3738 | "dev": true, 3739 | "requires": { 3740 | "string-width": "1.0.2", 3741 | "strip-ansi": "3.0.1" 3742 | } 3743 | }, 3744 | "wrappy": { 3745 | "version": "1.0.2", 3746 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3747 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 3748 | "dev": true 3749 | }, 3750 | "xml-name-validator": { 3751 | "version": "2.0.1", 3752 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", 3753 | "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", 3754 | "dev": true 3755 | }, 3756 | "xtend": { 3757 | "version": "4.0.1", 3758 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 3759 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 3760 | "dev": true 3761 | }, 3762 | "y18n": { 3763 | "version": "3.2.1", 3764 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 3765 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", 3766 | "dev": true 3767 | }, 3768 | "yargs": { 3769 | "version": "6.6.0", 3770 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", 3771 | "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", 3772 | "dev": true, 3773 | "requires": { 3774 | "camelcase": "3.0.0", 3775 | "cliui": "3.2.0", 3776 | "decamelize": "1.2.0", 3777 | "get-caller-file": "1.0.2", 3778 | "os-locale": "1.4.0", 3779 | "read-pkg-up": "1.0.1", 3780 | "require-directory": "2.1.1", 3781 | "require-main-filename": "1.0.1", 3782 | "set-blocking": "2.0.0", 3783 | "string-width": "1.0.2", 3784 | "which-module": "1.0.0", 3785 | "y18n": "3.2.1", 3786 | "yargs-parser": "4.2.1" 3787 | }, 3788 | "dependencies": { 3789 | "camelcase": { 3790 | "version": "3.0.0", 3791 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", 3792 | "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", 3793 | "dev": true 3794 | }, 3795 | "cliui": { 3796 | "version": "3.2.0", 3797 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 3798 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", 3799 | "dev": true, 3800 | "requires": { 3801 | "string-width": "1.0.2", 3802 | "strip-ansi": "3.0.1", 3803 | "wrap-ansi": "2.1.0" 3804 | } 3805 | } 3806 | } 3807 | }, 3808 | "yargs-parser": { 3809 | "version": "4.2.1", 3810 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", 3811 | "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", 3812 | "dev": true, 3813 | "requires": { 3814 | "camelcase": "3.0.0" 3815 | }, 3816 | "dependencies": { 3817 | "camelcase": { 3818 | "version": "3.0.0", 3819 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", 3820 | "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", 3821 | "dev": true 3822 | } 3823 | } 3824 | }, 3825 | "yn": { 3826 | "version": "2.0.0", 3827 | "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", 3828 | "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", 3829 | "dev": true 3830 | } 3831 | } 3832 | } 3833 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pretty-sort", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "author": "Jiayi Hu ", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@types/jest": "^19.2.2", 13 | "@types/lodash": "^4.14.62", 14 | "@types/node": "^7.0.12", 15 | "jest": "^19.0.2", 16 | "ts-jest": "^19.0.9", 17 | "ts-node": "^3.0.2", 18 | "tslint": "^5.1.0", 19 | "typescript": "^2.2.2" 20 | }, 21 | "jest": { 22 | "transform": { 23 | ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js" 24 | }, 25 | "testRegex": "algorithms/.*/.*\\.spec\\.ts$", 26 | "moduleFileExtensions": [ 27 | "ts", 28 | "tsx", 29 | "js" 30 | ], 31 | "snapshotSerializers": [ 32 | "./tests/btree-serializer.js", 33 | "./tests/matrix-serializer.js" 34 | ] 35 | }, 36 | "dependencies": { 37 | "lodash": "^4.17.4", 38 | "min-heap": "^0.2.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/btree-serializer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a Binary Tree to ASCII 3 | * Original source in Swift: https://gist.github.com/khanov/4f1472b5ae001da817db 4 | */ 5 | function buildTreeString(node, prefix = '', isTail) { 6 | let result = ''; 7 | 8 | if (node.right) { 9 | const newPrefix = prefix + (isTail ? '│ ' : ' '); 10 | result += buildTreeString(node.right, newPrefix, false); 11 | } 12 | 13 | result += prefix + (isTail ? '└── ' : '┌── ') + node.key + '\n'; 14 | 15 | if (node.left) { 16 | const newPrefix = prefix + (isTail ? ' ' : '│ '); 17 | result += buildTreeString(node.left, newPrefix, true); 18 | } 19 | 20 | return result; 21 | } 22 | 23 | module.exports = { 24 | print(val, serialize, indent) { 25 | return buildTreeString(val, '', true); 26 | }, 27 | 28 | test(val) { 29 | return ( 30 | val && val.hasOwnProperty('key') && val.hasOwnProperty('left') && val.hasOwnProperty('right') 31 | ); 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /tests/matrix-serializer.js: -------------------------------------------------------------------------------- 1 | const repeat = require('lodash/repeat'); 2 | 3 | function header(matrix) { 4 | const spaces = repeat(' ', matrix.y ? 5 : 3); 5 | 6 | let result = spaces; 7 | 8 | for (let i = 0; i < matrix[0].length; i++) { 9 | result += `${i} `; 10 | } 11 | 12 | if (matrix.x) { 13 | result += '\n' + spaces; 14 | for (let i = 0; i < matrix.x.length; i++) { 15 | result += `${matrix.x[i]} `; 16 | } 17 | } 18 | 19 | result += '\n' + spaces; 20 | result += repeat('__', matrix[0].length); 21 | result += '\n'; 22 | 23 | return result; 24 | } 25 | 26 | /** 27 | * Convert a matrix to ASCII 28 | */ 29 | function convertMatrix(matrix) { 30 | let result = ''; 31 | 32 | result += header(matrix); 33 | 34 | for (let row = 0; row < matrix.length; row++) { 35 | for (let column = 0; column < matrix[row].length; column++) { 36 | // Row header 37 | if (column === 0) result += `${row} ${matrix.y ? matrix.y[row] : ''}| `; 38 | 39 | const value = matrix[row][column]; 40 | result += `${value === undefined ? '∅' : value} `; 41 | } 42 | 43 | result += '\n'; 44 | } 45 | 46 | return result; 47 | } 48 | 49 | module.exports = { 50 | print(val, serialize, indent) { 51 | return convertMatrix(val); 52 | }, 53 | 54 | test(val) { 55 | return Array.isArray(val) && Array.isArray(val[0]); 56 | }, 57 | }; 58 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "sourceMap": true, 8 | "lib": [ 9 | "dom", 10 | "es2015", 11 | "es2016" 12 | ], 13 | "module": "commonjs", 14 | "moduleResolution": "node", 15 | "outDir": "./lib", 16 | "target": "es6", 17 | "baseUrl": ".", 18 | "paths": {} 19 | }, 20 | "exclude": [ 21 | "dist", 22 | "node_modules" 23 | ], 24 | "compileOnSave": false, 25 | "buildOnSave": false, 26 | "atom": { 27 | "rewriteTsconfig": false 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "arrow-parens": false, 5 | "curly": false, 6 | "interface-name": [ 7 | false 8 | ], 9 | "object-literal-key-quotes": [ 10 | false 11 | ], 12 | "object-literal-sort-keys": false, 13 | "one-line": [ 14 | false 15 | ], 16 | "only-arrow-functions": [ 17 | false 18 | ], 19 | "member-access": false, 20 | "member-ordering": [ 21 | false 22 | ], 23 | "no-console": [ 24 | false 25 | ], 26 | "no-string-literal": false, 27 | "no-var-requires": false, 28 | "ordered-imports": [ 29 | false 30 | ], 31 | "quotemark": [ 32 | true, 33 | "single" 34 | ], 35 | "trailing-comma": [true, { "multiline": { 36 | "objects": "always", 37 | "arrays": "always", 38 | "functions": "never", 39 | "typeLiterals": "ignore" 40 | }, "singleline": "never" }], 41 | "variable-name": [false] 42 | } 43 | } 44 | --------------------------------------------------------------------------------