diff --git a/package-lock.json b/package-lock.json index 33bf893..e68a566 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ot-core", - "version": "0.2.1", + "version": "0.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -35,23 +35,6 @@ "json-stable-stringify": "^1.0.1" } }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", @@ -1138,7 +1121,6 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1220,13 +1202,6 @@ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - }, "caniuse-lite": { "version": "1.0.30000727", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000727.tgz", @@ -1239,17 +1214,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1287,27 +1251,6 @@ "integrity": "sha512-vHDDF/bP9RYpTWtUhpJRhCFdvvp3iDWvEbuDbWgvjUrNGV1MXJrE0MPcwGtEled04m61iwdBLUIHZtDgzWS4ZQ==", "dev": true }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true, - "optional": true - } - } - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -1442,9 +1385,9 @@ } }, "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -1497,7 +1440,6 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "dev": true, - "optional": true, "requires": { "jsbn": "~0.1.0" } @@ -1613,35 +1555,10 @@ "fill-range": "^2.1.0" } }, - "expect": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-21.0.2.tgz", - "integrity": "sha512-7jXWqbXhO8IeLuHpj4zkrOEd7DYebpXTAZ2AkHnAg1yhTRC0sP3w2oEsH4TOIl7xRChfZzWBozBSruVEVBLTWQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "jest-diff": "^21.0.2", - "jest-get-type": "^21.0.2", - "jest-matcher-utils": "^21.0.2", - "jest-message-util": "^21.0.2", - "jest-regex-util": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extglob": { @@ -1691,16 +1608,43 @@ } }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { "is-number": "^2.1.0", "isobject": "^2.0.0", - "randomatic": "^1.1.3", + "randomatic": "^3.0.0", "repeat-element": "^1.1.2", "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + } } }, "find-up": { @@ -1782,7 +1726,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1803,12 +1748,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1823,17 +1770,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1950,7 +1900,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1962,6 +1913,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1976,6 +1928,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1983,12 +1936,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2007,6 +1962,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2087,7 +2043,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2099,6 +2056,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2184,7 +2142,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2220,6 +2179,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2239,6 +2199,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2282,12 +2243,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2372,30 +2335,39 @@ "dev": true }, "handlebars": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", "dev": true, "requires": { - "async": "^1.4.0", + "neo-async": "^2.6.0", "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true, + "optional": true }, "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, + "optional": true, "requires": { - "amdefine": ">=0.0.4" + "commander": "~2.20.0", + "source-map": "~0.6.1" } } } @@ -2425,12 +2397,6 @@ "ansi-regex": "^2.0.0" } }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, "hawk": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", @@ -2804,29 +2770,88 @@ "dev": true }, "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, + "babel-jest": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-21.2.0.tgz", + "integrity": "sha512-O0W2qLoWu1QOoOGgxiR2JID4O6WSpxPiQanrkyi9SSlM0PJ60Ptzlck47lhtnr9YZO3zYOsxHwnyeWJ6AffoBQ==", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.0.0", + "babel-preset-jest": "^21.2.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz", + "integrity": "sha512-yi5QuiVyyvhBUDLP4ButAnhYzkdrUwWDtvUJv71hjH3fclhnZg4HkDeqaitcR2dZZx/E67kGkRcPVjtVu+SJfQ==", + "dev": true + }, + "babel-preset-jest": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz", + "integrity": "sha512-hm9cBnr2h3J7yXoTtAVV0zg+3vg0Q/gT2GYuzlreTU0EPkJRtlNgKJJ3tBKEn0+VjAi3JykV6xCJkuUYttEEfA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^21.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^3.1.0", + "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "supports-color": "^5.3.0" + } + }, + "expect": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-21.2.1.tgz", + "integrity": "sha512-orfQQqFRTX0jH7znRIGi8ZMR8kTNpXklTTz8+HGTpmTKZo3Occ6JNB5FXMb8cRuiiC/GyDqsr30zUa66ACYlYw==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "jest-diff": "^21.2.1", + "jest-get-type": "^21.2.0", + "jest-matcher-utils": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-regex-util": "^21.2.0" + }, + "dependencies": { + "jest-message-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", + "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + } + }, + "jest-regex-util": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.2.0.tgz", + "integrity": "sha512-BKQ1F83EQy0d9Jen/mcVX7D+lUt2tthhK/2gDWRgLDJRNOdRgSp1iVqFxP8EN1ARuypvDflRfPzYT8fQnoBQFQ==", + "dev": true + } } }, "jest-cli": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-21.0.2.tgz", - "integrity": "sha512-uxkEhZFFaLCuVPNbJ0AL1sP0bIzj9nhkhxK4eMLS94QN79t8tGVWfNQlazOCn64g34tcLOu+WEcCEbQPU8DuSg==", + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-21.2.1.tgz", + "integrity": "sha512-T1BzrbFxDIW/LLYQqVfo94y/hhaj1NzVQkZgBumAC+sxbjMROI7VkihOdxNR758iYbQykL2ZOWUBurFgkQrzdg==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", @@ -2838,17 +2863,17 @@ "istanbul-lib-coverage": "^1.0.1", "istanbul-lib-instrument": "^1.4.2", "istanbul-lib-source-maps": "^1.1.0", - "jest-changed-files": "^21.0.2", - "jest-config": "^21.0.2", - "jest-environment-jsdom": "^21.0.2", - "jest-haste-map": "^21.0.2", - "jest-message-util": "^21.0.2", - "jest-regex-util": "^21.0.2", - "jest-resolve-dependencies": "^21.0.2", - "jest-runner": "^21.0.2", - "jest-runtime": "^21.0.2", - "jest-snapshot": "^21.0.2", - "jest-util": "^21.0.2", + "jest-changed-files": "^21.2.0", + "jest-config": "^21.2.1", + "jest-environment-jsdom": "^21.2.1", + "jest-haste-map": "^21.2.0", + "jest-message-util": "^21.2.1", + "jest-regex-util": "^21.2.0", + "jest-resolve-dependencies": "^21.2.0", + "jest-runner": "^21.2.1", + "jest-runtime": "^21.2.1", + "jest-snapshot": "^21.2.1", + "jest-util": "^21.2.1", "micromatch": "^2.3.11", "node-notifier": "^5.0.2", "pify": "^3.0.0", @@ -2858,581 +2883,346 @@ "which": "^1.2.12", "worker-farm": "^1.3.1", "yargs": "^9.0.0" + }, + "dependencies": { + "jest-changed-files": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-21.2.0.tgz", + "integrity": "sha512-+lCNP1IZLwN1NOIvBcV5zEL6GENK6TXrDj4UxWIeLvIsIDa+gf6J7hkqsW2qVVt/wvH65rVvcPwqXdps5eclTQ==", + "dev": true, + "requires": { + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-21.2.1.tgz", + "integrity": "sha512-fJru5HtlD/5l2o25eY9xT0doK3t2dlglrqoGpbktduyoI0T5CwuB++2YfoNZCrgZipTwPuAGonYv0q7+8yDc/A==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^21.2.1", + "jest-environment-node": "^21.2.1", + "jest-get-type": "^21.2.0", + "jest-jasmine2": "^21.2.1", + "jest-regex-util": "^21.2.0", + "jest-resolve": "^21.2.0", + "jest-util": "^21.2.1", + "jest-validate": "^21.2.1", + "pretty-format": "^21.2.1" + } + }, + "jest-environment-jsdom": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz", + "integrity": "sha512-mecaeNh0eWmzNrUNMWARysc0E9R96UPBamNiOCYL28k7mksb1d0q6DD38WKP7ABffjnXyUWJPVaWRgUOivwXwg==", + "dev": true, + "requires": { + "jest-mock": "^21.2.0", + "jest-util": "^21.2.1", + "jsdom": "^9.12.0" + } + }, + "jest-haste-map": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-21.2.0.tgz", + "integrity": "sha512-5LhsY/loPH7wwOFRMs+PT4aIAORJ2qwgbpMFlbWbxfN0bk3ZCwxJ530vrbSiTstMkYLao6JwBkLhCJ5XbY7ZHw==", + "dev": true, + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-docblock": "^21.2.0", + "micromatch": "^2.3.11", + "sane": "^2.0.0", + "worker-farm": "^1.3.1" + } + }, + "jest-message-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", + "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + } + }, + "jest-regex-util": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.2.0.tgz", + "integrity": "sha512-BKQ1F83EQy0d9Jen/mcVX7D+lUt2tthhK/2gDWRgLDJRNOdRgSp1iVqFxP8EN1ARuypvDflRfPzYT8fQnoBQFQ==", + "dev": true + }, + "jest-resolve-dependencies": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz", + "integrity": "sha512-ok8ybRFU5ScaAcfufIQrCbdNJSRZ85mkxJ1EhUp8Bhav1W1/jv/rl1Q6QoVQHObNxmKnbHVKrfLZbCbOsXQ+bQ==", + "dev": true, + "requires": { + "jest-regex-util": "^21.2.0" + } + }, + "jest-runner": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-21.2.1.tgz", + "integrity": "sha512-Anb72BOQlHqF/zETqZ2K20dbYsnqW/nZO7jV8BYENl+3c44JhMrA8zd1lt52+N7ErnsQMd2HHKiVwN9GYSXmrg==", + "dev": true, + "requires": { + "jest-config": "^21.2.1", + "jest-docblock": "^21.2.0", + "jest-haste-map": "^21.2.0", + "jest-jasmine2": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-runtime": "^21.2.1", + "jest-util": "^21.2.1", + "pify": "^3.0.0", + "throat": "^4.0.0", + "worker-farm": "^1.3.1" + } + }, + "jest-runtime": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-21.2.1.tgz", + "integrity": "sha512-6omlpA3+NSE+rHwD0PQjNEjZeb2z+oRmuehMfM1tWQVum+E0WV3pFt26Am0DUfQkkPyTABvxITRjCUclYgSOsA==", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-jest": "^21.2.0", + "babel-plugin-istanbul": "^4.0.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "graceful-fs": "^4.1.11", + "jest-config": "^21.2.1", + "jest-haste-map": "^21.2.0", + "jest-regex-util": "^21.2.0", + "jest-resolve": "^21.2.0", + "jest-util": "^21.2.1", + "json-stable-stringify": "^1.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "strip-bom": "3.0.0", + "write-file-atomic": "^2.1.0", + "yargs": "^9.0.0" + } + }, + "jest-snapshot": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.2.1.tgz", + "integrity": "sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^21.2.1", + "jest-matcher-utils": "^21.2.1", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^21.2.1" + } + }, + "jest-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.2.1.tgz", + "integrity": "sha512-r20W91rmHY3fnCoO7aOAlyfC51x2yeV3xF+prGsJAUsYhKeV670ZB8NO88Lwm7ASu8SdH0S+U+eFf498kjhA4g==", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "jest-message-util": "^21.2.1", + "jest-mock": "^21.2.0", + "jest-validate": "^21.2.1", + "mkdirp": "^0.5.1" + } + } } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "jest-diff": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-21.2.1.tgz", + "integrity": "sha512-E5fu6r7PvvPr5qAWE1RaUwIh/k6Zx/3OOkZ4rk5dBJkEWRrUuSgbMt2EO8IUTPTd6DOqU3LW6uTIwX5FRvXoFA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^21.2.0", + "pretty-format": "^21.2.1" } }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "jest-docblock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", + "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", + "dev": true + }, + "jest-environment-node": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-21.2.1.tgz", + "integrity": "sha512-R211867wx9mVBVHzrjGRGTy5cd05K7eqzQl/WyZixR/VkJ4FayS8qkKXZyYnwZi6Rxo6WEV81cDbiUx/GfuLNw==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "jest-mock": "^21.2.0", + "jest-util": "^21.2.1" + }, + "dependencies": { + "jest-message-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", + "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + } + }, + "jest-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.2.1.tgz", + "integrity": "sha512-r20W91rmHY3fnCoO7aOAlyfC51x2yeV3xF+prGsJAUsYhKeV670ZB8NO88Lwm7ASu8SdH0S+U+eFf498kjhA4g==", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "jest-message-util": "^21.2.1", + "jest-mock": "^21.2.0", + "jest-validate": "^21.2.1", + "mkdirp": "^0.5.1" + } + } } - } - } - }, - "jest-changed-files": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-21.0.2.tgz", - "integrity": "sha512-dtOoRr+WjmDCbbFkPg0jj1kSgfq5znW1/XKOqwS2Tpp507GMk6GtSz7riTDlEiEauApFbkL+iE23CLjMNGVjFw==", - "dev": true, - "requires": { - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-21.0.2.tgz", - "integrity": "sha512-WN6nwuamQeiMX7CBV8cVyIxAYQDDyGuUnASK0el6CFCGAzBnsXN5a4nHr3oE5eSYXZhLEmEeaFPejyuw/RQ97w==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^21.0.2", - "jest-environment-node": "^21.0.2", - "jest-get-type": "^21.0.2", - "jest-jasmine2": "^21.0.2", - "jest-regex-util": "^21.0.2", - "jest-resolve": "^21.0.2", - "jest-util": "^21.0.2", - "jest-validate": "^21.0.2", - "pretty-format": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + }, + "jest-get-type": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", + "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "dev": true + }, + "jest-jasmine2": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz", + "integrity": "sha512-lw8FXXIEekD+jYNlStfgNsUHpfMWhWWCgHV7n0B7mA/vendH7vBFs8xybjQsDzJSduptBZJHqQX9SMssya9+3A==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "chalk": "^2.0.1", + "expect": "^21.2.1", + "graceful-fs": "^4.1.11", + "jest-diff": "^21.2.1", + "jest-matcher-utils": "^21.2.1", + "jest-message-util": "^21.2.1", + "jest-snapshot": "^21.2.1", + "p-cancelable": "^0.3.0" + }, + "dependencies": { + "jest-message-util": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.2.1.tgz", + "integrity": "sha512-EbC1X2n0t9IdeMECJn2BOg7buOGivCvVNjqKMXTzQOu7uIfLml+keUfCALDh8o4rbtndIeyGU8/BKfoTr/LVDQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + } + }, + "jest-snapshot": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.2.1.tgz", + "integrity": "sha512-bpaeBnDpdqaRTzN8tWg0DqOTo2DvD3StOemxn67CUd1p1Po+BUpvePAp44jdJ7Pxcjfg+42o4NHw1SxdCA2rvg==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^21.2.1", + "jest-matcher-utils": "^21.2.1", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^21.2.1" + } + } } }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "jest-matcher-utils": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz", + "integrity": "sha512-kn56My+sekD43dwQPrXBl9Zn9tAqwoy25xxe7/iY4u+mG8P3ALj5IK7MLHZ4Mi3xW7uWVCjGY8cm4PqgbsqMCg==", "dev": true, "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "pretty-format": "^21.2.1" } }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "jest-mock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-21.2.0.tgz", + "integrity": "sha512-aZDfyVf0LEoABWiY6N0d+O963dUQSyUa4qgzurHR3TBDPen0YxKCJ6l2i7lQGh1tVdsuvdrCZ4qPj+A7PievCw==", + "dev": true + }, + "jest-resolve": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-21.2.0.tgz", + "integrity": "sha512-vefQ/Lr+VdNvHUZFQXWtOqHX3HEdOc2MtSahBO89qXywEbUxGPB9ZLP9+BHinkxb60UT2Q/tTDOS6rYc6Mwigw==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "browser-resolve": "^1.11.2", + "chalk": "^2.0.1", + "is-builtin-module": "^1.0.0" } - } - } - }, - "jest-diff": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-21.0.2.tgz", - "integrity": "sha512-k/OO6n00pzAA5MY0ri4H3hdQF0mE3RKp562Ses/+tqiDRPrCiugBGcx9D3QodywEyXCZxJKS91PhKPQrAFwn9w==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff": "^3.2.0", - "jest-get-type": "^21.0.2", - "pretty-format": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + }, + "jest-validate": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz", + "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "leven": "^2.1.0", + "pretty-format": "^21.2.1" } }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "pretty-format": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", + "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", "dev": true, "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-docblock": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.0.2.tgz", - "integrity": "sha512-3wPN1f5W0jh9bTZ7ygWFnzjB1CAIAWNDZ/rda+wKR/J1a1zF6ifQ7XkM1k0aS4mknN0W+3+FP2TSnMBJbgQJag==", - "dev": true - }, - "jest-environment-jsdom": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-21.0.2.tgz", - "integrity": "sha512-17lKGVAqqfHDlx0zP0HLJAkZOeyx2pJUUCRSKszaSHfiaoADjboqW/bkZozjLVs9UDz/h11mtVSZBQ6+d/cf5A==", - "dev": true, - "requires": { - "jest-mock": "^21.0.2", - "jest-util": "^21.0.2", - "jsdom": "^9.12.0" - } - }, - "jest-environment-node": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-21.0.2.tgz", - "integrity": "sha512-TqeLg02B3WR9aS3qI5VcGzxjsKHOch31h7kr4b6m66rdgFslG66nZJvp+X+Z7ALGKi6jKvovKImu/PygsuxF3Q==", - "dev": true, - "requires": { - "jest-mock": "^21.0.2", - "jest-util": "^21.0.2" - } - }, - "jest-get-type": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.0.2.tgz", - "integrity": "sha512-4KvNzzXMXeapGaMWd+SL5e47zcMn8KTWjom6Fl3avxVXnbKS7abD1p4xWe4ToAZfgNoYNsQ9Av/mnWMnZK/Z4A==", - "dev": true - }, - "jest-haste-map": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-21.0.2.tgz", - "integrity": "sha512-APJs7w2uFERWCzcuymHsBmzSzhLccWe8wiJ1BQg9rAT67Fp5ftin20ZtVVwUxtdD/6GGqv2mAMGL2h4CbG9H/w==", - "dev": true, - "requires": { - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.1.11", - "jest-docblock": "^21.0.2", - "micromatch": "^2.3.11", - "sane": "^2.0.0", - "worker-farm": "^1.3.1" - } - }, - "jest-jasmine2": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-21.0.2.tgz", - "integrity": "sha512-CB0Fq7kuISMHDUhnMeB8tkNGkq7O9noMFugeMqL0OjCIA0QkAlTFOQR2yGDYYUBhWafTl8Pw3mG1TaoNZ8xvnw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "expect": "^21.0.2", - "graceful-fs": "^4.1.11", - "jest-diff": "^21.0.2", - "jest-matcher-utils": "^21.0.2", - "jest-message-util": "^21.0.2", - "jest-snapshot": "^21.0.2", - "p-cancelable": "^0.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-matcher-utils": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-21.0.2.tgz", - "integrity": "sha512-IOBQqa3qVN7bjNYCr+DEPCx/vOmvgMh7upbrckGJQzeEfcHZ/UUVhh3dlaar+5fBQ7Aaf6wlesDUaCb4+NCU7g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "pretty-format": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-message-util": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-21.0.2.tgz", - "integrity": "sha512-KsFJgt4o1RSx0H1Usr/bYlCgSn/vzr/oduarz2O9DZaYlYn/DIJ4vfLRGIalixF/ABehrfKZy24KJSvTS3d+eA==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "micromatch": "^2.3.11", - "slash": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-mock": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-21.0.2.tgz", - "integrity": "sha512-TJ2J6JFHq+hDXhm51ZcFkMumlYIZJf6NkyJGGDwbINXKKKWboi9y3sWEPX/zmDp3mPolC4tgdlemQ+eaCBz/xA==", - "dev": true - }, - "jest-regex-util": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-21.0.2.tgz", - "integrity": "sha512-KmUZvbvislZZH7FHAhJ9PFMVcjSoso2fb+ClmJWd9oxrXiNMYmNsrMNbqQ/vyIQfCObR3n+ZtZgECS/8QJnEMw==", - "dev": true - }, - "jest-resolve": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-21.0.2.tgz", - "integrity": "sha512-zz0E/pv+0VaLB9ej6clmdtZXYAZE5/A+/mPtMOpYT0g05gt3Ieg4/4n2LPzHzop0jIfZNRD9a+bZdjOSFsNJHA==", - "dev": true, - "requires": { - "browser-resolve": "^1.11.2", - "chalk": "^2.0.1", - "is-builtin-module": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-21.0.2.tgz", - "integrity": "sha512-dVD0lX1FtFnBHT2/aTpy+UGRuJ+n5xK4Qvgc3KaP7YL7e39z/6nXGOKLvdmFtkd+Bbk/dbn4vO8Y4vt0Vvb2rw==", - "dev": true, - "requires": { - "jest-regex-util": "^21.0.2" - } - }, - "jest-runner": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-21.0.2.tgz", - "integrity": "sha512-Cm5HDGFgRLJIhECZTnb/EzLoaDQIzxbSVaNVCpj8Q0iUrpIeEB4AVXjVBzsxF/P4uHtXPy3B1V6MPJsqc7532w==", - "dev": true, - "requires": { - "jest-config": "^21.0.2", - "jest-docblock": "^21.0.2", - "jest-haste-map": "^21.0.2", - "jest-jasmine2": "^21.0.2", - "jest-message-util": "^21.0.2", - "jest-runtime": "^21.0.2", - "jest-util": "^21.0.2", - "pify": "^3.0.0", - "throat": "^4.0.0", - "worker-farm": "^1.3.1" - } - }, - "jest-runtime": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-21.0.2.tgz", - "integrity": "sha512-Y4uQggTRX/by0EI9DwO3o23CJii/zTrWG4VC8MKkcqqpC+zZjz0zh4gp0Kiriu8Tk6loh9gwqbRFzVcHs1w82A==", - "dev": true, - "requires": { - "babel-core": "^6.0.0", - "babel-jest": "^21.0.2", - "babel-plugin-istanbul": "^4.0.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "graceful-fs": "^4.1.11", - "jest-config": "^21.0.2", - "jest-haste-map": "^21.0.2", - "jest-regex-util": "^21.0.2", - "jest-resolve": "^21.0.2", - "jest-util": "^21.0.2", - "json-stable-stringify": "^1.0.1", - "micromatch": "^2.3.11", - "slash": "^1.0.0", - "strip-bom": "3.0.0", - "write-file-atomic": "^2.1.0", - "yargs": "^9.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-snapshot": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-21.0.2.tgz", - "integrity": "sha512-FJSjL10Y7uTTrWqGA+Lj75A2KBObizIW2KcICRrdFH8wr14cuSfQmlcbGoJcoP8obdR8jTsOz4KBHOTpdcYt3g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^21.0.2", - "jest-matcher-utils": "^21.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-util": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-21.0.2.tgz", - "integrity": "sha512-3cRvazDrS3ecAXIOEIpbTbMbc2IMe1Dkcg1xmhTos2qtRGbMvvoJj2VWXpicRdjVep+pGqSl3rurVnMBCXu2yw==", - "dev": true, - "requires": { - "callsites": "^2.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.11", - "jest-message-util": "^21.0.2", - "jest-mock": "^21.0.2", - "jest-validate": "^21.0.2", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "jest-validate": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.0.2.tgz", - "integrity": "sha512-QbZn5ouy7oMkp88ydirXIvyWP6+vpB+F3EaUklij6cfy8oJKtyNelFHQ7owyFLManu5NZJ6hk6WetUP4OcrfQQ==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^21.0.2", - "leven": "^2.1.0", - "pretty-format": "^21.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.1.0", - "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + } } } } @@ -3444,9 +3234,9 @@ "dev": true }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3457,8 +3247,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "dev": true }, "jsdom": { "version": "9.12.0", @@ -3555,13 +3344,6 @@ "is-buffer": "^1.1.5" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true - }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -3619,15 +3401,9 @@ } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "loose-envify": { "version": "1.3.1", @@ -3657,6 +3433,12 @@ "tmpl": "1.0.x" } }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", + "dev": true + }, "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", @@ -3667,9 +3449,9 @@ } }, "merge": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", - "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", "dev": true }, "micromatch": { @@ -3757,6 +3539,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, "node-fetch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", @@ -4055,33 +3843,6 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, - "pretty-format": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.0.2.tgz", - "integrity": "sha512-+fjqIZo/KcMEreY5onowgXzENgd6zKxJS9BoiIoOeRmXTM0Fo6Er0RUbIjzLyY2TBV1K2S7vDUzOVcUtKE9jgQ==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } - } - }, "private": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", @@ -4107,6 +3868,12 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "psl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", + "dev": true + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -4119,47 +3886,6 @@ "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "dev": true }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -4344,6 +4070,17 @@ "tough-cookie": "~2.3.0", "tunnel-agent": "^0.6.0", "uuid": "^3.0.0" + }, + "dependencies": { + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "^1.4.1" + } + } } }, "require-directory": { @@ -4364,16 +4101,6 @@ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -4389,6 +4116,12 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "sane": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sane/-/sane-2.0.0.tgz", @@ -4523,9 +4256,9 @@ "dev": true }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -4535,6 +4268,7 @@ "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "dependencies": { @@ -4617,9 +4351,9 @@ } }, "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", "dev": true }, "strip-ansi": { @@ -4695,12 +4429,21 @@ "dev": true }, "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "punycode": "^1.4.1" + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } } }, "tr46": { @@ -4728,8 +4471,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true + "dev": true }, "type-check": { "version": "0.3.2", @@ -4740,40 +4482,6 @@ "prelude-ls": "~1.1.2" } }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "optional": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", @@ -4899,13 +4607,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true, - "optional": true - }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", diff --git a/package.json b/package.json index eab72c5..99bd3f0 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ }, "dependencies": { "cross-fetch": "^3.0.1", - "lodash": "^4.17.4", + "lodash": "^4.17.15", "node-fetch": "^2.3.0", "tinyqueue": "^1.2.2", "whatwg-fetch": "^3.0.0" diff --git a/src/index.js b/src/index.js index 856a1a7..925d57a 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,7 @@ export {OTStateManager} from './ot/OTStateManager'; export {TransformResult} from './ot/OTSystem/TransformResult'; export {OTSystemBuilder} from './ot/OTSystem/OTSystemBuilder'; +export {MergedOTSystem} from './ot/OTSystem/MergedOTSystem'; export {OTCommit} from './ot/OTCommit'; export {ClientOTNode} from './ot/ClientOTNode'; export {commitsToGraphviz, makeCheckpointForCommit, merge} from './ot/otUtils'; diff --git a/src/ot/OTStateManager.js b/src/ot/OTStateManager.js index cfd376e..b926d09 100644 --- a/src/ot/OTStateManager.js +++ b/src/ot/OTStateManager.js @@ -12,7 +12,7 @@ import assert from 'assert'; import EventEmitter from 'events'; import {serial} from '../common/utils'; -import type OTSystem from "./OTSystem/OTSystem"; +import type OTSystemImpl from "./OTSystem/OTSystemImpl"; import type {OTOperation} from "./interfaces/OTOperation"; import type {OTNode, fetchData} from "./interfaces/OTNode"; @@ -23,7 +23,7 @@ const DEFAULT_RETRY_TIMEOUT = 1000; export class OTStateManager { _initState: provider; _otNode: OTNode; - _otSystem: OTSystem; + _otSystem: OTSystemImpl; _retryTimeout: number; _state: TState; @@ -38,7 +38,7 @@ export class OTStateManager { constructor( initState: provider, node: OTNode, - otSystem: OTSystem, + otSystem: OTSystemImpl, retryTimeout: number = DEFAULT_RETRY_TIMEOUT ) { this._initState = initState; diff --git a/src/ot/OTSystem/MergedOTSystem.js b/src/ot/OTSystem/MergedOTSystem.js new file mode 100644 index 0000000..2efe214 --- /dev/null +++ b/src/ot/OTSystem/MergedOTSystem.js @@ -0,0 +1,192 @@ +/* + * Copyright (с) 2019-present, SoftIndex LLC. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @flow + +import {TransformResult} from './TransformResult'; +import {OTOperation} from "../interfaces/OTOperation"; +import type {OTSystem} from "../interfaces/OTSystem"; + +export type constructor2 = (Array<$FlowFixMe>, Array<$FlowFixMe>) => OTOperation; +export type constructor3 = (Array<$FlowFixMe>, Array<$FlowFixMe>, Array<$FlowFixMe>) => OTOperation; +export type constructor4 = (Array<$FlowFixMe>, Array<$FlowFixMe>, Array<$FlowFixMe>, Array<$FlowFixMe>) => OTOperation; +export type getter = $FlowFixMe => Array>; + +export class MergedOTSystem implements OTSystem { + _constructor: constructor2; + _getter1: getter; + _otSystem1: OTSystem; + _getter2: getter; + _otSystem2: OTSystem; + + constructor(constructor: constructor2, + getter1: getter, + otSystem1: OTSystem, + getter2: getter, + otSystem2: OTSystem + ) { + this._constructor = constructor; + this._getter1 = getter1; + this._otSystem1 = otSystem1; + this._getter2 = getter2; + this._otSystem2 = otSystem2; + } + + static merge2(constructor: constructor2, + getter1: getter, + otSystem1: OTSystem, + getter2: getter, + otSystem2: OTSystem): OTSystem { + return new MergedOTSystem(constructor, getter1, otSystem1, getter2, otSystem2); + } + + static merge3(constructor: constructor3, + getter1: getter, + otSystem1: OTSystem, + getter2: getter, + otSystem2: OTSystem, + getter3: getter, + otSystem3: OTSystem): OTSystem { + + const premerged = this.merge2(Helper.create, + helper => helper.ops1, otSystem1, + helper => helper.ops2, otSystem2); + + + return this.merge2((helpers, ops) => { + let helper = extractHelper(helpers); + return constructor(helper.ops1, helper.ops2, ops); + }, + multiOP => combine(getter1(multiOP), getter2(multiOP), Helper.create), premerged, + getter3, otSystem3); + } + + static merge4(constructor: constructor4, + getter1: getter, + otSystem1: OTSystem, + getter2: getter, + otSystem2: OTSystem, + getter3: getter, + otSystem3: OTSystem, + getter4: getter, + otSystem4: OTSystem): OTSystem { + + const premerged1 = this.merge2(Helper.create, + helper => helper.ops1, otSystem1, + helper => helper.ops2, otSystem2); + + const premerged2 = this.merge2(Helper.create, + helper => helper.ops1, otSystem3, + helper => helper.ops2, otSystem4); + + return this.merge2((helpers1, helpers2) => { + let helper1 = extractHelper(helpers1); + let helper2 = extractHelper(helpers2); + return constructor(helper1.ops1, helper1.ops2, helper2.ops1, helper2.ops2) + }, + multiOp => combine(getter1(multiOp), getter2(multiOp), Helper.create), premerged1, + multiOp => combine(getter3(multiOp), getter4(multiOp), Helper.create), premerged2); + } + + /** + * Is operation empty + */ + isEmpty(op: OTOperation): boolean { + for (let operation of this._getter1(op)) { + if (!this._otSystem1.isEmpty(operation)) { + return false; + } + } + for (let operation of this._getter2(op)) { + if (!this._otSystem2.isEmpty(operation)) { + return false; + } + } + return true; + } + + /** + * Transform two diffs + */ + transform(leftOps: Array>, rightOps: Array>): TransformResult { + let leftOps1 = this._collect(leftOps, this._getter1); + let leftOps2 = this._collect(leftOps, this._getter2); + let rightOps1 = this._collect(rightOps, this._getter1); + let rightOps2 = this._collect(rightOps, this._getter2); + + let transform1 = this._otSystem1.transform(leftOps1, rightOps1); + let transform2 = this._otSystem2.transform(leftOps2, rightOps2); + + let left = combine(transform1.leftOps, transform2.leftOps, this._constructor); + let right = combine(transform1.rightOps, transform2.rightOps, this._constructor); + + return TransformResult.of(left, right); + } + + /** + * Squash operations + */ + squash(ops: Array>): Array> { + if (ops.length === 0) return ops; + let squashed1 = this._otSystem1.squash(this._collect(ops, this._getter1)); + let squashed2 = this._otSystem2.squash(this._collect(ops, this._getter2)); + return combine(squashed1, squashed2, this._constructor); + } + + /** + * Invert operations + */ + invert(ops: Array>): Array> { + if (ops.length === 0) return ops; + let inverted1 = this._otSystem1.invert(this._collect(ops, this._getter1)); + let inverted2 = this._otSystem2.invert(this._collect(ops, this._getter2)); + return combine(inverted1, inverted2, this._constructor); + } + + _collect(ops: Array>, getter: OTOperation => Array>): Array> { + let result: Array> = []; + ops.map(el => getter(el)).forEach(ops => result.push(...ops)); + return result; + } +} + +// region helpers +function combine(ops1: Array, ops2: Array, constructor: (Array, Array) => S): Array { + if (ops1.length === 0 && ops2.length === 0) { + return []; + } else { + return [constructor(ops1, ops2)]; + } +} + +function extractHelper(helpers: Array>): Helper { + if (helpers.length > 1) { + throw new Error('Invalid state, there can only be one or zero helpers'); + } + return helpers.length === 0 ? new Helper([], []) : helpers[0]; +} + +class Helper implements OTOperation { + ops1: Array>; + ops2: Array>; + + constructor(ops1: Array>, ops2: Array>) { + this.ops1 = ops1; + this.ops2 = ops2; + } + + static create(ops1: Array>, ops2: Array>) { + return new Helper(ops1, ops2); + } + + apply(state: S): S { + throw new Error('Helper class'); + } +} + +// endregion diff --git a/src/ot/OTSystem/OTSystemBuilder.js b/src/ot/OTSystem/OTSystemBuilder.js index d74eb23..c6b60eb 100644 --- a/src/ot/OTSystem/OTSystemBuilder.js +++ b/src/ot/OTSystem/OTSystemBuilder.js @@ -8,11 +8,11 @@ // @flow -import OTSystem from "./OTSystem"; +import OTSystemImpl from "./OTSystemImpl"; import {ensureMapValue} from '../../common/utils'; import {OTOperation} from "../interfaces/OTOperation"; -import type {transformer, squasher, emptyPredicate, inverter} from './OTSystem'; +import type {transformer, squasher, emptyPredicate, inverter} from './OTSystemImpl'; import {TransformResult} from "./TransformResult"; export class OTSystemBuilder { @@ -28,8 +28,8 @@ export class OTSystemBuilder { this._inverters = new Map(); } - build(): OTSystem { - return new OTSystem(this._transformers, this._squashers, this._emptyPredicated, this._inverters); + build(): OTSystemImpl { + return new OTSystemImpl(this._transformers, this._squashers, this._emptyPredicated, this._inverters); } withTransformFunction(LeftOp: Class>, RightOp: Class>, transformer: transformer): OTSystemBuilder { diff --git a/src/ot/OTSystem/OTSystem.js b/src/ot/OTSystem/OTSystemImpl.js similarity index 97% rename from src/ot/OTSystem/OTSystem.js rename to src/ot/OTSystem/OTSystemImpl.js index 1689219..53e4f17 100644 --- a/src/ot/OTSystem/OTSystem.js +++ b/src/ot/OTSystem/OTSystemImpl.js @@ -10,13 +10,14 @@ import {TransformResult} from './TransformResult'; import {OTOperation} from "../interfaces/OTOperation"; +import type {OTSystem} from "../interfaces/OTSystem"; export type transformer = ($FlowFixMe, $FlowFixMe) => TransformResult; export type squasher = ($FlowFixMe, $FlowFixMe) => ?OTOperation; export type emptyPredicate = ($FlowFixMe) => boolean; export type inverter = ($FlowFixMe) => OTOperation; -class OTSystem { +class OTSystemImpl implements OTSystem { _transformers: Map>, Map>, transformer>>; _squashers: Map>, Map>, squasher>>; _emptyPredicates: Map>, emptyPredicate>; @@ -219,4 +220,4 @@ class OTSystem { } } -export default OTSystem; +export default OTSystemImpl; diff --git a/src/ot/OTSystem/__tests__/MergedOTSystem-test.js b/src/ot/OTSystem/__tests__/MergedOTSystem-test.js new file mode 100644 index 0000000..39d43d4 --- /dev/null +++ b/src/ot/OTSystem/__tests__/MergedOTSystem-test.js @@ -0,0 +1,221 @@ +/* + * Copyright (с) 2019-present, SoftIndex LLC. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @flow + +import TestAddOp from '../../../test/TestAddOp'; +import TestSetOp from '../../../test/TestSetOp'; +import {MultiOp, State, testMergedOTResolver} from "../../../test/merged/testMergedOTResolver"; +import TestArrayOp from "../../../test/merged/TestArrayOp"; + +describe('Squash', () => { + it('Should squash operations1', () => { + const opsAdd1 = [ + new TestAddOp(0, 3), + new TestAddOp(3, 1), + new TestAddOp(4, 10) + ]; + const opsAdd2 = [ + new TestAddOp(14, 6), + new TestAddOp(20, 124), + new TestAddOp(144, -54) + ]; + const opsSet1 = [ + new TestSetOp(0, 34), + new TestSetOp(34, 4), + new TestSetOp(4, 23) + ]; + const opsSet2 = [ + new TestSetOp(23, 12), + new TestSetOp(12, 45), + new TestSetOp(45, 63) + ]; + const opsArr1 = [ + new TestArrayOp('a', false), + new TestArrayOp('a', true), + new TestArrayOp('b', false) + ]; + const opsArr2 = [ + new TestArrayOp('g', false), + new TestArrayOp('g', true), + new TestArrayOp('ff', false) + ]; + + let multiOps = [new MultiOp(opsAdd1, opsSet1, opsArr1), new MultiOp(opsAdd2, opsSet2, opsArr2)]; + + const result = testMergedOTResolver.squash(multiOps); + expect(result).toEqual([new MultiOp( + [new TestAddOp(0, 90)], + [new TestSetOp(0, 63)], + [new TestArrayOp('b', false), new TestArrayOp('ff', false)] + )]); + }); + + it('Should squash operations2', () => { + const opsAdd1 = []; + const opsAdd2 = []; + const opsSet1 = []; + const opsSet2 = []; + const opsArr1 = [ + new TestArrayOp('a', false), + new TestArrayOp('a', true), + new TestArrayOp('b', false) + ]; + const opsArr2 = [ + new TestArrayOp('g', false), + new TestArrayOp('g', true), + new TestArrayOp('ff', false) + ]; + + let multiOps = [new MultiOp(opsAdd1, opsSet1, opsArr1), new MultiOp(opsAdd2, opsSet2, opsArr2)]; + + const result = testMergedOTResolver.squash(multiOps); + expect(result).toEqual([new MultiOp( + [], + [], + [new TestArrayOp('b', false), new TestArrayOp('ff', false)] + )]); + }); +}); + +describe('Empty', () => { + it('Should be non empty', () => { + const opsAdd = [new TestAddOp(4, 10)]; + const opsSet = [new TestSetOp(4, 23)]; + const opsArr = [new TestArrayOp('b', false)]; + + const isEmpty = testMergedOTResolver.isEmpty(new MultiOp(opsAdd, opsSet, opsArr)); + expect(isEmpty).toEqual(false); + }); + it('Should also be non empty', () => { + const opsAdd = []; + const opsSet = [new TestSetOp(4, 23)]; + const opsArr = []; + + const result = testMergedOTResolver.isEmpty(new MultiOp(opsAdd, opsSet, opsArr)); + expect(result).toEqual(false); + }); + it('Should be empty if no ops', () => { + const opsAdd = []; + const opsSet = []; + const opsArr = []; + + const isEmpty = testMergedOTResolver.isEmpty(new MultiOp(opsAdd, opsSet, opsArr)); + expect(isEmpty).toEqual(true); + }); + it('Should be empty ops are empty', () => { + const opsAdd = []; + const opsSet = [new TestSetOp(123, 123)]; + const opsArr = []; + + const isEmpty = testMergedOTResolver.isEmpty(new MultiOp(opsAdd, opsSet, opsArr)); + expect(isEmpty).toEqual(true); + }); +}); + +describe('Invert', () => { + it('Should invert operations', () => { + const opsAdd1 = [ + new TestAddOp(0, 3), + new TestAddOp(3, 1), + new TestAddOp(4, 10) + ]; + const opsAdd2 = [ + new TestAddOp(14, 6), + new TestAddOp(20, 124), + new TestAddOp(144, -54) + ]; + const opsSet1 = [ + new TestSetOp(0, 34), + new TestSetOp(34, 4), + new TestSetOp(4, 23) + ]; + const opsSet2 = [ + new TestSetOp(23, 12), + new TestSetOp(12, 45), + new TestSetOp(45, 63) + ]; + const opsArr1 = [ + new TestArrayOp('a', false), + new TestArrayOp('a', true), + new TestArrayOp('b', false) + ]; + const opsArr2 = [ + new TestArrayOp('g', false), + new TestArrayOp('g', true), + new TestArrayOp('ff', false) + ]; + + let multiOps = [new MultiOp(opsAdd1, opsSet1, opsArr1), new MultiOp(opsAdd2, opsSet2, opsArr2)]; + + const result = testMergedOTResolver.squash(multiOps); + expect(result).toEqual([new MultiOp( + [new TestAddOp(0, 90)], + [new TestSetOp(0, 63)], + [new TestArrayOp('b', false), new TestArrayOp('ff', false)] + )]); + }); +}); + +describe('Transform', () => { + it('Should transform operations', () => { + const opsAddLeft = [ + new TestAddOp(0, 1), + new TestAddOp(1, 3), + new TestAddOp(4, 6) + ]; + const opsAddRight = [ + new TestAddOp(0, 15), + new TestAddOp(15, 30), + new TestAddOp(45, 45) + ]; + + const opsSetLeft = [ + new TestSetOp(0, 34), + new TestSetOp(34, 4), + new TestSetOp(4, 23) + ]; + const opsSetRight = [ + new TestSetOp(0, 12), + new TestSetOp(12, 4), + new TestSetOp(4, 63) + ]; + + const opsArrLeft = [ + new TestArrayOp('a', false), + new TestArrayOp('b', false) + ]; + const opsArrRight = [ + new TestArrayOp('b', false), + new TestArrayOp('cc', false), + ]; + + const leftOps = [new MultiOp(opsAddLeft, opsSetLeft, opsArrLeft)]; + const rightOps = [new MultiOp(opsAddRight, opsSetRight, opsArrRight)]; + + let stateLeft = new State(); + let stateRight = new State(); + + leftOps.forEach(op => op.apply(stateLeft)); + rightOps.forEach(op => op.apply(stateRight)); + + const result = testMergedOTResolver.transform(leftOps, rightOps); + result.leftOps.forEach(op => op.apply(stateLeft)); + result.rightOps.forEach(op => op.apply(stateRight)); + + expect(stateLeft).toEqual(stateRight); + + expect(stateLeft.number1).toEqual(100); + expect(stateLeft.number2).toEqual(63); + expect(stateLeft.strings.size).toEqual(3); + + const expectedStrings = ['a', 'b', 'cc']; + expectedStrings.forEach(el => expect(stateLeft.strings).toContain(el)); + }); +}); + diff --git a/src/ot/interfaces/OTSystem.js b/src/ot/interfaces/OTSystem.js new file mode 100644 index 0000000..81fc61c --- /dev/null +++ b/src/ot/interfaces/OTSystem.js @@ -0,0 +1,23 @@ +/* + * Copyright (с) 2019-present, SoftIndex LLC. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @flow + + +import type {OTOperation} from "./OTOperation"; +import {TransformResult} from "../OTSystem/TransformResult"; + +export interface OTSystem { + isEmpty(op: OTOperation): boolean; + + transform(leftOps: Array>, rightOps: Array>): TransformResult; + + squash(ops: Array>): Array>; + + invert(ops: Array>): Array>; +} diff --git a/src/ot/otUtils.js b/src/ot/otUtils.js index 8dd381b..1bf7a4a 100644 --- a/src/ot/otUtils.js +++ b/src/ot/otUtils.js @@ -12,7 +12,7 @@ import Queue from 'tinyqueue'; import type {OTRemote} from "./interfaces/OTRemote"; import {OTCommit} from "./OTCommit"; import type {OTOperation} from "./interfaces/OTOperation"; -import OTSystem from "./OTSystem/OTSystem"; +import OTSystemImpl from "./OTSystem/OTSystemImpl"; import {unwrap, difference} from '../common/utils'; type comparator = (T, T) => number; @@ -28,7 +28,7 @@ export type findResult = { parentToChild: Array> } | null; -export async function makeCheckpointForCommit(otResolver: OTSystem, +export async function makeCheckpointForCommit(otResolver: OTSystemImpl, remote: OTRemote, commitIdComparator: comparator, commitId: K): Promise>> { @@ -202,7 +202,7 @@ function withoutSubnodes(startNodes: Set<$FlowFixMe>, } function doMerge(startNodes: Set<$FlowFixMe>, - otResolver: OTSystem, + otResolver: OTSystemImpl, opsState: Map<$FlowFixMe, Set<$FlowFixMe>>, commits: commits): $FlowFixMe | null { if (startNodes.size === 1) { @@ -291,7 +291,7 @@ function doMerge(startNodes: Set<$FlowFixMe>, return newCommitId; } -export async function merge(otResolver: OTSystem, +export async function merge(otResolver: OTSystemImpl, otRemote: OTRemote, commitIdComparator: comparator, startNodes: Set): Promise>>> { diff --git a/src/test/merged/TestArrayOp.js b/src/test/merged/TestArrayOp.js new file mode 100644 index 0000000..1865fa3 --- /dev/null +++ b/src/test/merged/TestArrayOp.js @@ -0,0 +1,32 @@ +/* + * Copyright (с) 2019-present, SoftIndex LLC. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @flow + +import type {OTOperation} from "../../ot/interfaces/OTOperation"; + +class TestArrayOp implements OTOperation> { + string: string; + remove: boolean; + + constructor(string: string, remove: boolean) { + this.string = string; + this.remove = remove; + } + + apply(state: Set) { + if (this.remove){ + state.delete(this.string); + } else { + state.add(this.string); + } + return state; + } +} + +export default TestArrayOp; diff --git a/src/test/merged/testMergedOTResolver.js b/src/test/merged/testMergedOTResolver.js new file mode 100644 index 0000000..cc82429 --- /dev/null +++ b/src/test/merged/testMergedOTResolver.js @@ -0,0 +1,95 @@ +/* + * Copyright (с) 2019-present, SoftIndex LLC. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @flow + +import TestAddOp from '../TestAddOp'; +import TestSetOp from '../TestSetOp'; +import {OTSystemBuilder} from "../../ot/OTSystem/OTSystemBuilder"; +import {TransformResult} from "../../ot/OTSystem/TransformResult"; +import type {OTSystem} from "../../ot/interfaces/OTSystem"; +import MergedOTSystem from "../../ot/OTSystem/MergedOTSystem"; +import type {OTOperation} from "../../ot/interfaces/OTOperation"; +import TestArrayOp from "./TestArrayOp"; + +const testAddOTResolver: OTSystem = new OTSystemBuilder() + .withTransformFunction(TestAddOp, TestAddOp, (leftOp: TestAddOp, rightOp: TestAddOp) => { + return TransformResult.of([ + new TestAddOp(leftOp.prev + leftOp.delta, rightOp.delta) + ], [ + new TestAddOp(rightOp.prev + rightOp.delta, leftOp.delta) + ]); + }) + .withSquashFunction(TestAddOp, TestAddOp, (prevOp: TestAddOp, nextOp: TestAddOp) => { + return new TestAddOp(prevOp.prev, prevOp.delta + nextOp.delta); + }) + .withEmptyPredicate(TestAddOp, (op: TestAddOp) => op.delta === 0) + .withInvertFunction(TestAddOp, (op: TestAddOp) => new TestAddOp(op.prev + op.delta, -op.delta)) + .build(); + +const testSetOTResolver: OTSystem = new OTSystemBuilder() + .withTransformFunction(TestSetOp, TestSetOp, (leftOp: TestSetOp, rightOp: TestSetOp) => { + if (leftOp.next > rightOp.next) { + return TransformResult.left([new TestSetOp(leftOp.next, rightOp.next)]); + } + if (rightOp.next < leftOp.next) { + return TransformResult.right([new TestSetOp(rightOp.next, leftOp.next)]); + } + return TransformResult.empty(); + }) + .withSquashFunction(TestSetOp, TestSetOp, (prevOp: TestSetOp, nextOp: TestSetOp) => { + return new TestSetOp(prevOp.prev, nextOp.next); + }) + .withEmptyPredicate(TestSetOp, (op: TestSetOp) => op.prev === op.next) + .withInvertFunction(TestSetOp, (op: TestSetOp) => new TestSetOp(op.next, op.prev)) + .build(); + +const testArrayOTResolver: OTSystem> = new OTSystemBuilder() + .withTransformFunction(TestArrayOp, TestArrayOp, (leftOp: TestArrayOp, rightOp: TestArrayOp) => { + return TransformResult.of([rightOp], [leftOp]); + }) + .withSquashFunction(TestArrayOp, TestArrayOp, (prevOp: TestArrayOp, nextOp: TestArrayOp) => { + if (prevOp.string !== nextOp.string) return null; + if (prevOp.remove !== nextOp.remove) return new TestArrayOp("", true); + return prevOp; + }) + .withEmptyPredicate(TestArrayOp, (op: TestArrayOp) => op.string === "") + .withInvertFunction(TestArrayOp, (op: TestArrayOp) => new TestArrayOp(op.string, !op.remove)) + .build(); + + +export class State { + number1: number = 0; + number2: number = 0; + strings: Set = new Set(); +} + +export class MultiOp implements OTOperation { + ops1: Array; + ops2: Array; + ops3: Array; + + constructor(ops1: Array, ops2: Array, ops3: Array) { + this.ops1 = ops1; + this.ops2 = ops2; + this.ops3 = ops3; + } + + apply(state: State): State { + this.ops1.forEach(op => state.number1 = op.apply(state.number1)); + this.ops2.forEach(op => state.number2 = op.apply(state.number2)); + this.ops3.forEach(op => state.strings = op.apply(state.strings)); + return state; + } +} + +export const testMergedOTResolver: OTSystem = MergedOTSystem.merge3((a1, a2, a3) => new MultiOp(a1, a2, a3), + multiOp => multiOp.ops1, testAddOTResolver, + multiOp => multiOp.ops2, testSetOTResolver, + multiOp => multiOp.ops3, testArrayOTResolver +); diff --git a/src/test/testOTResolver.js b/src/test/testOTResolver.js index 3e18570..b7bba10 100644 --- a/src/test/testOTResolver.js +++ b/src/test/testOTResolver.js @@ -13,9 +13,9 @@ import {OTSystemBuilder} from '../ot/OTSystem/OTSystemBuilder'; import TestAddOp from './TestAddOp'; import TestSetOp from './TestSetOp'; -import type OTSystem from '../ot/OTSystem/OTSystem'; +import type OTSystemImpl from '../ot/OTSystem/OTSystemImpl'; -const testOTResolver: OTSystem = new OTSystemBuilder() +const testOTResolver: OTSystemImpl = new OTSystemBuilder() .withTransformFunction(TestAddOp, TestAddOp, (leftOp: TestAddOp, rightOp: TestAddOp) => { return TransformResult.of([ new TestAddOp(leftOp.prev + leftOp.delta, rightOp.delta)