diff --git a/.eslintignore b/.eslintignore index 6ff4ce5d..f7c44ebd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,2 @@ src/core/vendor/** -src/core/operations/legacy/** \ No newline at end of file +src/core/operations/legacy/** diff --git a/Gruntfile.js b/Gruntfile.js index df06ba2e..81d838b5 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -22,11 +22,11 @@ module.exports = function (grunt) { // Tasks grunt.registerTask("dev", "A persistent task which creates a development build whenever source files are modified.", - ["clean:dev", "webpack-dev-server:start"]); + ["clean:dev", "exec:generateConfig", "concurrent:dev"]); grunt.registerTask("node", "Compiles CyberChef into a single NodeJS module.", - ["clean:node", "clean:config", "webpack:node", "chmod:build"]); + ["clean:node", "clean:config", "exec:generateConfig", "webpack:node", "chmod:build"]); grunt.registerTask("test", "A task which runs all the tests in test/tests.", @@ -38,7 +38,7 @@ module.exports = function (grunt) { grunt.registerTask("prod", "Creates a production-ready build. Use the --msg flag to add a compile message.", - ["eslint", "clean:prod", "webpack:web", "inline", "chmod"]); + ["eslint", "clean:prod", "exec:generateConfig", "webpack:web", "inline", "chmod"]); grunt.registerTask("default", "Lints the code base", @@ -46,7 +46,7 @@ module.exports = function (grunt) { grunt.registerTask("inline", "Compiles a production build of CyberChef into a single, portable web page.", - ["webpack:webInline", "runInliner", "clean:inlineScripts"]); + ["exec:generateConfig", "webpack:webInline", "runInliner", "clean:inlineScripts"]); grunt.registerTask("runInliner", runInliner); @@ -61,9 +61,11 @@ module.exports = function (grunt) { grunt.loadNpmTasks("grunt-jsdoc"); grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-contrib-watch"); grunt.loadNpmTasks("grunt-chmod"); grunt.loadNpmTasks("grunt-exec"); grunt.loadNpmTasks("grunt-accessibility"); + grunt.loadNpmTasks("grunt-concurrent"); // Project configuration @@ -278,7 +280,7 @@ module.exports = function (grunt) { chunks: false, modules: false, entrypoints: false, - warningsFilter: /source-map/, + warningsFilter: [/source-map/, /dependency is an expression/], } }, start: { @@ -348,6 +350,18 @@ module.exports = function (grunt) { src: ["docs/**/*", "docs/"] } }, + watch: { + config: { + files: ["src/core/operations/**/*", "!src/core/operations/index.mjs"], + tasks: ["exec:generateConfig"] + } + }, + concurrent: { + dev: ["watch:config", "webpack-dev-server:start"], + options: { + logConcurrentOutput: true + } + }, exec: { repoSize: { command: [ @@ -364,9 +378,13 @@ module.exports = function (grunt) { }, generateConfig: { command: [ + "echo '\n--- Regenerating config files. ---'", + "mkdir -p src/core/config/modules", + "echo 'export default {};\n' > src/core/config/modules/OpModules.mjs", + "echo '[]\n' > src/core/config/OperationConfig.json", "node --experimental-modules src/core/config/scripts/generateOpsIndex.mjs", "node --experimental-modules src/core/config/scripts/generateConfig.mjs", - "echo ---\nConfig scripts finished.\n---\n" + "echo '--- Config scripts finished. ---\n'" ].join(";") }, tests: { diff --git a/package-lock.json b/package-lock.json index 1bcdb061..35b473b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,222 @@ { "name": "cyberchef", - "version": "7.9.0", + "version": "7.11.1", "lockfileVersion": 1, "requires": true, "dependencies": { + "@webassemblyjs/ast": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", + "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "debug": "3.1.0", + "webassemblyjs": "1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", + "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", + "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", + "dev": true, + "requires": { + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", + "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.4.3" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", + "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", + "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", + "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/leb128": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", + "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "dev": true, + "requires": { + "leb": "0.3.0" + } + }, + "@webassemblyjs/validation": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", + "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3" + } + }, + "@webassemblyjs/wasm-edit": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", + "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/helper-wasm-section": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-opt": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-printer": "1.4.3", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", + "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", + "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", + "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", + "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/floating-point-hex-parser": "1.4.3", + "@webassemblyjs/helper-code-frame": "1.4.3", + "@webassemblyjs/helper-fsm": "1.4.3", + "long": "3.2.0", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", + "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "3.2.0" + } + }, "JSONSelect": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz", @@ -29,23 +242,6 @@ "requires": { "mime-types": "2.1.18", "negotiator": "0.6.1" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - } } }, "access-sniff": { @@ -56,57 +252,37 @@ "requires": { "axios": "0.18.0", "bluebird": "3.5.1", - "chalk": "2.3.1", - "commander": "2.14.1", + "chalk": "2.4.1", + "commander": "2.15.1", "glob": "7.1.2", - "html_codesniffer": "2.1.1", - "jsdom": "11.6.2", + "html_codesniffer": "2.2.0", + "jsdom": "11.10.0", "mkdirp": "0.5.1", "phantomjs-prebuilt": "2.1.16", - "rc": "1.2.5", - "underscore": "1.8.3", + "rc": "1.2.7", + "underscore": "1.9.0", "unixify": "1.0.0", "validator": "9.4.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==", + "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" + "color-convert": "1.9.1" } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "supports-color": "5.4.0" } }, "has-flag": { @@ -116,26 +292,26 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" } }, "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.0.tgz", + "integrity": "sha512-4IV1DSSxC1QK48j9ONFK1MoIAKKkbE8i7u55w2R6IqBqbT7A/iG7aZBCR2Bi8piF0Uz+i/MG1aeqLwl/5vqF+A==", "dev": true } } }, "acorn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", - "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "acorn-dynamic-import": { @@ -144,7 +320,7 @@ "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", "dev": true, "requires": { - "acorn": "5.5.0" + "acorn": "5.5.3" } }, "acorn-globals": { @@ -153,7 +329,7 @@ "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", "dev": true, "requires": { - "acorn": "5.5.0" + "acorn": "5.5.3" } }, "acorn-jsx": { @@ -174,34 +350,23 @@ } }, "ajv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", - "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, - "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.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", @@ -214,9 +379,9 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, "ansi-escapes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, "ansi-html": { @@ -241,7 +406,7 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.9", + "micromatch": "3.1.10", "normalize-path": "2.1.1" } }, @@ -309,7 +474,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.10.0" + "es-abstract": "1.11.0" } }, "array-union": { @@ -360,7 +525,7 @@ "requires": { "bn.js": "4.11.8", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -385,12 +550,12 @@ "dev": true }, "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "async-each": { @@ -412,9 +577,9 @@ "dev": true }, "atob": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", - "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", "dev": true }, "autoprefixer": { @@ -424,7 +589,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000810", + "caniuse-db": "1.0.30000843", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -437,8 +602,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000843", + "electron-to-chromium": "1.3.47" } } } @@ -450,9 +615,9 @@ "dev": true }, "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", "dev": true }, "axios": { @@ -476,9 +641,9 @@ } }, "babel-core": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", - "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { "babel-code-frame": "6.26.0", @@ -494,12 +659,20 @@ "convert-source-map": "1.5.1", "debug": "2.6.9", "json5": "0.5.1", - "lodash": "4.17.5", + "lodash": "4.17.10", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", "private": "0.1.8", "slash": "1.0.0", "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "babel-generator": { @@ -513,7 +686,7 @@ "babel-types": "6.26.0", "detect-indent": "4.0.0", "jsesc": "1.3.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "source-map": "0.5.7", "trim-right": "1.0.1" }, @@ -523,6 +696,12 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -558,7 +737,7 @@ "babel-helper-function-name": "6.24.1", "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-helper-explode-assignable-expression": { @@ -623,7 +802,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-helper-remap-async-to-generator": { @@ -664,9 +843,9 @@ } }, "babel-loader": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.3.tgz", - "integrity": "sha512-PeN29YvOynPMvNk7QCzsHqxpmfXwKAC+uxkiSNFQsmXBBVltzEkVWmv/Ip3tx7yk149dQUwk497bTXNu+DZjLA==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz", + "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==", "dev": true, "requires": { "find-cache-dir": "1.0.0", @@ -757,7 +936,7 @@ "babel-template": "6.26.0", "babel-traverse": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-plugin-transform-es2015-classes": { @@ -841,15 +1020,15 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", "babel-runtime": "6.26.0", "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", - "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { "babel-plugin-transform-strict-mode": "6.24.1", @@ -999,7 +1178,7 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.3", + "core-js": "2.5.6", "regenerator-runtime": "0.10.5" }, "dependencies": { @@ -1011,9 +1190,9 @@ } }, "babel-preset-env": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", - "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "requires": { "babel-plugin-check-es2015-constants": "6.22.0", @@ -1030,7 +1209,7 @@ "babel-plugin-transform-es2015-function-name": "6.24.1", "babel-plugin-transform-es2015-literals": "6.22.0", "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", "babel-plugin-transform-es2015-modules-umd": "6.24.1", "babel-plugin-transform-es2015-object-super": "6.24.1", @@ -1043,9 +1222,9 @@ "babel-plugin-transform-es2015-unicode-regex": "6.24.1", "babel-plugin-transform-exponentiation-operator": "6.24.1", "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.11.3", - "invariant": "2.2.3", - "semver": "5.4.1" + "browserslist": "3.2.7", + "invariant": "2.2.4", + "semver": "5.5.0" } }, "babel-register": { @@ -1054,11 +1233,11 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "6.26.0", + "babel-core": "6.26.3", "babel-runtime": "6.26.0", - "core-js": "2.5.3", + "core-js": "2.5.6", "home-or-tmp": "2.0.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "mkdirp": "0.5.1", "source-map-support": "0.4.18" } @@ -1068,7 +1247,7 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.3", + "core-js": "2.5.6", "regenerator-runtime": "0.11.1" } }, @@ -1081,7 +1260,7 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-traverse": { @@ -1096,8 +1275,8 @@ "babylon": "6.18.0", "debug": "2.6.9", "globals": "9.18.0", - "invariant": "2.2.3", - "lodash": "4.17.5" + "invariant": "2.2.4", + "lodash": "4.17.10" } }, "babel-types": { @@ -1107,7 +1286,7 @@ "requires": { "babel-runtime": "6.26.0", "esutils": "2.0.2", - "lodash": "4.17.5", + "lodash": "4.17.10", "to-fast-properties": "1.0.3" } }, @@ -1145,13 +1324,42 @@ "requires": { "is-descriptor": "1.0.2" } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } } } }, "base64-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", - "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, "batch": { @@ -1168,6 +1376,15 @@ "optional": true, "requires": { "tweetnacl": "0.14.5" + }, + "dependencies": { + "tweetnacl": { + "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 + } } }, "bcryptjs": { @@ -1182,9 +1399,9 @@ "dev": true }, "bignumber.js": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-6.0.0.tgz", - "integrity": "sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.1.0.tgz", + "integrity": "sha512-ioirFr31dV5NwDdw6bFYCi9a62dBhGHohVmWYh0VS84GGbQsb69kIZ1wyqXNqFaPJmvIt9EXpqenk/0hc8tiTQ==" }, "binary-extensions": { "version": "1.11.0", @@ -1193,60 +1410,106 @@ "dev": true }, "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", "dev": true }, + "bn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bn/-/bn-1.0.1.tgz", + "integrity": "sha1-oVOCXmsessLbdyYUmwR6B84KO7M=" + }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, - "body-parser": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", - "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { - "bytes": "2.2.0", + "continuable-cache": "0.3.1", + "error": "7.0.2", + "raw-body": "1.1.7", + "safe-json-parse": "1.0.1" + } + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", "content-type": "1.0.4", - "debug": "2.2.0", + "debug": "2.6.9", "depd": "1.1.2", - "http-errors": "1.3.1", - "iconv-lite": "0.4.13", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", "on-finished": "2.3.0", - "qs": "5.2.0", - "raw-body": "2.1.7", + "qs": "6.5.1", + "raw-body": "2.3.2", "type-is": "1.6.16" }, "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true }, "qs": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", - "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + } + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", "dev": true } } @@ -1277,7 +1540,7 @@ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } }, "bootstrap": { @@ -1299,9 +1562,9 @@ "integrity": "sha1-cOCusqh3wNx2aZHeEI4hcPwpov8=" }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "1.0.0", @@ -1309,34 +1572,23 @@ } }, "braces": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", - "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "1.1.0", "array-unique": "0.3.2", - "define-property": "1.0.0", "extend-shallow": "2.0.1", "fill-range": "4.0.0", "isobject": "3.0.1", - "kind-of": "6.0.2", "repeat-element": "1.1.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "snapdragon-node": "2.1.1", "split-string": "3.1.0", "to-regex": "3.0.2" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -1345,12 +1597,6 @@ "requires": { "is-extendable": "0.1.1" } - }, - "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 } } }, @@ -1367,34 +1613,34 @@ "dev": true }, "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", "evp_bytestokey": "1.0.3" } }, "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", + "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { "cipher-base": "1.0.4", @@ -1420,44 +1666,36 @@ "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", "elliptic": "6.4.0", "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "parse-asn1": "5.1.1" } }, "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "0.2.9" + "pako": "1.0.6" } }, "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.7.tgz", + "integrity": "sha512-oYVLxFVqpX9uMhOIQBLtZL+CX4uY8ZpWcjNTaxyWl5rO8yA9SSNikFnAfvk8J3P/7z3BZwNmEqFKaJoYltj3MQ==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000810", - "electron-to-chromium": "1.3.34" - }, - "dependencies": { - "electron-to-chromium": { - "version": "1.3.34", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", - "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", - "dev": true - } + "caniuse-lite": "1.0.30000843", + "electron-to-chromium": "1.3.47" } }, "bson": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/bson/-/bson-2.0.4.tgz", - "integrity": "sha512-e/GPy6CE0xL7MOYYRMIEwPGKF21WNaQdPIpV0YvaQDoR7oc47KUZ8c2P/TlRJVQP8RZ4CEsArGBC1NbkCRvl1w==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-2.0.6.tgz", + "integrity": "sha512-DH9Xvo+zN7PnS6rmQauNWLZqICiwOXygoh0nppbJrcpGv6XUyon6S/rGSvUkR3SdyqHQ6YjSkxmSnmqOhUZNew==" }, "buffer": { "version": "4.9.1", @@ -1465,11 +1703,17 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.8", + "base64-js": "1.3.0", + "ieee754": "1.1.11", "isarray": "1.0.0" } }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "dev": true + }, "buffer-indexof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", @@ -1495,11 +1739,16 @@ "dev": true }, "bytes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", - "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", "dev": true }, + "bzip-deflate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bzip-deflate/-/bzip-deflate-1.0.0.tgz", + "integrity": "sha1-sC2wB+83vrzCk4Skssb08PTHlsk=" + }, "cacache": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", @@ -1510,46 +1759,15 @@ "chownr": "1.0.1", "glob": "7.1.2", "graceful-fs": "4.1.11", - "lru-cache": "4.1.1", + "lru-cache": "4.1.3", "mississippi": "2.0.0", "mkdirp": "0.5.1", "move-concurrently": "1.0.1", "promise-inflight": "1.0.1", "rimraf": "2.6.2", - "ssri": "5.2.4", + "ssri": "5.3.0", "unique-filename": "1.1.0", "y18n": "4.0.0" - }, - "dependencies": { - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - } } }, "cache-base": { @@ -1617,7 +1835,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000810", + "caniuse-db": "1.0.30000843", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1628,22 +1846,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000843", + "electron-to-chromium": "1.3.47" } } } }, "caniuse-db": { - "version": "1.0.30000810", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000810.tgz", - "integrity": "sha1-vSWDDEHvq2Qzmi44H0lnc0PIRQk=", + "version": "1.0.30000843", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000843.tgz", + "integrity": "sha1-T36FAfVX3JvNN90zrIWQXHZe/sI=", "dev": true }, "caniuse-lite": { - "version": "1.0.30000810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz", - "integrity": "sha512-/0Q00Oie9C72P8zQHtFvzmkrMC3oOFUnMWjCy5F2+BE8lzICm91hQPhh0+XIsAFPKOe2Dh3pKgbRmU3EKxfldA==", + "version": "1.0.30000843", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000843.tgz", + "integrity": "sha512-1ntiW826MhRBmM0CeI7w1cQr16gxwOoM8doJWh3BFalPZoKWdZXs27Bc04xth/3NR1/wNXn9cpP4F92lVenCvg==", "dev": true }, "caseless": { @@ -1661,16 +1879,6 @@ "underscore-contrib": "0.3.0" } }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1689,16 +1897,24 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, + "chi-squared": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chi-squared/-/chi-squared-1.1.0.tgz", + "integrity": "sha1-iShlz/qOCnIPkhv8nGNcGawqNG0=", + "requires": { + "gamma": "1.0.0" + } + }, "chokidar": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", - "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "dev": true, "requires": { "anymatch": "2.0.0", "async-each": "1.0.1", - "braces": "2.3.1", - "fsevents": "1.1.3", + "braces": "2.3.2", + "fsevents": "1.2.4", "glob-parent": "3.1.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -1706,7 +1922,7 @@ "normalize-path": "2.1.1", "path-is-absolute": "1.0.1", "readdirp": "2.1.0", - "upath": "1.0.4" + "upath": "1.1.0" } }, "chownr": { @@ -1716,9 +1932,9 @@ "dev": true }, "chrome-trace-event": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.2.tgz", - "integrity": "sha1-kPNohdU0WlBiEzLwcXtZWIPV2YI=", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", + "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", "dev": true }, "cipher-base": { @@ -1728,7 +1944,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "circular-json": { @@ -1771,73 +1987,24 @@ "requires": { "is-descriptor": "0.1.6" } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true } } }, "clean-css": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz", - "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", + "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", "dev": true, "requires": { "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "cli": { @@ -1848,22 +2015,6 @@ "requires": { "exit": "0.1.2", "glob": "7.1.2" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } } }, "cli-cursor": { @@ -1882,28 +2033,37 @@ "dev": true }, "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" }, "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true + }, + "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" + } } } }, "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "co": { @@ -1949,15 +2109,15 @@ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "dev": true, "requires": { - "clone": "1.0.3", - "color-convert": "1.9.0", + "clone": "1.0.4", + "color-convert": "1.9.1", "color-string": "0.3.0" } }, "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { "color-name": "1.1.3" @@ -1995,18 +2155,18 @@ "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=" }, "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { "delayed-stream": "1.0.0" } }, "commander": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", - "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, "commondir": { @@ -2028,19 +2188,11 @@ "dev": true, "requires": { "mime-db": "1.33.0" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - } } }, "compression": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.2.tgz", + "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", "dev": true, "requires": { @@ -2058,6 +2210,12 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true } } }, @@ -2068,13 +2226,14 @@ "dev": true }, "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { + "buffer-from": "1.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "typedarray": "0.0.6" } }, @@ -2111,10 +2270,10 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", "dev": true }, "convert-source-map": { @@ -2147,17 +2306,6 @@ "mkdirp": "0.5.1", "rimraf": "2.6.2", "run-queue": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.0.6" - } - } } }, "copy-descriptor": { @@ -2167,9 +2315,9 @@ "dev": true }, "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", + "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==" }, "core-util-is": { "version": "1.0.2", @@ -2190,20 +2338,12 @@ "os-homedir": "1.0.2", "parse-json": "2.2.0", "require-from-string": "1.2.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -2211,29 +2351,30 @@ } }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { "cipher-base": "1.0.4", "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.10" + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "cross-spawn": { @@ -2242,9 +2383,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.3", "shebang-command": "1.2.0", - "which": "1.2.14" + "which": "1.3.0" } }, "cryptiles": { @@ -2262,7 +2403,7 @@ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } } } @@ -2278,15 +2419,15 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "1.0.0", + "browserify-cipher": "1.0.1", "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", "randombytes": "2.0.6", "randomfill": "1.0.4" } @@ -2303,9 +2444,9 @@ "dev": true }, "css-loader": { - "version": "0.28.10", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.10.tgz", - "integrity": "sha512-X1IJteKnW9Llmrd+lJ0f7QZHh9Arf+11S7iRcoT2+riig3BK0QaCaOtubAulMK6Itbo08W6d3l8sW21r+Jhp5Q==", + "version": "0.28.11", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", + "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", "dev": true, "requires": { "babel-code-frame": "6.26.0", @@ -2353,7 +2494,7 @@ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { - "regenerate": "1.3.3", + "regenerate": "1.4.0", "regjsgen": "0.2.0", "regjsparser": "0.1.5" } @@ -2420,6 +2561,14 @@ "requires": { "clap": "1.2.3", "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "cssom": { @@ -2457,6 +2606,15 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.42" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2466,21 +2624,32 @@ "assert-plus": "1.0.0" } }, - "datauri": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/datauri/-/datauri-1.0.5.tgz", - "integrity": "sha1-0JddGrbI8uDOPKQ7qkU5vhLSiaA=", + "data-urls": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", + "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", "dev": true, "requires": { - "image-size": "0.3.5", - "mimer": "0.2.3", - "semver": "5.4.1" + "abab": "1.0.4", + "whatwg-mimetype": "2.1.0", + "whatwg-url": "6.4.1" + } + }, + "datauri": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/datauri/-/datauri-1.1.0.tgz", + "integrity": "sha512-0q+cTTKx7q8eDteZRIQLTFJuiIsVing17UbWTPssY4JLSMaYsk/VKpNulBDo9NSgQWcvlPrkEHW8kUO67T/7mQ==", + "dev": true, + "requires": { + "image-size": "0.6.2", + "mimer": "0.3.2", + "semver": "5.5.0" }, "dependencies": { "image-size": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.3.5.tgz", - "integrity": "sha1-gyQOqy+1sAsEqrjHSwRx6cunrYw=", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.2.tgz", + "integrity": "sha512-pH3vDzpczdsKHdZ9xxR3O46unSjisgVx0IImay7Zz2EdhRVbCkj+nthx9OuuWEhakx9FAO+fNVGrF0rZ2oMOvw==", "dev": true } } @@ -2524,22 +2693,21 @@ "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", "dev": true }, "deep-for-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/deep-for-each/-/deep-for-each-1.0.6.tgz", - "integrity": "sha1-r6DOJJxYSSqXIFOUeKGNN+GxC64=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/deep-for-each/-/deep-for-each-2.0.3.tgz", + "integrity": "sha512-Y9mu+rplGcNZ7veer+5rqcdI9w3aPb7/WyE/nYnsuPevaE2z5YuC2u7/Gz/hIKsa0zo8sE8gKoBimSNsO/sr+A==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "lodash.isplainobject": "4.0.6" } }, "deep-is": { @@ -2565,6 +2733,37 @@ "requires": { "is-descriptor": "1.0.2", "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "defined": { @@ -2581,11 +2780,19 @@ "requires": { "globby": "5.0.0", "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1", - "rimraf": "2.2.8" + "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "delayed-stream": { @@ -2607,7 +2814,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "destroy": { @@ -2632,14 +2839,14 @@ "dev": true }, "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==" + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -2660,7 +2867,7 @@ "dev": true, "requires": { "ip": "1.1.5", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "dns-txt": { @@ -2713,6 +2920,12 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true } } }, @@ -2757,14 +2970,14 @@ } }, "duplexify": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", - "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", "dev": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-shift": "1.0.0" } }, @@ -2799,9 +3012,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz", - "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=", + "version": "1.3.47", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.47.tgz", + "integrity": "sha1-dk6IfKkQTQGgrI6r7n38DizhQQQ=", "dev": true }, "elliptic": { @@ -2815,7 +3028,7 @@ "hash.js": "1.1.3", "hmac-drbg": "1.0.1", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -2832,9 +3045,9 @@ "dev": true }, "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { "once": "1.4.0" @@ -2852,9 +3065,9 @@ } }, "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", "dev": true }, "errno": { @@ -2866,6 +3079,16 @@ "prr": "1.0.1" } }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "dev": true, + "requires": { + "string-template": "0.2.1", + "xtend": "4.0.1" + } + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", @@ -2876,9 +3099,9 @@ } }, "es-abstract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", - "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", + "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2899,6 +3122,28 @@ "is-symbol": "1.0.1" } }, + "es5-ext": { + "version": "0.10.42", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz", + "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.42", + "es6-symbol": "3.1.1" + } + }, "es6-object-assign": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", @@ -2924,6 +3169,21 @@ "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz", "integrity": "sha1-84kl8jyz4+jObNqP93T867sJDN4=" }, + "es6-promisify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.0.tgz", + "integrity": "sha512-8Tbqjrb8lC85dd81haajYwuRmiU2rkqNAFnlvQOJeeKqdUloIlI+JcUqeJruV4rCm5Y7oNU7jfs2FbmxhRR/2g==" + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.42" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2951,12 +3211,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true } } }, @@ -2976,35 +3230,35 @@ } }, "eslint": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.1.tgz", - "integrity": "sha512-gPSfpSRCHre1GLxGmO68tZNxOlL2y7xBd95VcLD+Eo4S2js31YoMum3CAQIOaxY24hqYOMksMvW38xuuWKQTgw==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { "ajv": "5.5.2", "babel-code-frame": "6.26.0", - "chalk": "2.3.1", - "concat-stream": "1.6.0", + "chalk": "2.4.1", + "concat-stream": "1.6.2", "cross-spawn": "5.1.0", "debug": "3.1.0", "doctrine": "2.1.0", "eslint-scope": "3.7.1", "eslint-visitor-keys": "1.0.0", - "espree": "3.5.3", - "esquery": "1.0.0", + "espree": "3.5.4", + "esquery": "1.0.1", "esutils": "2.0.2", "file-entry-cache": "2.0.0", "functional-red-black-tree": "1.0.1", "glob": "7.1.2", - "globals": "11.3.0", - "ignore": "3.3.7", + "globals": "11.5.0", + "ignore": "3.3.8", "imurmurhash": "0.1.4", "inquirer": "3.3.0", "is-resolvable": "1.1.0", - "js-yaml": "3.10.0", + "js-yaml": "3.11.0", "json-stable-stringify-without-jsonify": "1.0.1", "levn": "0.3.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "minimatch": "3.0.4", "mkdirp": "0.5.1", "natural-compare": "1.4.0", @@ -3012,26 +3266,15 @@ "path-is-inside": "1.0.2", "pluralize": "7.0.0", "progress": "2.0.0", + "regexpp": "1.1.0", "require-uncached": "1.0.3", - "semver": "5.4.1", + "semver": "5.5.0", "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", - "table": "4.0.3", + "table": "4.0.2", "text-table": "0.2.0" }, "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -3039,23 +3282,23 @@ "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "debug": { @@ -3067,24 +3310,10 @@ "ms": "2.0.0" } }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, "globals": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz", - "integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", + "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", "dev": true }, "has-flag": { @@ -3094,9 +3323,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.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "dev": true, "requires": { "argparse": "1.0.10", @@ -3119,9 +3348,9 @@ } }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -3135,7 +3364,7 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "4.2.0", + "esrecurse": "4.2.1", "estraverse": "4.2.0" } }, @@ -3229,21 +3458,13 @@ } }, "espree": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.3.tgz", - "integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.5.0", + "acorn": "5.5.3", "acorn-jsx": "3.0.1" - }, - "dependencies": { - "acorn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", - "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", - "dev": true - } } }, "esprima": { @@ -3252,22 +3473,21 @@ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" }, "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "4.2.0" } }, "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "estraverse": "4.2.0" } }, "esshorten": { @@ -3310,9 +3530,9 @@ "dev": true }, "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, "events": { @@ -3327,7 +3547,7 @@ "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", "dev": true, "requires": { - "original": "1.0.0" + "original": "1.0.1" } }, "evp_bytestokey": { @@ -3337,7 +3557,7 @@ "dev": true, "requires": { "md5.js": "1.3.4", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "execa": { @@ -3377,7 +3597,7 @@ "extend-shallow": "2.0.1", "posix-character-classes": "0.1.1", "regex-not": "1.0.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "to-regex": "3.0.2" }, "dependencies": { @@ -3398,105 +3618,6 @@ "requires": { "is-extendable": "0.1.1" } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - }, - "dependencies": { - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } } } }, @@ -3519,9 +3640,9 @@ } }, "express": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", - "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "dev": true, "requires": { "accepts": "1.3.5", @@ -3536,7 +3657,7 @@ "encodeurl": "1.0.2", "escape-html": "1.0.3", "etag": "1.8.1", - "finalhandler": "1.1.0", + "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "1.1.2", @@ -3547,10 +3668,10 @@ "qs": "6.5.1", "range-parser": "1.2.0", "safe-buffer": "5.1.1", - "send": "0.16.1", - "serve-static": "1.13.1", + "send": "0.16.2", + "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.3.1", + "statuses": "1.4.0", "type-is": "1.6.16", "utils-merge": "1.0.1", "vary": "1.1.2" @@ -3562,72 +3683,16 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "1.6.16" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", "dev": true }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - } - } - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true } } @@ -3660,13 +3725,13 @@ } }, "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { "chardet": "0.4.2", - "iconv-lite": "0.4.19", + "iconv-lite": "0.4.23", "tmp": "0.0.33" } }, @@ -3682,7 +3747,7 @@ "extend-shallow": "2.0.1", "fragment-cache": "0.2.1", "regex-not": "1.0.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "to-regex": "3.0.2" }, "dependencies": { @@ -3703,6 +3768,35 @@ "requires": { "is-extendable": "0.1.1" } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } } } }, @@ -3712,49 +3806,10 @@ "integrity": "sha512-Hypkn9jUTnFr0DpekNam53X47tXn3ucY08BQumv7kdGgeVUBLq3DJHJTi6HNxv4jl9W+Skxjz9+RnK0sJyqqjA==", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "loader-utils": "1.1.0", "schema-utils": "0.4.5", "webpack-sources": "1.1.0" - }, - "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", - "dev": true, - "requires": { - "source-list-map": "2.0.0", - "source-map": "0.6.1" - } - } } }, "extract-zip": { @@ -3769,6 +3824,23 @@ "yauzl": "2.4.1" }, "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, "mkdirp": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", @@ -3787,9 +3859,9 @@ "dev": true }, "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { @@ -3847,48 +3919,19 @@ } }, "file-loader": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.10.tgz", - "integrity": "sha512-dNnT4yJgUPtGDg0+m03kQ0b/PZi3Y12EnqYuRPNCsbYkBZc6j+fwVWy40jWzZjn5kIzQ4BLIxzJimbwAYlnPGw==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "dev": true, "requires": { "loader-utils": "1.1.0", "schema-utils": "0.4.5" - }, - "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "dev": true - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - } } }, "file-saver": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", - "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI=" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz", + "integrity": "sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg==" }, "file-sync-cmp": { "version": "0.1.1", @@ -3896,12 +3939,6 @@ "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=", "dev": true }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -3926,9 +3963,9 @@ } }, "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { "debug": "2.6.9", @@ -3936,16 +3973,8 @@ "escape-html": "1.0.3", "on-finished": "2.3.0", "parseurl": "1.3.2", - "statuses": "1.3.1", + "statuses": "1.4.0", "unpipe": "1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } } }, "find-cache-dir": { @@ -3955,7 +3984,7 @@ "dev": true, "requires": { "commondir": "1.0.1", - "make-dir": "1.2.0", + "make-dir": "1.3.0", "pkg-dir": "2.0.0" } }, @@ -4011,13 +4040,13 @@ "dev": true }, "flush-write-stream": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz", - "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "follow-redirects": { @@ -4046,15 +4075,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", @@ -4068,14 +4088,14 @@ "dev": true }, "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "forwarded": { @@ -4106,7 +4126,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "fs-extra": { @@ -4129,7 +4149,7 @@ "graceful-fs": "4.1.11", "iferr": "0.1.5", "imurmurhash": "0.1.4", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "fs.realpath": { @@ -4139,39 +4159,29 @@ "dev": true }, "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", "dev": true, "optional": true, "requires": { - "nan": "2.8.0", - "node-pre-gyp": "0.6.39" + "nan": "2.10.0", + "node-pre-gyp": "0.10.0" }, "dependencies": { "abbrev": { - "version": "1.1.0", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, "ansi-regex": { "version": "2.1.1", "bundled": true, "dev": true }, "aproba": { - "version": "1.1.1", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true @@ -4183,91 +4193,25 @@ "optional": true, "requires": { "delegates": "1.0.0", - "readable-stream": "2.2.9" + "readable-stream": "2.3.6" } }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { "version": "1.0.0", "bundled": true, "dev": true }, - "caseless": { - "version": "0.12.0", + "brace-expansion": { + "version": "1.1.11", "bundled": true, "dev": true, - "optional": true + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } }, - "co": { - "version": "4.6.0", + "chownr": { + "version": "1.0.1", "bundled": true, "dev": true, "optional": true @@ -4277,14 +4221,6 @@ "bundled": true, "dev": true }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, "concat-map": { "version": "0.0.1", "bundled": true, @@ -4298,35 +4234,11 @@ "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "debug": { - "version": "2.6.8", + "version": "2.6.9", "bundled": true, "dev": true, "optional": true, @@ -4335,16 +4247,11 @@ } }, "deep-extend": { - "version": "0.4.2", + "version": "0.5.1", "bundled": true, "dev": true, "optional": true }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, "delegates": { "version": "1.0.0", "bundled": true, @@ -4352,74 +4259,25 @@ "optional": true }, "detect-libc": { - "version": "1.0.2", + "version": "1.0.3", "bundled": true, "dev": true, "optional": true }, - "ecc-jsbn": { - "version": "0.1.1", + "fs-minipass": { + "version": "1.2.5", "bundled": true, "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "minipass": "2.2.4" } }, "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } + "optional": true }, "gauge": { "version": "2.7.4", @@ -4427,7 +4285,7 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.1.1", + "aproba": "1.2.0", "console-control-strings": "1.1.0", "has-unicode": "2.0.1", "object-assign": "4.1.1", @@ -4437,27 +4295,11 @@ "wide-align": "1.1.2" } }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, "glob": { "version": "7.1.2", "bundled": true, "dev": true, + "optional": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -4467,64 +4309,35 @@ "path-is-absolute": "1.0.1" } }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, "has-unicode": { "version": "2.0.1", "bundled": true, "dev": true, "optional": true }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", + "iconv-lite": { + "version": "0.4.21", "bundled": true, "dev": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "safer-buffer": "2.1.2" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "3.0.4" } }, "inflight": { "version": "1.0.6", "bundled": true, "dev": true, + "optional": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -4536,7 +4349,7 @@ "dev": true }, "ini": { - "version": "1.3.4", + "version": "1.3.5", "bundled": true, "dev": true, "optional": true @@ -4549,104 +4362,18 @@ "number-is-nan": "1.0.1" } }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, "isarray": { "version": "1.0.0", "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, "dev": true, "optional": true }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, "minimatch": { "version": "3.0.4", "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -4654,6 +4381,24 @@ "bundled": true, "dev": true }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.1.1", + "yallist": "3.0.2" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "2.2.4" + } + }, "mkdirp": { "version": "0.5.1", "bundled": true, @@ -4668,23 +4413,33 @@ "dev": true, "optional": true }, - "node-pre-gyp": { - "version": "0.6.39", + "needle": { + "version": "2.2.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.3", "mkdirp": "0.5.1", + "needle": "2.2.0", "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.7", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" } }, "nopt": { @@ -4693,12 +4448,28 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" } }, "npmlog": { - "version": "4.1.0", + "version": "4.1.2", "bundled": true, "dev": true, "optional": true, @@ -4714,12 +4485,6 @@ "bundled": true, "dev": true }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, "object-assign": { "version": "4.1.1", "bundled": true, @@ -4747,7 +4512,7 @@ "optional": true }, "osenv": { - "version": "0.1.4", + "version": "0.1.5", "bundled": true, "dev": true, "optional": true, @@ -4759,39 +4524,23 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", + "version": "2.0.0", "bundled": true, "dev": true, "optional": true }, "rc": { - "version": "1.2.1", + "version": "1.2.7", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", + "deep-extend": "0.5.1", + "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" }, @@ -4805,64 +4554,48 @@ } }, "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", + "version": "2.3.6", "bundled": true, "dev": true, "optional": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "rimraf": { - "version": "2.6.1", + "version": "2.6.2", "bundled": true, "dev": true, + "optional": true, "requires": { "glob": "7.1.2" } }, "safe-buffer": { - "version": "5.0.1", + "version": "5.1.1", "bundled": true, "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, "semver": { - "version": "5.3.0", + "version": "5.5.0", "bundled": true, "dev": true, "optional": true @@ -4879,39 +4612,6 @@ "dev": true, "optional": true }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, "string-width": { "version": "1.0.2", "bundled": true, @@ -4923,19 +4623,14 @@ } }, "string_decoder": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "5.1.1" } }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, "strip-ansi": { "version": "3.0.1", "bundled": true, @@ -4951,81 +4646,26 @@ "optional": true }, "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", + "version": "4.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, "dev": true, "optional": true }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, "wide-align": { "version": "1.1.2", "bundled": true, @@ -5039,6 +4679,11 @@ "version": "1.0.2", "bundled": true, "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true } } }, @@ -5054,6 +4699,11 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "gamma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gamma/-/gamma-1.0.0.tgz", + "integrity": "sha1-mDwck5/iPZMnAVhXEeHZpDDLdMs=" + }, "gaze": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", @@ -5103,9 +4753,9 @@ } }, "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -5116,42 +4766,6 @@ "path-is-absolute": "1.0.1" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -5186,10 +4800,18 @@ "requires": { "array-union": "1.0.2", "arrify": "1.0.1", - "glob": "7.0.6", + "glob": "7.1.2", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "globule": { @@ -5199,24 +4821,8 @@ "dev": true, "requires": { "glob": "7.1.2", - "lodash": "4.17.5", + "lodash": "4.17.10", "minimatch": "3.0.4" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } } }, "graceful-fs": { @@ -5239,9 +4845,9 @@ "glob": "7.0.6", "grunt-cli": "1.2.0", "grunt-known-options": "1.1.0", - "grunt-legacy-log": "1.0.0", + "grunt-legacy-log": "1.0.2", "grunt-legacy-util": "1.0.0", - "iconv-lite": "0.4.19", + "iconv-lite": "0.4.23", "js-yaml": "3.5.5", "minimatch": "3.0.4", "nopt": "3.0.6", @@ -5255,6 +4861,20 @@ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, "grunt-cli": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", @@ -5276,6 +4896,12 @@ "argparse": "1.0.10", "esprima": "2.7.3" } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true } } }, @@ -5295,6 +4921,34 @@ "dev": true, "requires": { "shelljs": "0.5.3" + }, + "dependencies": { + "shelljs": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "dev": true + } + } + }, + "grunt-concurrent": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/grunt-concurrent/-/grunt-concurrent-2.3.1.tgz", + "integrity": "sha1-Hj2zjM71o9oRleYdYx/n4yE0TSM=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "async": "1.5.2", + "indent-string": "2.1.0", + "pad-stream": "1.2.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } } }, "grunt-contrib-clean": { @@ -5312,15 +4966,6 @@ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.0.6" - } } } }, @@ -5345,43 +4990,16 @@ "jshint": "2.9.5" } }, - "grunt-contrib-uglify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-2.3.0.tgz", - "integrity": "sha1-s9AmDr3WzvoS/y+Onh4ln33kIW8=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "maxmin": "1.1.0", - "object.assign": "4.1.0", - "uglify-js": "2.8.29", - "uri-path": "1.0.0" - } - }, "grunt-contrib-watch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", - "integrity": "sha1-hKGnodar0m7VaEE0lscxM+mQAY8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", + "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { - "async": "1.5.2", + "async": "2.6.0", "gaze": "1.1.2", - "lodash": "3.10.1", - "tiny-lr": "0.2.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } + "lodash": "4.17.10", + "tiny-lr": "1.1.1" } }, "grunt-eslint": { @@ -5390,43 +5008,43 @@ "integrity": "sha512-VZlDOLrB2KKefDDcx/wR8rEEz7smDwDKVblmooa+itdt/2jWw3ee2AiZB5Ap4s4AoRY0pbHRjZ3HHwY8uKR9Rw==", "dev": true, "requires": { - "chalk": "2.1.0", - "eslint": "4.18.1" + "chalk": "2.4.1", + "eslint": "4.19.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==", + "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "5.4.0" } }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "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.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } @@ -5445,7 +5063,7 @@ "requires": { "cross-spawn": "3.0.1", "jsdoc": "3.5.5", - "marked": "0.3.12" + "marked": "0.3.19" }, "dependencies": { "cross-spawn": { @@ -5454,8 +5072,8 @@ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "dev": true, "requires": { - "lru-cache": "4.1.1", - "which": "1.2.14" + "lru-cache": "4.1.3", + "which": "1.3.0" } } } @@ -5467,16 +5085,15 @@ "dev": true }, "grunt-legacy-log": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz", - "integrity": "sha1-+4bxgJhHvAfcR4Q/ns1srLYt8tU=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.2.tgz", + "integrity": "sha512-WdedTJ/6zCXnI/coaouzqvkI19uwqbcPkdsXiDRKJyB5rOUlOxnCnTVbpeUdEckKVir2uHF3rDBYppj2p6N3+g==", "dev": true, "requires": { "colors": "1.1.2", "grunt-legacy-log-utils": "1.0.0", "hooker": "0.2.3", - "lodash": "3.10.1", - "underscore.string": "3.2.3" + "lodash": "4.17.10" }, "dependencies": { "colors": { @@ -5484,12 +5101,6 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true } } }, @@ -5537,27 +5148,26 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=", "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } } } }, "grunt-webpack": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-3.0.2.tgz", - "integrity": "sha512-ghSkdCdvbF1SpI46qDT9FYqw5ZP5sSYbEQU/DwzoJE1K42xizAZ5Rv3kzpaRdJT4yvu8/6fO5+wne3/y0n74QA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-3.1.2.tgz", + "integrity": "sha512-Ngixl4W/mNJYyghyXJ+JzJ7pUaVRcVKgvC+74ePXPglAEodc9jMlBrGszZAzmspCuvo5dkhbBIcuBHn+Wv1pOQ==", "dev": true, "requires": { - "deep-for-each": "1.0.6", - "lodash": "4.17.5" - } - }, - "gzip-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz", - "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", - "dev": true, - "requires": { - "browserify-zlib": "0.1.4", - "concat-stream": "1.6.0" + "deep-for-each": "2.0.3", + "lodash": "4.17.10" } }, "handle-thing": { @@ -5578,7 +5188,7 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "5.2.3", + "ajv": "5.5.2", "har-schema": "2.0.0" } }, @@ -5644,12 +5254,13 @@ } }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "hash.js": { @@ -5659,7 +5270,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "hasha": { @@ -5680,8 +5291,8 @@ "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.0.2" + "hoek": "4.2.1", + "sntp": "2.1.0" } }, "he": { @@ -5702,14 +5313,14 @@ "dev": true, "requires": { "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", "dev": true }, "home-or-tmp": { @@ -5729,9 +5340,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "hpack.js": { @@ -5741,9 +5352,9 @@ "dev": true, "requires": { "inherits": "2.0.3", - "obuf": "1.1.1", - "readable-stream": "2.3.3", - "wbuf": "1.7.2" + "obuf": "1.1.2", + "readable-stream": "2.3.6", + "wbuf": "1.7.3" } }, "html-comment-regex": { @@ -5768,51 +5379,32 @@ "dev": true }, "html-minifier": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.9.tgz", - "integrity": "sha512-EZqO91XJwkj8BeLx9C12sKB/AHoTANaZax39vEOP9f/X/9jgJ3r1O2+neabuHqpz5kJO71TapP9JrtCY39su1A==", + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.15.tgz", + "integrity": "sha512-OZa4rfb6tZOZ3Z8Xf0jKxXkiDcFWldQePGYFDcgKqES2sXeWaEv9y6QQvWUtX3ySI3feApQi5uCsHLINQ6NoAw==", "dev": true, "requires": { "camel-case": "3.0.0", - "clean-css": "4.1.9", - "commander": "2.14.1", + "clean-css": "4.1.11", + "commander": "2.15.1", "he": "1.1.1", - "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.3.12" - }, - "dependencies": { - "source-map": { - "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.3.12", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.12.tgz", - "integrity": "sha512-4jxrTXlV0HaXTsNILfXW0eey7Qo8qHYM6ih5ZNh45erDWU2GHmKDmekwBTskDb12h+kdd2DBvdzqVb47YzNmTA==", - "dev": true, - "requires": { - "commander": "2.14.1", - "source-map": "0.6.1" - } - } + "uglify-js": "3.3.25" } }, "html-webpack-plugin": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.0.4.tgz", - "integrity": "sha1-SYwQ9A+Zozn789h8WoCs+Mvqjps=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", "dev": true, "requires": { - "html-minifier": "3.5.9", + "html-minifier": "3.5.15", "loader-utils": "0.2.17", - "lodash": "4.17.5", + "lodash": "4.17.10", "pretty-error": "2.1.1", "tapable": "1.0.0", - "toposort": "1.0.6", + "toposort": "1.0.7", "util.promisify": "1.0.0" }, "dependencies": { @@ -5831,16 +5423,15 @@ } }, "html_codesniffer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/html_codesniffer/-/html_codesniffer-2.1.1.tgz", - "integrity": "sha512-ms7RxMbIPunkyyZIsU22HV1lTBRrmDov+FlCYTu9ONTSyP5Yj2V8cg27p1e2qL1zxhMl/yLx8P9/b7a9O8gcXQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/html_codesniffer/-/html_codesniffer-2.2.0.tgz", + "integrity": "sha512-xG6E3g2V/huu/WwRcrX3AFRmAUFkU7PWlgF/QFLtuRitI+NxvJcYTFthb24rB7/mhKE3khSIxB11A8IQTJ2N9w==", "dev": true, "requires": { "grunt": "1.0.2", "grunt-contrib-copy": "1.0.0", "grunt-contrib-jshint": "1.1.0", - "grunt-contrib-uglify": "2.3.0", - "grunt-contrib-watch": "1.0.0", + "grunt-contrib-watch": "1.1.0", "load-grunt-tasks": "3.5.2" } }, @@ -5857,12 +5448,6 @@ "readable-stream": "1.1.14" }, "dependencies": { - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -5896,142 +5481,44 @@ "dev": true }, "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { + "depd": "1.1.2", "inherits": "2.0.3", + "setprototypeof": "1.1.0", "statuses": "1.4.0" } }, "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.12.tgz", + "integrity": "sha1-uc+/Sizybw/DSxDKFImid3HjR08=", "dev": true }, "http-proxy": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", - "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "1.2.0", + "eventemitter3": "3.1.0", + "follow-redirects": "1.4.1", "requires-port": "1.0.0" } }, "http-proxy-middleware": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", - "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", "dev": true, "requires": { - "http-proxy": "1.16.2", - "is-glob": "3.1.0", - "lodash": "4.17.5", - "micromatch": "2.3.11" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - } - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } - } - } + "http-proxy": "1.17.0", + "is-glob": "4.0.0", + "lodash": "4.17.10", + "micromatch": "3.1.10" } }, "http-signature": { @@ -6042,7 +5529,7 @@ "requires": { "assert-plus": "1.0.0", "jsprim": "1.4.1", - "sshpk": "1.13.1" + "sshpk": "1.14.1" } }, "https-browserify": { @@ -6051,11 +5538,32 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "iced-error": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.12.tgz", + "integrity": "sha1-4KhhRigXzwzpdLE/ymEtOg1dEL4=" + }, + "iced-lock": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/iced-lock/-/iced-lock-1.1.0.tgz", + "integrity": "sha1-YRbvHKs6zW5rEIk7snumIv0/3nI=", + "requires": { + "iced-runtime": "1.0.3" + } + }, + "iced-runtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/iced-runtime/-/iced-runtime-1.0.3.tgz", + "integrity": "sha1-LU9PuZmreqVDCxk8d6f85BGDGc4=" + }, "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } }, "icss-replace-symbols": { "version": "1.1.0", @@ -6069,27 +5577,27 @@ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", "dev": true, "requires": { - "postcss": "6.0.19" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -6099,26 +5607,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -6127,9 +5629,9 @@ } }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", + "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", "dev": true }, "iferr": { @@ -6139,9 +5641,9 @@ "dev": true }, "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", "dev": true }, "image-size": { @@ -6169,14 +5671,6 @@ "requires": { "loader-utils": "1.1.0", "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "imurmurhash": { @@ -6234,8 +5728,8 @@ "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", "dev": true, "requires": { - "moment": "2.20.1", - "sanitize-html": "1.17.0" + "moment": "2.22.1", + "sanitize-html": "1.18.2" } }, "inquirer": { @@ -6244,13 +5738,13 @@ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.1", + "ansi-escapes": "3.1.0", + "chalk": "2.4.1", "cli-cursor": "2.1.0", "cli-width": "2.2.0", - "external-editor": "2.1.0", + "external-editor": "2.2.0", "figures": "2.0.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "mute-stream": "0.0.7", "run-async": "2.3.0", "rx-lite": "4.0.8", @@ -6267,23 +5761,23 @@ "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -6302,9 +5796,9 @@ } }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -6322,9 +5816,9 @@ } }, "invariant": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", - "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "requires": { "loose-envify": "1.3.1" } @@ -6354,19 +5848,22 @@ "dev": true }, "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "3.2.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 + "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.6" + } } } }, @@ -6407,19 +5904,22 @@ "dev": true }, "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "3.2.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 + "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.6" + } } } }, @@ -6430,20 +5930,20 @@ "dev": true }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" }, "dependencies": { "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true } } @@ -6454,21 +5954,6 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -6512,6 +5997,17 @@ "dev": true, "requires": { "kind-of": "3.2.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.6" + } + } } }, "is-odd": { @@ -6538,18 +6034,18 @@ "dev": true }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "1.0.0" + "is-path-inside": "1.0.1" } }, "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { "path-is-inside": "1.0.2" @@ -6570,18 +6066,6 @@ "isobject": "3.0.1" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -6694,7 +6178,7 @@ "requires": { "esprima": "1.0.4", "estraverse": "0.0.4", - "source-map": "0.5.7" + "source-map": "0.6.1" } }, "esprima": { @@ -6724,9 +6208,9 @@ "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" }, "js-base64": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", - "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.5.tgz", + "integrity": "sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ==", "dev": true }, "js-crc": { @@ -6739,6 +6223,53 @@ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==" }, + "js-to-mjs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/js-to-mjs/-/js-to-mjs-0.2.0.tgz", + "integrity": "sha512-5OlmInr6FuKAEAqNi0Ag8ErS8LWCp53w/vHSc6Ndm8aTckuOKI/uiil/ltP/xRrl+cSz8Q/oW7q6iglNQHCx+A==", + "dev": true, + "requires": { + "babylon": "6.18.0", + "chalk": "2.4.1" + }, + "dependencies": { + "ansi-styles": { + "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.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -6783,12 +6314,12 @@ "dev": true, "requires": { "babylon": "7.0.0-beta.19", - "bluebird": "3.5.0", + "bluebird": "3.5.1", "catharsis": "0.8.9", "escape-string-regexp": "1.0.5", "js2xmlparser": "3.0.0", "klaw": "2.0.0", - "marked": "0.3.12", + "marked": "0.3.19", "mkdirp": "0.5.1", "requizzle": "0.2.1", "strip-json-comments": "2.0.1", @@ -6820,44 +6351,51 @@ } }, "jsdoc-babel": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.3.0.tgz", - "integrity": "sha1-Lqrv2eyo2LeIRTlKHM6diJa+++E=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.4.0.tgz", + "integrity": "sha512-KF3WTPvoPYc8ZyXzC1m+vvwi+2VCKkqZX/NkqcE1tFephp8RnZAxG52QB/wvz/zoDS6XU28aM8NItMPMad50PA==", "dev": true, "requires": { - "lodash": "4.17.5" + "jsdoc-regex": "1.0.1", + "lodash": "4.17.10" } }, + "jsdoc-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz", + "integrity": "sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=", + "dev": true + }, "jsdom": { - "version": "11.6.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.6.2.tgz", - "integrity": "sha512-pAeZhpbSlUp5yQcS6cBQJwkbzmv4tWFaYxHbFVSxzXefqjvtRA851Z5N2P+TguVG9YeUDcgb8pdeVQRJh0XR3Q==", + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.10.0.tgz", + "integrity": "sha512-x5No5FpJgBg3j5aBwA8ka6eGuS5IxbC8FOkmyccKvObtFT0bDMict/LOxINZsZGZSfGdNomLZ/qRV9Bpq/GIBA==", "dev": true, "requires": { "abab": "1.0.4", - "acorn": "5.5.0", + "acorn": "5.5.3", "acorn-globals": "4.1.0", "array-equal": "1.0.0", - "browser-process-hrtime": "0.1.2", - "content-type-parser": "1.0.2", "cssom": "0.3.2", "cssstyle": "0.2.37", + "data-urls": "1.0.0", "domexception": "1.0.1", "escodegen": "1.9.1", "html-encoding-sniffer": "1.0.2", - "left-pad": "1.2.0", - "nwmatcher": "1.4.3", + "left-pad": "1.3.0", + "nwmatcher": "1.4.4", "parse5": "4.0.0", "pn": "1.1.0", - "request": "2.83.0", + "request": "2.86.0", "request-promise-native": "1.0.5", "sax": "1.2.4", "symbol-tree": "3.2.2", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "w3c-hr-time": "1.0.1", "webidl-conversions": "4.0.2", "whatwg-encoding": "1.0.3", - "whatwg-url": "6.4.0", + "whatwg-mimetype": "2.1.0", + "whatwg-url": "6.4.1", "ws": "4.1.0", "xml-name-validator": "3.0.0" } @@ -6889,12 +6427,6 @@ "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", "dev": true }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", - "dev": true - }, "strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", @@ -6915,15 +6447,6 @@ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -6957,12 +6480,6 @@ "graceful-fs": "4.1.11" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, "jsonpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.0.tgz", @@ -6994,9 +6511,29 @@ } }, "jsrsasign": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.6.tgz", - "integrity": "sha1-RYbwCCPjAuWZokSke+IMYardD88=" + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz", + "integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY=" + }, + "kbpgp": { + "version": "2.0.77", + "resolved": "https://registry.npmjs.org/kbpgp/-/kbpgp-2.0.77.tgz", + "integrity": "sha1-bp0vV5hb6VlsXqbJ5aODM/MasZk=", + "requires": { + "bn": "1.0.1", + "bzip-deflate": "1.0.0", + "deep-equal": "1.0.1", + "iced-error": "0.0.12", + "iced-lock": "1.1.0", + "iced-runtime": "1.0.3", + "keybase-ecurve": "1.0.0", + "keybase-nacl": "1.0.10", + "minimist": "1.2.0", + "pgp-utils": "0.0.34", + "purepack": "1.0.4", + "triplesec": "3.0.26", + "tweetnacl": "0.13.3" + } }, "kew": { "version": "0.7.0", @@ -7004,6 +6541,24 @@ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", "dev": true }, + "keybase-ecurve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/keybase-ecurve/-/keybase-ecurve-1.0.0.tgz", + "integrity": "sha1-xrxyrdpGA/0xhP7n6ZaU7Y/WmtI=", + "requires": { + "bn": "1.0.1" + } + }, + "keybase-nacl": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/keybase-nacl/-/keybase-nacl-1.0.10.tgz", + "integrity": "sha1-OGWDHpSBUWSI33y9mJRn6VDYeos=", + "requires": { + "iced-runtime": "1.0.3", + "tweetnacl": "0.13.3", + "uint64be": "1.0.1" + } + }, "killable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", @@ -7011,13 +6566,10 @@ "dev": true }, "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.6" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "klaw": { "version": "1.3.1", @@ -7028,12 +6580,6 @@ "graceful-fs": "4.1.11" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -7043,194 +6589,38 @@ "invert-kv": "1.0.0" } }, + "leb": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", + "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", + "dev": true + }, "left-pad": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.2.0.tgz", - "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", "dev": true }, "less": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.0.1.tgz", - "integrity": "sha512-qUR4uNv88/c0mpnGOULgMLRXXSD6X0tYo4cVrokzsvn68+nuj8rskInCSe2eLAVYWGD/oAlq8P7J/FeZ/euKiw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/less/-/less-3.0.4.tgz", + "integrity": "sha512-q3SyEnPKbk9zh4l36PGeW2fgynKu+FpbhiUNx/yaiBUQ3V0CbACCgb9FzYWcRgI2DJlP6eI4jc8XPrCTi55YcQ==", "dev": true, "requires": { "errno": "0.1.7", "graceful-fs": "4.1.11", "image-size": "0.5.5", - "mime": "1.4.1", + "mime": "1.6.0", "mkdirp": "0.5.1", "promise": "7.3.1", - "request": "2.81.0", - "source-map": "0.5.7" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true, - "optional": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1" - } - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "optional": true, - "requires": { - "hoek": "2.16.3" - } - } + "request": "2.86.0", + "source-map": "0.6.1" } }, "less-loader": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.0.6.tgz", - "integrity": "sha512-WPFY3NMJGJna8kIxtgSu6AVG7K6uRPdfE2J7vpQqFWMN/RkOosV09rOVUt3wghNClWH2Pg7YumD1dHiv1Thfug==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz", + "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==", "dev": true, "requires": { "clone": "2.1.1", @@ -7243,12 +6633,6 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true } } }, @@ -7295,6 +6679,14 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "strip-bom": "2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "loader-runner": { @@ -7325,9 +6717,9 @@ } }, "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "lodash.camelcase": { "version": "4.3.0", @@ -7347,6 +6739,18 @@ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", "dev": true }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7354,9 +6758,9 @@ "dev": true }, "lodash.mergewith": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", - "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "dev": true }, "lodash.sortby": { @@ -7383,27 +6787,27 @@ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { - "chalk": "2.3.1" + "chalk": "2.4.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==", + "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -7413,9 +6817,9 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -7438,15 +6842,19 @@ } }, "loglevelnext": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.3.tgz", - "integrity": "sha512-OCxd/b78TijTB4b6zVqLbMrxhebyvdZKwqpL0VHUZ0pYhavXaPD4l6Xrr4n5xqTYWiqtb0i7ikSoJY/myQ/Org==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "requires": { + "es6-symbol": "3.1.1", + "object.assign": "4.1.0" + } }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", "dev": true }, "loose-envify": { @@ -7474,9 +6882,9 @@ "dev": true }, "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "dev": true, "requires": { "pseudomap": "1.0.2", @@ -7490,20 +6898,12 @@ "dev": true }, "make-dir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", - "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { "pify": "3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } } }, "map-cache": { @@ -7528,9 +6928,9 @@ } }, "marked": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz", - "integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", "dev": true }, "math-expression-evaluator": { @@ -7539,30 +6939,6 @@ "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", "dev": true }, - "maxmin": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz", - "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "figures": "1.7.0", - "gzip-size": "1.0.0", - "pretty-bytes": "1.0.4" - }, - "dependencies": { - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - } - } - }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", @@ -7571,18 +6947,6 @@ "requires": { "hash-base": "3.0.4", "inherits": "2.0.3" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - } } }, "media-typer": { @@ -7597,7 +6961,7 @@ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "mimic-fn": "1.1.0" + "mimic-fn": "1.2.0" } }, "memory-fs": { @@ -7607,7 +6971,7 @@ "dev": true, "requires": { "errno": "0.1.7", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "meow": { @@ -7626,14 +6990,6 @@ "read-pkg-up": "1.0.1", "redent": "1.0.0", "trim-newlines": "1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "merge-descriptors": { @@ -7649,14 +7005,14 @@ "dev": true }, "micromatch": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.9.tgz", - "integrity": "sha512-SlIz6sv5UPaAVVFRKodKjCg48EbNoIhgetzfK/Cy0v5U52Z6zB136M8tp0UC9jM53LYbmIRihJszvvqpKkfm9g==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", - "braces": "2.3.1", + "braces": "2.3.2", "define-property": "2.0.2", "extend-shallow": "3.0.2", "extglob": "2.0.4", @@ -7665,16 +7021,8 @@ "nanomatch": "1.2.9", "object.pick": "1.3.0", "regex-not": "1.0.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "to-regex": "3.0.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 - } } }, "miller-rabin": { @@ -7688,42 +7036,43 @@ } }, "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "dev": true }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" } }, "mimer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.3.tgz", - "integrity": "sha512-cICHJPMZUdZMqWaOQ+Eh0hHo1R6IUCiBee7WvIGGUJsZyjdMUInxQVmyu8hKj5uCy+Bi+Wlp/EsdUR61yOdWOw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.3.2.tgz", + "integrity": "sha512-N6NcgDQAevhP/02DQ/epK6daLy4NKrIHyTlJcO6qBiYn98q+Y4a/knNsAATCe1xLS2F0nEmJp+QYli2s8vKwyQ==", "dev": true }, "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "minimalistic-crypto-utils": { @@ -7738,14 +7087,13 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mississippi": { "version": "2.0.0", @@ -7753,28 +7101,16 @@ "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", "dev": true, "requires": { - "concat-stream": "1.6.0", - "duplexify": "3.5.1", - "end-of-stream": "1.4.0", - "flush-write-stream": "1.0.2", + "concat-stream": "1.6.2", + "duplexify": "3.6.0", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.3", "from2": "2.3.0", "parallel-transform": "1.1.0", "pump": "2.0.1", - "pumpify": "1.3.5", + "pumpify": "1.5.1", "stream-each": "1.2.2", "through2": "2.0.3" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "1.4.0", - "once": "1.4.0" - } - } } }, "mixin-deep": { @@ -7805,19 +7141,35 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } } }, "moment": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", - "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz", + "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ==" }, "moment-timezone": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", - "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.17.tgz", + "integrity": "sha512-Y/JpVEWIOA9Gho4vO15MTnW1FCmHi3ypprrkUaxsZ1TKg3uqC8q/qMBjTddkHoiwwZN3qvZSr4zJP7x9V3LpXA==", "requires": { - "moment": "2.20.1" + "moment": "2.22.1" + } + }, + "more-entropy": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/more-entropy/-/more-entropy-0.0.7.tgz", + "integrity": "sha1-Z7/G96hvJvvDeqyD/UbYjGHRCbU=", + "requires": { + "iced-runtime": "1.0.3" } }, "move-concurrently": { @@ -7832,17 +7184,6 @@ "mkdirp": "0.5.1", "rimraf": "2.6.2", "run-queue": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.0.6" - } - } } }, "ms": { @@ -7885,9 +7226,9 @@ "dev": true }, "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", "dev": true, "optional": true }, @@ -7907,16 +7248,8 @@ "kind-of": "6.0.2", "object.pick": "1.3.0", "regex-not": "1.0.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "to-regex": "3.0.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 - } } }, "natural-compare": { @@ -7925,15 +7258,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "ncname": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", - "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", - "dev": true, - "requires": { - "xml-char-classes": "1.0.0" - } - }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -7941,9 +7265,15 @@ "dev": true }, "neo-async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", - "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, "no-case": { @@ -7956,9 +7286,9 @@ } }, "node-forge": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.2.tgz", - "integrity": "sha512-XTBoBY8NoeGAqQywTM8BjBz/Ro37eTmVF657yf6JumfOhxW9eET43Hve5+6L4+lo3hTDx7kTbC1WfasTHinDpg==" + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" }, "node-libs-browser": { "version": "2.1.0", @@ -7980,30 +7310,21 @@ "process": "0.11.10", "punycode": "1.4.1", "querystring-es3": "0.2.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-browserify": "2.0.1", - "stream-http": "2.8.0", - "string_decoder": "1.0.3", - "timers-browserify": "2.0.6", + "stream-http": "2.8.2", + "string_decoder": "1.1.1", + "timers-browserify": "2.0.10", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "1.0.6" - } - }, - "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true } } @@ -8044,10 +7365,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.5.0", + "hosted-git-info": "2.6.0", "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -8108,9 +7429,9 @@ "dev": true }, "nwmatcher": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", - "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" }, "oauth-sign": { "version": "0.8.2", @@ -8144,41 +7465,13 @@ "is-descriptor": "0.1.6" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "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": { - "kind-of": "3.2.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-buffer": "1.1.6" } } } @@ -8217,17 +7510,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.10.0" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "es-abstract": "1.11.0" } }, "object.pick": { @@ -8240,9 +7523,9 @@ } }, "obuf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", - "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, "on-finished": { @@ -8275,13 +7558,13 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "1.1.0" + "mimic-fn": "1.2.0" } }, "opn": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", - "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { "is-wsl": "1.1.0" @@ -8301,24 +7584,12 @@ } }, "original": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", - "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz", + "integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==", "dev": true, "requires": { - "url-parse": "1.0.5" - }, - "dependencies": { - "url-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", - "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", - "dev": true, - "requires": { - "querystringify": "0.0.4", - "requires-port": "1.0.0" - } - } + "url-parse": "1.4.0" } }, "os-browserify": { @@ -8365,10 +7636,13 @@ "dev": true }, "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } }, "p-locate": { "version": "2.0.0", @@ -8376,7 +7650,7 @@ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "1.1.0" + "p-limit": "1.2.0" } }, "p-map": { @@ -8385,10 +7659,29 @@ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", "dev": true }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pad-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pad-stream/-/pad-stream-1.2.0.tgz", + "integrity": "sha1-Yx3Mn3mBC3BZZeid7eps/w/B38k=", + "dev": true, + "requires": { + "meow": "3.7.0", + "pumpify": "1.5.1", + "repeating": "2.0.1", + "split2": "1.1.1", + "through2": "2.0.3" + } + }, "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", "dev": true }, "parallel-transform": { @@ -8399,7 +7692,7 @@ "requires": { "cyclist": "0.2.2", "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "param-case": { @@ -8412,45 +7705,16 @@ } }, "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { "asn1.js": "4.10.1", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } + "pbkdf2": "3.0.16" } }, "parse-json": { @@ -8531,19 +7795,27 @@ "graceful-fs": "4.1.11", "pify": "2.3.0", "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "pbkdf2": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", - "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "pend": { @@ -8558,6 +7830,15 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "pgp-utils": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/pgp-utils/-/pgp-utils-0.0.34.tgz", + "integrity": "sha1-2E9J98GTteC5QV9cxcKmle15DCM=", + "requires": { + "iced-error": "0.0.12", + "iced-runtime": "1.0.3" + } + }, "phantomjs-prebuilt": { "version": "2.1.16", "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", @@ -8570,15 +7851,15 @@ "hasha": "2.2.0", "kew": "0.7.0", "progress": "1.1.8", - "request": "2.83.0", + "request": "2.86.0", "request-progress": "2.0.1", - "which": "1.2.14" + "which": "1.3.0" } }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pinkie": { @@ -8679,11 +7960,17 @@ "dev": true, "requires": { "chalk": "1.1.3", - "js-base64": "2.4.3", + "js-base64": "2.4.5", "source-map": "0.5.7", "supports-color": "3.2.3" }, "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -8728,60 +8015,60 @@ } }, "postcss-css-variables": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.8.0.tgz", - "integrity": "sha512-ilcsJMhq09HOsQ2RzXm+fPQNEwMN3kLab6IYpcL5EH8E1EKvBrWQRsiWONWqjWPAKHFMWkEvJTHJJzP9m1E0yQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.8.1.tgz", + "integrity": "sha1-pS5e8aLrYzqKT1/ENNbYXUD+cxA=", "dev": true, "requires": { "escape-string-regexp": "1.0.5", "extend": "3.0.1", - "postcss": "6.0.12" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "5.4.0" } }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "postcss": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz", - "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.4.1", + "source-map": "0.6.1", + "supports-color": "5.4.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==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } @@ -8848,30 +8135,30 @@ "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", "dev": true, "requires": { - "postcss": "6.0.19", + "postcss": "6.0.22", "postcss-value-parser": "3.3.0", "read-cache": "1.0.0", "resolve": "1.1.7" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -8881,26 +8168,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -8941,52 +8222,35 @@ } }, "postcss-loader": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.1.tgz", - "integrity": "sha512-f0J/DWE/hyO9/LH0WHpXkny/ZZ238sSaG3p1SRBtVZnFWUtD7GXIEgHoBg8cnAeRbmEvUxHQptY46zWfwNYj/w==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.5.tgz", + "integrity": "sha512-pV7kB5neJ0/1tZ8L1uGOBNTVBCSCXQoIsZMsrwvO8V2rKGa2tBl/f80GGVxow2jJnRJ2w1ocx693EKhZAb9Isg==", "dev": true, "requires": { "loader-utils": "1.1.0", - "postcss": "6.0.19", + "postcss": "6.0.22", "postcss-load-config": "1.2.0", "schema-utils": "0.4.5" }, "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -8996,36 +8260,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -9063,7 +8311,7 @@ "caniuse-api": "1.6.1", "postcss": "5.2.18", "postcss-selector-parser": "2.2.3", - "vendors": "1.0.1" + "vendors": "1.0.2" }, "dependencies": { "browserslist": { @@ -9072,8 +8320,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000810", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000843", + "electron-to-chromium": "1.3.47" } } } @@ -9135,27 +8383,27 @@ "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=", "dev": true, "requires": { - "postcss": "6.0.19" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -9165,26 +8413,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -9199,27 +8441,27 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.19" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -9229,26 +8471,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -9263,27 +8499,27 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.19" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -9293,26 +8529,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -9327,27 +8557,27 @@ "dev": true, "requires": { "icss-replace-symbols": "1.1.0", - "postcss": "6.0.19" + "postcss": "6.0.22" }, "dependencies": { "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -9357,26 +8587,20 @@ "dev": true }, "postcss": { - "version": "6.0.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", - "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -9507,22 +8731,6 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-bytes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", - "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", @@ -9546,16 +8754,15 @@ "dev": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" }, "promise": { "version": "7.3.1", @@ -9596,45 +8803,50 @@ "dev": true }, "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", "randombytes": "2.0.6" } }, "pump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", - "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "once": "1.4.0" } }, "pumpify": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz", - "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { - "duplexify": "3.5.1", + "duplexify": "3.6.0", "inherits": "2.0.3", - "pump": "1.0.2" + "pump": "2.0.1" } }, "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", "dev": true }, + "purepack": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.4.tgz", + "integrity": "sha1-CGKC/ZOShfWGZLqam7oxzbFlzNI=" + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -9642,9 +8854,9 @@ "dev": true }, "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "query-string": { @@ -9670,39 +8882,18 @@ "dev": true }, "querystringify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", - "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", + "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", "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": { - "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.6" - } - } - } - }, "randombytes": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "randomfill": { @@ -9712,7 +8903,7 @@ "dev": true, "requires": { "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "range-parser": { @@ -9722,48 +8913,33 @@ "dev": true }, "raw-body": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", - "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.13", - "unpipe": "1.0.0" + "bytes": "1.0.0", + "string_decoder": "0.10.31" }, "dependencies": { - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "rc": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz", - "integrity": "sha1-J1zWh/bjs2zHVrqibf7oCnkDAf0=", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", + "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", "dev": true, "requires": { - "deep-extend": "0.4.2", + "deep-extend": "0.5.1", "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "read-cache": { @@ -9773,6 +8949,14 @@ "dev": true, "requires": { "pify": "2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "read-pkg": { @@ -9818,17 +9002,17 @@ } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, @@ -9840,7 +9024,7 @@ "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "set-immediate-shim": "1.0.1" } }, @@ -9891,9 +9075,9 @@ } }, "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, "regenerator-runtime": { @@ -9912,15 +9096,6 @@ "private": "0.1.8" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -9931,13 +9106,19 @@ "safe-regex": "1.1.0" } }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.3.3", + "regenerate": "1.4.0", "regjsgen": "0.2.0", "regjsparser": "0.1.5" } @@ -10074,33 +9255,32 @@ } }, "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "version": "2.86.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.86.0.tgz", + "integrity": "sha512-BQZih67o9r+Ys94tcIW4S7Uu8pthjrQVxhsZ/weOwHbDfACxvIyvnAbzFQxjy1jMtvFSzv5zf4my6cZsJBbVzw==", "dev": true, "requires": { "aws-sign2": "0.7.0", - "aws4": "1.6.0", + "aws4": "1.7.0", "caseless": "0.12.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.3.1", + "form-data": "2.3.2", "har-validator": "5.0.3", "hawk": "6.0.2", "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "oauth-sign": "0.8.2", "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "uuid": "3.2.1" } }, "request-progress": { @@ -10118,7 +9298,7 @@ "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", "dev": true, "requires": { - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "request-promise-native": { @@ -10129,7 +9309,7 @@ "requires": { "request-promise-core": "1.1.1", "stealthy-require": "1.1.1", - "tough-cookie": "2.3.3" + "tough-cookie": "2.3.4" } }, "require-directory": { @@ -10251,28 +9431,22 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "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=", + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "align-text": "0.1.4" + "glob": "7.1.2" } }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - }, "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "2.0.2", + "hash-base": "3.0.4", "inherits": "2.0.3" } }, @@ -10310,9 +9484,15 @@ } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", "dev": true }, "safe-regex": { @@ -10324,55 +9504,60 @@ "ret": "0.1.15" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "sanitize-html": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.17.0.tgz", - "integrity": "sha512-5r265ukJgS+MXVMK0OxXLn7iBqRTIxYK0m6Bc+/gFhCY20Vr/KFp/ZTKu9hyB3tKkiGPiQ08aGDPUbjbBhRpXw==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.18.2.tgz", + "integrity": "sha512-52ThA+Z7h6BnvpSVbURwChl10XZrps5q7ytjTwWcIe9bmJwnVP6cpEVK2NvDOUhGupoqAvNbUz3cpnJDp4+/pg==", "dev": true, "requires": { - "chalk": "2.3.0", + "chalk": "2.4.1", "htmlparser2": "3.9.2", "lodash.clonedeep": "4.5.0", "lodash.escaperegexp": "4.1.2", - "lodash.mergewith": "4.6.0", - "postcss": "6.0.16", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.mergewith": "4.6.1", + "postcss": "6.0.22", "srcset": "1.0.0", "xtend": "4.0.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==", + "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "5.4.0" } }, - "domhandler": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", - "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "htmlparser2": { @@ -10382,48 +9567,31 @@ "dev": true, "requires": { "domelementtype": "1.3.0", - "domhandler": "2.4.1", + "domhandler": "2.3.0", "domutils": "1.5.1", "entities": "1.1.1", "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "postcss": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", - "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "version": "6.0.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz", + "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==", "dev": true, "requires": { - "chalk": "2.3.0", + "chalk": "2.4.1", "source-map": "0.6.1", - "supports-color": "5.1.0" - }, - "dependencies": { - "supports-color": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", - "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } + "supports-color": "5.4.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } @@ -10435,12 +9603,39 @@ "dev": true }, "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", + "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", "dev": true, "requires": { - "ajv": "5.2.3" + "ajv": "6.5.0", + "ajv-keywords": "3.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", + "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1", + "uri-js": "4.2.1" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + } } }, "scryptsy": { @@ -10455,32 +9650,24 @@ "dev": true }, "selfsigned": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.2.tgz", - "integrity": "sha1-tESVgNmZKbZbEKSDiTAaZZIIh1g=", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", + "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==", "dev": true, "requires": { - "node-forge": "0.7.1" - }, - "dependencies": { - "node-forge": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz", - "integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA=", - "dev": true - } + "node-forge": "0.7.5" } }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "send": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", - "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "dev": true, "requires": { "debug": "2.6.9", @@ -10490,52 +9677,26 @@ "escape-html": "1.0.3", "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", - "statuses": "1.3.1" + "statuses": "1.4.0" }, "dependencies": { - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - } - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true } } }, "serialize-javascript": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz", - "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", + "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", "dev": true }, "serve-index": { @@ -10548,47 +9709,21 @@ "batch": "0.6.1", "debug": "2.6.9", "escape-html": "1.0.3", - "http-errors": "1.6.2", - "mime-types": "2.1.17", + "http-errors": "1.6.3", + "mime-types": "2.1.18", "parseurl": "1.3.2" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - } } }, "serve-static": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", - "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { "encodeurl": "1.0.2", "escape-html": "1.0.3", "parseurl": "1.3.2", - "send": "0.16.1" + "send": "0.16.2" } }, "set-blocking": { @@ -10597,15 +9732,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", - "dev": true, - "requires": { - "to-object-path": "0.3.0" - } - }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", @@ -10648,13 +9774,13 @@ "dev": true }, "sha.js": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", - "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "shebang-command": { @@ -10673,9 +9799,9 @@ "dev": true }, "shelljs": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", - "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", "dev": true }, "signal-exit": { @@ -10715,9 +9841,9 @@ } }, "snapdragon": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", - "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { "base": "0.11.2", @@ -10726,8 +9852,8 @@ "extend-shallow": "2.0.1", "map-cache": "0.2.2", "source-map": "0.5.7", - "source-map-resolve": "0.5.1", - "use": "2.0.2" + "source-map-resolve": "0.5.2", + "use": "3.1.0" }, "dependencies": { "define-property": { @@ -10748,61 +9874,10 @@ "is-extendable": "0.1.1" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -10826,6 +9901,35 @@ "requires": { "is-descriptor": "1.0.2" } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } } } }, @@ -10836,15 +9940,26 @@ "dev": true, "requires": { "kind-of": "3.2.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.6" + } + } } }, "sntp": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", - "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } }, "sockjs": { @@ -10854,7 +9969,7 @@ "dev": true, "requires": { "faye-websocket": "0.10.0", - "uuid": "3.1.0" + "uuid": "3.2.1" } }, "sockjs-client": { @@ -10868,7 +9983,7 @@ "faye-websocket": "0.11.1", "inherits": "2.0.3", "json3": "3.3.2", - "url-parse": "1.2.0" + "url-parse": "1.4.0" }, "dependencies": { "faye-websocket": { @@ -10903,17 +10018,17 @@ "dev": true }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-resolve": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.0.3", + "atob": "2.1.1", "decode-uri-component": "0.2.0", "resolve-url": "0.2.1", "source-map-url": "0.4.0", @@ -10927,6 +10042,14 @@ "dev": true, "requires": { "source-map": "0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "source-map-url": { @@ -10936,24 +10059,35 @@ "dev": true }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "spdy": { @@ -10965,24 +10099,24 @@ "debug": "2.6.9", "handle-thing": "1.2.5", "http-deceiver": "1.2.7", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "select-hose": "2.0.0", - "spdy-transport": "2.0.20" + "spdy-transport": "2.1.0" } }, "spdy-transport": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz", - "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", + "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", "dev": true, "requires": { "debug": "2.6.9", "detect-node": "2.0.3", "hpack.js": "2.1.6", - "obuf": "1.1.1", - "readable-stream": "2.3.3", - "safe-buffer": "5.1.1", - "wbuf": "1.7.2" + "obuf": "1.1.2", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "wbuf": "1.7.3" } }, "split-string": { @@ -10999,6 +10133,15 @@ "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.3.5.tgz", "integrity": "sha1-YuLOZtLPkcx3SqXwdJ/yUTgDn1A=" }, + "split2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.1.1.tgz", + "integrity": "sha1-Fi2bGIZfAqsvKtlYVSLbm1TEgfk=", + "dev": true, + "requires": { + "through2": "2.0.3" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -11021,9 +10164,9 @@ "integrity": "sha1-mItJTQ3JwxkAX9rJZj1jOO/tHyI=" }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { "asn1": "0.2.3", @@ -11042,16 +10185,23 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true, "optional": true + }, + "tweetnacl": { + "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 } } }, "ssri": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.2.4.tgz", - "integrity": "sha512-UnEAgMZa15973iH7cUi0AHjJn1ACDIkaMyZILoqwN6yzt+4P81I8tBc5Hl+qwi5auMplZtPQsHrPBR5vJLcQtQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", + "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "static-eval": { @@ -11080,63 +10230,6 @@ "requires": { "is-descriptor": "0.1.6" } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true } } }, @@ -11159,7 +10252,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "stream-each": { @@ -11168,19 +10261,19 @@ "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", "dev": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "stream-shift": "1.0.0" } }, "stream-http": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz", - "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", + "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", "dev": true, "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "to-arraybuffer": "1.0.1", "xtend": "4.0.1" } @@ -11197,6 +10290,12 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -11225,20 +10324,14 @@ } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -11278,36 +10371,13 @@ "dev": true }, "style-loader": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.2.tgz", - "integrity": "sha512-FrLMGaOLVhS5pvoez3eJyc0ktchT1inEZziBSjBq1hHQBK3GFkF57Qd825DcrUhjaAWQk70MKrIl5bfjadR/Dg==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", "dev": true, "requires": { "loader-utils": "1.1.0", "schema-utils": "0.4.5" - }, - "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - } } }, "supports-color": { @@ -11345,54 +10415,37 @@ "dev": true }, "table": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", - "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0", - "chalk": "2.3.1", - "lodash": "4.17.5", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "chalk": "2.4.1", + "lodash": "4.17.10", "slice-ansi": "1.0.0", "string-width": "2.1.1" }, "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -11402,9 +10455,9 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -11453,7 +10506,7 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "xtend": "4.0.1" } }, @@ -11464,48 +10517,36 @@ "dev": true }, "timers-browserify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz", - "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "dev": true, "requires": { "setimmediate": "1.0.5" } }, "tiny-lr": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", - "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { - "body-parser": "1.14.2", - "debug": "2.2.0", + "body": "5.1.0", + "debug": "3.1.0", "faye-websocket": "0.10.0", "livereload-js": "2.3.0", - "parseurl": "1.3.2", - "qs": "5.1.0" + "object-assign": "4.1.1", + "qs": "6.5.2" }, "dependencies": { "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", - "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", - "dev": true } } }, @@ -11536,6 +10577,17 @@ "dev": true, "requires": { "kind-of": "3.2.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.6" + } + } } }, "to-regex": { @@ -11561,18 +10613,26 @@ } }, "toposort": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", - "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "dev": true }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "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" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "tr46": { @@ -11582,14 +10642,6 @@ "dev": true, "requires": { "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", - "dev": true - } } }, "trim-newlines": { @@ -11604,6 +10656,18 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "triplesec": { + "version": "3.0.26", + "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-3.0.26.tgz", + "integrity": "sha1-3/K7R1ikIzcuc5o5fYmR8Fl9CsE=", + "requires": { + "iced-error": "0.0.12", + "iced-lock": "1.1.0", + "iced-runtime": "1.0.3", + "more-entropy": "0.0.7", + "progress": "1.1.8" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -11616,15 +10680,13 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "tweetnacl": { - "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 + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz", + "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y=" }, "type-check": { "version": "0.3.2", @@ -11642,23 +10704,6 @@ "requires": { "media-typer": "0.3.0", "mime-types": "2.1.18" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - } } }, "typedarray": { @@ -11668,77 +10713,42 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" + "version": "0.7.18", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", + "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA==" }, "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "version": "3.3.25", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.25.tgz", + "integrity": "sha512-hobogryjDV36VrLK3Y69ou4REyrTApzUblVFmdQOYRe8cYaSmFJXMb4dR9McdvYDSbeNdzUgYr2YVukJaErJcA==", "dev": true, "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "commander": "2.15.1", + "source-map": "0.6.1" } }, - "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 - }, "uglifyjs-webpack-plugin": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz", - "integrity": "sha512-CG/NvzXfemUAm5Y4Guh5eEaJYHtkG7kKNpXEJHp9QpxsFVB5/qKvYWoMaq4sa99ccZ0hM3MK8vQV9XPZB4357A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz", + "integrity": "sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw==", "dev": true, "requires": { "cacache": "10.0.4", "find-cache-dir": "1.0.0", "schema-utils": "0.4.5", - "serialize-javascript": "1.4.0", + "serialize-javascript": "1.5.0", "source-map": "0.6.1", "uglify-es": "3.3.9", "webpack-sources": "1.1.0", - "worker-farm": "1.5.4" + "worker-farm": "1.6.0" }, "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, "commander": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", "dev": true }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -11748,19 +10758,14 @@ "commander": "2.13.0", "source-map": "0.6.1" } - }, - "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", - "dev": true, - "requires": { - "source-list-map": "2.0.0", - "source-map": "0.6.1" - } } } }, + "uint64be": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz", + "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU=" + }, "underscore": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", @@ -11919,9 +10924,9 @@ } }, "upath": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", - "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, "upper-case": { @@ -11930,11 +10935,14 @@ "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", "dev": true }, - "uri-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", - "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", - "dev": true + "uri-js": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", + "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", + "dev": true, + "requires": { + "punycode": "2.1.0" + } }, "urix": { "version": "0.1.0", @@ -11967,120 +10975,41 @@ "dev": true }, "url-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", - "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.0.1.tgz", + "integrity": "sha512-rAonpHy7231fmweBKUFe0bYnlGDty77E+fm53NZdij7j/YOpyGzc7ttqG1nAXl3aRs0k41o0PC3TvGXQiw2Zvw==", "dev": true, "requires": { "loader-utils": "1.1.0", - "mime": "1.4.1", - "schema-utils": "0.3.0" + "mime": "2.3.1", + "schema-utils": "0.4.5" + }, + "dependencies": { + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + } } }, "url-parse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", - "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.0.tgz", + "integrity": "sha512-ERuGxDiQ6Xw/agN4tuoCRbmwRuZP0cJ1lJxJubXr5Q/5cDa78+Dc4wfvtxzhzhkm5VvmW6Mf8EVj9SPGN4l8Lg==", "dev": true, "requires": { - "querystringify": "1.0.0", + "querystringify": "2.0.0", "requires-port": "1.0.0" - }, - "dependencies": { - "querystringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", - "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", - "dev": true - } } }, "use": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", - "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "dev": true, "requires": { - "define-property": "0.2.5", - "isobject": "3.0.1", - "lazy-cache": "2.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.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.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", - "dev": true, - "requires": { - "set-getter": "0.1.0" - } - } + "kind-of": "6.0.2" } }, "utf8": { @@ -12134,25 +11063,25 @@ "dev": true }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", "dev": true }, "valid-data-url": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.4.tgz", - "integrity": "sha512-p3bCVl3Vrz42TV37a1OjagyLLd6qQAXBDWarIazuo7NQzCt8Kw8ZZwSAbUVPGlz5ubgbgJmgT0KRjLeCFNrfoQ==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.6.tgz", + "integrity": "sha512-FXg2qXMzfAhZc0y2HzELNfUeiOjPr+52hU1DNBWiJJ2luXD+dD1R9NA48Ug5aj0ibbxroeGDc/RJv6ThiGgkDw==", "dev": true }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "validator": { @@ -12168,9 +11097,9 @@ "dev": true }, "vendors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", - "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", "dev": true }, "verror": { @@ -12208,23 +11137,23 @@ } }, "watchpack": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", - "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "dev": true, "requires": { - "chokidar": "2.0.2", + "chokidar": "2.0.3", "graceful-fs": "4.1.11", - "neo-async": "2.5.0" + "neo-async": "2.5.1" } }, "wbuf": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", - "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "requires": { - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "web-resource-inliner": { @@ -12233,24 +11162,21 @@ "integrity": "sha512-fOWnBQHVX8zHvEbECDTxtYL0FXIIZZ5H3LWoez8mGopYJK7inEru1kVMDzM1lVdeJBNEqUnNP5FBGxvzuMcwwQ==", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "chalk": "1.1.3", - "datauri": "1.0.5", + "datauri": "1.1.0", "htmlparser2": "3.9.2", "lodash.unescape": "4.0.1", - "request": "2.83.0", - "valid-data-url": "0.1.4", + "request": "2.86.0", + "valid-data-url": "0.1.6", "xtend": "4.0.1" }, "dependencies": { - "domhandler": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", - "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true }, "htmlparser2": { "version": "3.9.2", @@ -12259,15 +11185,28 @@ "dev": true, "requires": { "domelementtype": "1.3.0", - "domhandler": "2.4.1", + "domhandler": "2.3.0", "domutils": "1.5.1", "entities": "1.1.1", "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } } } }, + "webassemblyjs": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", + "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/validation": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "3.2.0" + } + }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -12275,150 +11214,126 @@ "dev": true }, "webpack": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.0.1.tgz", - "integrity": "sha512-jHQNMmKPElreOYLCxR7SHfPnbhcqRT9O7lYPOMDR6Gt5XueJ7tH7JReXm4uMFstBKf7rj2Y7AD3LiMKR2zexYA==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.8.3.tgz", + "integrity": "sha512-/hfAjBISycdK597lxONjKEFX7dSIU1PsYwC3XlXUXoykWBlv9QV5HnO+ql3HvrrgfBJ7WXdnjO9iGPR2aAc5sw==", "dev": true, "requires": { - "acorn": "5.5.0", + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wasm-edit": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "acorn": "5.5.3", "acorn-dynamic-import": "3.0.0", - "ajv": "6.2.0", - "ajv-keywords": "3.1.0", - "chrome-trace-event": "0.1.2", + "ajv": "6.5.0", + "ajv-keywords": "3.2.0", + "chrome-trace-event": "0.1.3", "enhanced-resolve": "4.0.0", "eslint-scope": "3.7.1", "loader-runner": "2.3.0", "loader-utils": "1.1.0", "memory-fs": "0.4.1", - "micromatch": "3.1.9", + "micromatch": "3.1.10", "mkdirp": "0.5.1", - "neo-async": "2.5.0", + "neo-async": "2.5.1", "node-libs-browser": "2.1.0", "schema-utils": "0.4.5", "tapable": "1.0.0", - "uglifyjs-webpack-plugin": "1.2.2", - "watchpack": "1.5.0", - "webpack-sources": "1.0.1" + "uglifyjs-webpack-plugin": "1.2.5", + "watchpack": "1.6.0", + "webpack-sources": "1.1.0" }, "dependencies": { "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", + "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", "dev": true, "requires": { - "fast-deep-equal": "1.0.0", + "fast-deep-equal": "2.0.1", "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "json-schema-traverse": "0.3.1", + "uri-js": "4.2.1" } }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true } } }, "webpack-dev-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", - "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz", + "integrity": "sha512-I6Mmy/QjWU/kXwCSFGaiOoL5YEQIVmbb0o45xMoCyQAg/mClqZVTcsX327sPfekDyJWpCxb+04whNyLOIxpJdQ==", "dev": true, "requires": { "loud-rejection": "1.6.0", "memory-fs": "0.4.1", - "mime": "2.2.0", + "mime": "2.3.1", "path-is-absolute": "1.0.1", "range-parser": "1.2.0", - "url-join": "2.0.5", - "webpack-log": "1.1.2" + "url-join": "4.0.0", + "webpack-log": "1.2.0" }, "dependencies": { "mime": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.2.0.tgz", - "integrity": "sha512-0Qz9uF1ATtl8RKJG4VRfOymh7PyEor6NbrI/61lRfuRe4vx9SNATrvAeTj2EWVRKjEQGskrzWkJBBY5NbaVHIA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", "dev": true }, "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", "dev": true } } }, "webpack-dev-server": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.0.tgz", - "integrity": "sha512-ap7Fth7oh4sthC0nJkvRm2W3SaWryBeR19DWIcAwJlcooN0tB2fEKuZqckYR3uaJ6wXPCK1xMWAQWXhV5xVe8g==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.4.tgz", + "integrity": "sha512-itcIUDFkHuj1/QQxzUFOEXXmxOj5bku2ScLEsOFPapnq2JRTm58gPdtnBphBJOKL2+M3p6+xygL64bI+3eyzzw==", "dev": true, "requires": { "ansi-html": "0.0.7", "array-includes": "3.0.3", "bonjour": "3.5.0", - "chokidar": "2.0.2", + "chokidar": "2.0.3", "compression": "1.7.2", "connect-history-api-fallback": "1.5.0", "debug": "3.1.0", "del": "3.0.0", - "express": "4.16.2", + "express": "4.16.3", "html-entities": "1.2.1", - "http-proxy-middleware": "0.17.4", + "http-proxy-middleware": "0.18.0", "import-local": "1.0.0", "internal-ip": "1.2.0", "ip": "1.1.5", "killable": "1.0.0", "loglevel": "1.6.1", - "opn": "5.2.0", + "opn": "5.3.0", "portfinder": "1.0.13", - "selfsigned": "1.10.2", + "selfsigned": "1.10.3", "serve-index": "1.9.1", "sockjs": "0.3.19", "sockjs-client": "1.1.4", "spdy": "3.4.7", "strip-ansi": "3.0.1", - "supports-color": "5.2.0", - "webpack-dev-middleware": "2.0.6", - "webpack-log": "1.1.2", - "yargs": "9.0.1" + "supports-color": "5.4.0", + "webpack-dev-middleware": "3.1.3", + "webpack-log": "1.2.0", + "yargs": "11.0.0" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -12436,10 +11351,10 @@ "requires": { "globby": "6.1.0", "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", "p-map": "1.2.0", "pify": "3.0.0", - "rimraf": "2.2.8" + "rimraf": "2.6.2" } }, "globby": { @@ -12449,7 +11364,7 @@ "dev": true, "requires": { "array-union": "1.0.2", - "glob": "7.0.6", + "glob": "7.1.2", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" @@ -12469,153 +11384,47 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.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": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" - } } } }, "webpack-log": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.1.2.tgz", - "integrity": "sha512-B53SD4N4BHpZdUwZcj4st2QT7gVfqZtqHDruC1N+K2sciq0Rt/3F1Dx6RlylVkcrToMLTaiaeT48k9Lq4iDVDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", "dev": true, "requires": { - "chalk": "2.3.1", + "chalk": "2.4.1", "log-symbols": "2.2.0", - "loglevelnext": "1.0.3", - "uuid": "3.1.0" + "loglevelnext": "1.0.5", + "uuid": "3.2.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==", + "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" + "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" + "supports-color": "5.4.0" } }, "has-flag": { @@ -12625,9 +11434,9 @@ "dev": true }, "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -12636,28 +11445,19 @@ } }, "webpack-node-externals": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.6.0.tgz", - "integrity": "sha1-Iyxi7GCSsQBjWj0p2DwXRxKN+b0=", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz", + "integrity": "sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg==", "dev": true }, "webpack-sources": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", - "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "dev": true, "requires": { "source-list-map": "2.0.0", - "source-map": "0.5.7" - } - }, - "webpack-synchronizable-shell-plugin": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/webpack-synchronizable-shell-plugin/-/webpack-synchronizable-shell-plugin-0.0.7.tgz", - "integrity": "sha512-b1ZPHwkHR5+MDRLp9CbLxDaaTTcf4/tmxU+Tc6Z3lpv6krnIPv0doXfgBHkDthHUkwsURyO9fgRnJ/VxyFBEwQ==", - "dev": true, - "requires": { - "babel-polyfill": "6.26.0" + "source-map": "0.6.1" } }, "websocket-driver": { @@ -12666,7 +11466,7 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.4.10", + "http-parser-js": "0.4.12", "websocket-extensions": "0.1.3" } }, @@ -12683,12 +11483,26 @@ "dev": true, "requires": { "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + } } }, + "whatwg-mimetype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", + "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", + "dev": true + }, "whatwg-url": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz", - "integrity": "sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.1.tgz", + "integrity": "sha512-FwygsxsXx27x6XXuExA/ox3Ktwcbf+OAvrKmLulotDAiO1Q6ixchPFaHYsis2zZBZSJTR0+dR+JVtf7MlbqZjw==", "dev": true, "requires": { "lodash.sortby": "4.7.0", @@ -12703,9 +11517,9 @@ "dev": true }, "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { "isexe": "2.0.0" @@ -12717,25 +11531,18 @@ "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 - }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-farm": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.4.tgz", - "integrity": "sha512-ITyClEvcfv0ozqJl1vmWFWhvI+OIrkbInYqkEPE50wFPXj8J9Gd3FYf8+CkZJXJJsQBYe+2DvmoK9Zhx5w8W+w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", "dev": true, "requires": { - "errno": "0.1.7", - "xtend": "4.0.1" + "errno": "0.1.7" } }, "worker-loader": { @@ -12746,35 +11553,6 @@ "requires": { "loader-utils": "1.1.0", "schema-utils": "0.4.5" - }, - "dependencies": { - "ajv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.0.tgz", - "integrity": "sha1-r6wpW7qgFSRJ5SJ0LkVHwa6TKNI=", - "dev": true, - "requires": { - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "dev": true - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", - "dev": true, - "requires": { - "ajv": "6.2.0", - "ajv-keywords": "3.1.0" - } - } } }, "wrap-ansi": { @@ -12831,15 +11609,9 @@ "dev": true, "requires": { "async-limiter": "1.0.0", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, - "xml-char-classes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", - "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=", - "dev": true - }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -12886,29 +11658,37 @@ "dev": true }, "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", "dev": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", + "cliui": "4.1.0", "decamelize": "1.2.0", - "window-size": "0.1.0" + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" }, "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true } } }, "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { "camelcase": "4.1.0" diff --git a/package.json b/package.json index 635d47cc..849f800e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "7.9.0", + "version": "7.11.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", @@ -30,60 +30,64 @@ "main": "build/node/CyberChef.js", "bugs": "https://github.com/gchq/CyberChef/issues", "devDependencies": { - "babel-core": "^6.26.0", - "babel-loader": "^7.1.3", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.4", "babel-preset-env": "^1.6.1", - "css-loader": "^0.28.10", - "eslint": "^4.18.1", + "css-loader": "^0.28.11", + "eslint": "^4.19.1", "exports-loader": "^0.7.0", "extract-text-webpack-plugin": "^4.0.0-alpha0", - "file-loader": "^1.1.10", + "file-loader": "^1.1.11", "grunt": ">=1.0.2", "grunt-accessibility": "~6.0.0", "grunt-chmod": "~1.1.1", + "grunt-concurrent": "^2.3.1", "grunt-contrib-clean": "~1.1.0", "grunt-contrib-copy": "~1.0.0", + "grunt-contrib-watch": "^1.0.1", "grunt-eslint": "^20.1.0", "grunt-exec": "~3.0.0", "grunt-jsdoc": "^2.2.1", - "grunt-webpack": "^3.0.2", - "html-webpack-plugin": "^3.0.4", + "grunt-webpack": "^3.1.1", + "html-webpack-plugin": "^3.2.0", "imports-loader": "^0.8.0", "ink-docstrap": "^1.3.2", - "jsdoc-babel": "^0.3.0", - "less": "^3.0.1", - "less-loader": "^4.0.6", - "postcss-css-variables": "^0.8.0", + "js-to-mjs": "^0.2.0", + "jsdoc-babel": "^0.4.0", + "less": "^3.0.2", + "less-loader": "^4.1.0", + "postcss-css-variables": "^0.8.1", "postcss-import": "^11.1.0", - "postcss-loader": "^2.1.1", + "postcss-loader": "^2.1.4", "sitemap": "^1.13.0", - "style-loader": "^0.20.2", - "url-loader": "^0.6.2", + "style-loader": "^0.21.0", + "url-loader": "^1.0.1", "web-resource-inliner": "^4.2.1", - "webpack": "^4.0.1", - "webpack-dev-server": "^3.1.0", - "webpack-node-externals": "^1.6.0", - "webpack-synchronizable-shell-plugin": "0.0.7", + "webpack": "^4.6.0", + "webpack-dev-server": "^3.1.3", + "webpack-node-externals": "^1.7.2", "worker-loader": "^1.1.1" }, "dependencies": { "babel-polyfill": "^6.26.0", "babel-plugin-transform-builtin-extend": "1.1.2", "bcryptjs": "^2.4.3", - "bignumber.js": "^6.0.0", + "bignumber.js": "^7.0.1", "bootstrap": "^3.3.7", "bootstrap-colorpicker": "^2.5.2", "bootstrap-switch": "^3.3.4", - "bson": "^2.0.4", + "bson": "^2.0.6", + "chi-squared": "^1.1.0", "crypto-api": "^0.8.0", "crypto-js": "^3.1.9-1", "ctph.js": "0.0.5", - "diff": "^3.4.0", + "diff": "^3.5.0", "escodegen": "^1.9.1", + "es6-promisify": "^6.0.0", "esmangle": "^1.0.1", "esprima": "^4.0.0", "exif-parser": "^0.1.12", - "file-saver": "^1.3.3", + "file-saver": "^1.3.8", "highlight.js": "^9.12.0", "jquery": "^3.3.1", "js-crc": "^0.2.0", @@ -91,15 +95,16 @@ "jsbn": "^1.1.0", "jsesc": "^2.5.1", "jsonpath": "^1.0.0", - "jsrsasign": "8.0.6", - "lodash": "^4.17.5", + "jsrsasign": "8.0.12", + "lodash": "^4.17.10", "loglevel": "^1.6.1", + "kbpgp": "^2.0.77", "loglevel-message-prefix": "^3.0.0", - "moment": "^2.20.1", - "moment-timezone": "^0.5.14", - "node-forge": "^0.7.2", + "moment": "^2.22.1", + "moment-timezone": "^0.5.16", + "node-forge": "^0.7.5", "node-md6": "^0.1.0", - "nwmatcher": "^1.4.3", + "nwmatcher": "^1.4.4", "otp": "^0.1.3", "scryptsy": "^2.0.0", "sladex-blowfish": "^0.8.1", @@ -120,6 +125,7 @@ "test": "grunt test", "docs": "grunt docs", "lint": "grunt lint", - "build-node": "grunt node" + "build-node": "grunt node", + "postinstall": "[ -f node_modules/crypto-api/src/crypto-api.mjs ] || npx j2m node_modules/crypto-api/src/crypto-api.js" } } diff --git a/src/core/Chef.mjs b/src/core/Chef.mjs index 79172479..a7302377 100755 --- a/src/core/Chef.mjs +++ b/src/core/Chef.mjs @@ -60,6 +60,12 @@ class Chef { recipe.setBreakpoint(progress + 1, true); } + // If the previously run operation presented a different value to its + // normal output, we need to recalculate it. + if (recipe.lastOpPresented(progress)) { + progress = 0; + } + // If stepping with flow control, we have to start from the beginning // but still want to skip all previous breakpoints if (progress > 0 && containsFc) { diff --git a/src/core/ChefWorker.js b/src/core/ChefWorker.js index dbbda126..8f6cbce5 100644 --- a/src/core/ChefWorker.js +++ b/src/core/ChefWorker.js @@ -91,7 +91,7 @@ self.addEventListener("message", function(e) { */ async function bake(data) { // Ensure the relevant modules are loaded - loadRequiredModules(data.recipeConfig); + self.loadRequiredModules(data.recipeConfig); try { const response = await self.chef.bake( @@ -144,25 +144,6 @@ async function getDishAs(data) { } -/** - * Checks that all required modules are loaded and loads them if not. - * - * @param {Object} recipeConfig - */ -function loadRequiredModules(recipeConfig) { - recipeConfig.forEach(op => { - const module = self.OperationConfig[op.op].module; - - if (!OpModules.hasOwnProperty(module)) { - log.info("Loading module " + module); - self.sendStatusMessage("Loading module " + module); - self.importScripts(self.docURL + "/" + module + ".js"); - self.sendStatusMessage(""); - } - }); -} - - /** * Calculates highlight offsets if possible. * @@ -182,6 +163,25 @@ function calculateHighlights(recipeConfig, direction, pos) { } +/** + * Checks that all required modules are loaded and loads them if not. + * + * @param {Object} recipeConfig + */ +self.loadRequiredModules = function(recipeConfig) { + recipeConfig.forEach(op => { + const module = self.OperationConfig[op.op].module; + + if (!OpModules.hasOwnProperty(module)) { + log.info(`Loading ${module} module`); + self.sendStatusMessage(`Loading ${module} module`); + self.importScripts(`${self.docURL}/${module}.js`); + self.sendStatusMessage(""); + } + }); +}; + + /** * Send status update to the app. * diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js deleted file mode 100755 index f1bb8dab..00000000 --- a/src/core/FlowControl.js +++ /dev/null @@ -1,291 +0,0 @@ -import Recipe from "./Recipe"; -import Dish from "./Dish"; - - -/** - * Flow Control operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const FlowControl = { - - /** - * Fork operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @returns {Object} The updated state of the recipe. - */ - runFork: async function(state) { - const opList = state.opList, - inputType = opList[state.progress].inputType, - outputType = opList[state.progress].outputType, - input = await state.dish.get(inputType), - ings = opList[state.progress].ingValues, - splitDelim = ings[0], - mergeDelim = ings[1], - ignoreErrors = ings[2], - subOpList = []; - let inputs = [], - i; - - if (input) - inputs = input.split(splitDelim); - - // Create subOpList for each tranche to operate on - // (all remaining operations unless we encounter a Merge) - for (i = state.progress + 1; i < opList.length; i++) { - if (opList[i].name === "Merge" && !opList[i].disabled) { - break; - } else { - subOpList.push(opList[i]); - } - } - - const recipe = new Recipe(); - let output = "", - progress = 0; - - state.forkOffset += state.progress + 1; - - recipe.addOperations(subOpList); - - // Take a deep(ish) copy of the ingredient values - const ingValues = subOpList.map(op => JSON.parse(JSON.stringify(op.ingValues))); - - // Run recipe over each tranche - for (i = 0; i < inputs.length; i++) { - log.debug(`Entering tranche ${i + 1} of ${inputs.length}`); - - // Baseline ing values for each tranche so that registers are reset - subOpList.forEach((op, i) => { - op.ingValues = JSON.parse(JSON.stringify(ingValues[i])); - }); - - const dish = new Dish(); - dish.set(inputs[i], inputType); - - try { - progress = await recipe.execute(dish, 0, state); - } catch (err) { - if (!ignoreErrors) { - throw err; - } - progress = err.progress + 1; - } - output += await dish.get(outputType) + mergeDelim; - } - - state.dish.set(output, outputType); - state.progress += progress; - return state; - }, - - - /** - * Merge operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @returns {Object} The updated state of the recipe. - */ - runMerge: function(state) { - // No need to actually do anything here. The fork operation will - // merge when it sees this operation. - return state; - }, - - - /** - * Register operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @returns {Object} The updated state of the recipe. - */ - runRegister: async function(state) { - const ings = state.opList[state.progress].ingValues, - extractorStr = ings[0], - i = ings[1], - m = ings[2]; - - let modifiers = ""; - if (i) modifiers += "i"; - if (m) modifiers += "m"; - - const extractor = new RegExp(extractorStr, modifiers), - input = await state.dish.get(Dish.STRING), - registers = input.match(extractor); - - if (!registers) return state; - - if (ENVIRONMENT_IS_WORKER()) { - self.setRegisters(state.forkOffset + state.progress, state.numRegisters, registers.slice(1)); - } - - /** - * Replaces references to registers (e.g. $R0) with the contents of those registers. - * - * @param {string} str - * @returns {string} - */ - function replaceRegister(str) { - // Replace references to registers ($Rn) with contents of registers - return str.replace(/(\\*)\$R(\d{1,2})/g, (match, slashes, regNum) => { - const index = parseInt(regNum, 10) + 1; - if (index <= state.numRegisters || index >= state.numRegisters + registers.length) - return match; - if (slashes.length % 2 !== 0) return match.slice(1); // Remove escape - return slashes + registers[index - state.numRegisters]; - }); - } - - // Step through all subsequent ops and replace registers in args with extracted content - for (let i = state.progress + 1; i < state.opList.length; i++) { - if (state.opList[i].disabled) continue; - - let args = state.opList[i].ingValues; - args = args.map(arg => { - if (typeof arg !== "string" && typeof arg !== "object") return arg; - - if (typeof arg === "object" && arg.hasOwnProperty("string")) { - arg.string = replaceRegister(arg.string); - return arg; - } - return replaceRegister(arg); - }); - state.opList[i].setIngValues(args); - } - - state.numRegisters += registers.length - 1; - return state; - }, - - - /** - * Jump operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @param {number} state.numJumps - The number of jumps taken so far. - * @returns {Object} The updated state of the recipe. - */ - runJump: function(state) { - const ings = state.opList[state.progress].ingValues, - label = ings[0], - maxJumps = ings[1], - jmpIndex = FlowControl._getLabelIndex(label, state); - - if (state.numJumps >= maxJumps || jmpIndex === -1) { - log.debug("Maximum jumps reached or label cannot be found"); - return state; - } - - state.progress = jmpIndex; - state.numJumps++; - log.debug(`Jumping to label '${label}' at position ${jmpIndex} (jumps = ${state.numJumps})`); - return state; - }, - - - /** - * Conditional Jump operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @param {number} state.numJumps - The number of jumps taken so far. - * @returns {Object} The updated state of the recipe. - */ - runCondJump: async function(state) { - const ings = state.opList[state.progress].ingValues, - dish = state.dish, - regexStr = ings[0], - invert = ings[1], - label = ings[2], - maxJumps = ings[3], - jmpIndex = FlowControl._getLabelIndex(label, state); - - if (state.numJumps >= maxJumps || jmpIndex === -1) { - log.debug("Maximum jumps reached or label cannot be found"); - return state; - } - - if (regexStr !== "") { - const strMatch = await dish.get(Dish.STRING).search(regexStr) > -1; - if (!invert && strMatch || invert && !strMatch) { - state.progress = jmpIndex; - state.numJumps++; - log.debug(`Jumping to label '${label}' at position ${jmpIndex} (jumps = ${state.numJumps})`); - } - } - - return state; - }, - - - /** - * Return operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @returns {Object} The updated state of the recipe. - */ - runReturn: function(state) { - state.progress = state.opList.length; - return state; - }, - - - /** - * Comment operation. - * - * @param {Object} state - The current state of the recipe. - * @param {number} state.progress - The current position in the recipe. - * @param {Dish} state.dish - The Dish being operated on. - * @param {Operation[]} state.opList - The list of operations in the recipe. - * @returns {Object} The updated state of the recipe. - */ - runComment: function(state) { - return state; - }, - - - /** - * Returns the index of a label. - * - * @private - * @param {Object} state - * @param {string} name - * @returns {number} - */ - _getLabelIndex: function(name, state) { - for (let o = 0; o < state.opList.length; o++) { - const operation = state.opList[o]; - if (operation.name === "Label"){ - const ings = operation.ingValues; - if (name === ings[0]) { - return o; - } - } - } - return -1; - }, -}; - -export default FlowControl; diff --git a/src/core/Ingredient.mjs b/src/core/Ingredient.mjs index 18823daf..914500f3 100755 --- a/src/core/Ingredient.mjs +++ b/src/core/Ingredient.mjs @@ -21,6 +21,7 @@ class Ingredient { this.name = ""; this.type = ""; this._value = null; + this.toggleValues = []; if (ingredientConfig) { this._parseConfig(ingredientConfig); @@ -38,6 +39,7 @@ class Ingredient { this.name = ingredientConfig.name; this.type = ingredientConfig.type; this.defaultValue = ingredientConfig.value; + this.toggleValues = ingredientConfig.toggleValues; } diff --git a/src/core/Operation.mjs b/src/core/Operation.mjs index e87c31f4..855b75ab 100755 --- a/src/core/Operation.mjs +++ b/src/core/Operation.mjs @@ -81,9 +81,10 @@ class Operation { * this behaviour. * * @param {*} data - The result of the run() function + * @param {Object[]} args - The operation's arguments * @returns {*} - A human-readable version of the data */ - present(data) { + present(data, args) { return data; } @@ -172,7 +173,8 @@ class Operation { return { name: ing.name, type: ing.type, - value: ing.defaultValue + value: ing.defaultValue, + toggleValues: ing.toggleValues || [] }; }); } @@ -186,7 +188,7 @@ class Operation { get config() { return { "op": this.name, - "args": this._ingList.map(ing => ing.conf) + "args": this._ingList.map(ing => ing.config) }; } @@ -272,6 +274,15 @@ class Operation { return this._flowControl; } + /** + * Set whether this Operation is a flowcontrol op. + * + * @param {boolean} value + */ + set flowControl(value) { + this._flowControl = !!value; + } + } export default Operation; diff --git a/src/core/Recipe.mjs b/src/core/Recipe.mjs index 22c4463b..a5b2e81f 100755 --- a/src/core/Recipe.mjs +++ b/src/core/Recipe.mjs @@ -172,12 +172,15 @@ class Recipe { numRegisters = state.numRegisters; } else { output = await op.run(input, op.ingValues); - this.lastRunOp = op; dish.set(output, op.outputType); } + this.lastRunOp = op; } catch (err) { // Return expected errors as output - if (err instanceof OperationError) { + if (err instanceof OperationError || + (err.type && err.type === "OperationError")) { + // Cannot rely on `err instanceof OperationError` here as extending + // native types is not fully supported yet. dish.set(err.message, "string"); return i; } else { @@ -209,7 +212,10 @@ class Recipe { async present(dish) { if (!this.lastRunOp) return; - const output = await this.lastRunOp.present(await dish.get(this.lastRunOp.outputType)); + const output = await this.lastRunOp.present( + await dish.get(this.lastRunOp.outputType), + this.lastRunOp.ingValues + ); dish.set(output, this.lastRunOp.presentType); } @@ -267,6 +273,18 @@ class Recipe { return highlights; } + + /** + * Determines whether the previous operation has a different presentation type to its normal output. + * + * @param {number} progress + * @returns {boolean} + */ + lastOpPresented(progress) { + if (progress < 1) return false; + return this.opList[progress-1].presentType !== this.opList[progress-1].outputType; + } + } export default Recipe; diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index f90bc394..c35aef13 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -524,36 +524,43 @@ class Utils { * Parses CSV data and returns it as a two dimensional array or strings. * * @param {string} data + * @param {string[]} [cellDelims=[","]] + * @param {string[]} [lineDelims=["\n", "\r"]] * @returns {string[][]} * * @example * // returns [["head1", "head2"], ["data1", "data2"]] * Utils.parseCSV("head1,head2\ndata1,data2"); */ - static parseCSV(data) { + static parseCSV(data, cellDelims=[","], lineDelims=["\n", "\r"]) { let b, - ignoreNext = false, + next, + renderNext = false, inString = false, cell = "", line = []; const lines = []; + // Remove BOM, often present in Excel CSV files + if (data.length && data[0] === "\uFEFF") data = data.substr(1); + for (let i = 0; i < data.length; i++) { b = data[i]; - if (ignoreNext) { + next = data[i+1] || ""; + if (renderNext) { cell += b; - ignoreNext = false; + renderNext = false; } else if (b === "\\") { - cell += b; - ignoreNext = true; + renderNext = true; } else if (b === "\"" && !inString) { inString = true; } else if (b === "\"" && inString) { - inString = false; - } else if (b === "," && !inString) { + if (next === "\"") renderNext = true; + else inString = false; + } else if (!inString && cellDelims.indexOf(b) >= 0) { line.push(cell); cell = ""; - } else if ((b === "\n" || b === "\r") && !inString) { + } else if (!inString && lineDelims.indexOf(b) >= 0) { line.push(cell); cell = ""; lines.push(line); @@ -713,7 +720,7 @@ class Utils { * @param {boolean} [newline=false] - whether to add a newline after each operation * @returns {string} */ - static generatePrettyRecipe(recipeConfig, newline=false) { + static generatePrettyRecipe(recipeConfig, newline = false) { let prettyConfig = "", name = "", args = "", diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js deleted file mode 100755 index 70e4ea4b..00000000 --- a/src/core/config/Categories.js +++ /dev/null @@ -1,366 +0,0 @@ -/** - * Type definition for a CatConf. - * - * @typedef {Object} CatConf - * @property {string} name - The display name for the category - * @property {string[]} ops - A list of the operations to be included in this category - */ - - -/** - * Categories of operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constant - * @type {CatConf[]} - */ -const Categories = [ - { - name: "Favourites", - ops: [] - }, - { - name: "Data format", - ops: [ - // "To Hexdump", - // "From Hexdump", - "To Hex", - "From Hex", - // "To Charcode", - // "From Charcode", - // "To Decimal", - // "From Decimal", - // "To Binary", - // "From Binary", - // "To Octal", - // "From Octal", - "To Base64", - "From Base64", - "Show Base64 offsets", - "To Base32", - "From Base32", - // "To Base58", - // "From Base58", - // "To Base", - // "From Base", - // "To BCD", - // "From BCD", - // "To HTML Entity", - // "From HTML Entity", - // "URL Encode", - // "URL Decode", - // "Escape Unicode Characters", - // "Unescape Unicode Characters", - // "To Quoted Printable", - // "From Quoted Printable", - // "To Punycode", - // "From Punycode", - // "To Hex Content", - // "From Hex Content", - // "PEM to Hex", - // "Hex to PEM", - // "Parse ASN.1 hex string", - // "Change IP format", - // "Encode text", - // "Decode text", - // "Swap endianness", - // ] - // }, - // { - // name: "Encryption / Encoding", - // ops: [ - // "AES Encrypt", - // "AES Decrypt", - // "Blowfish Encrypt", - // "Blowfish Decrypt", - // "DES Encrypt", - // "DES Decrypt", - // "Triple DES Encrypt", - // "Triple DES Decrypt", - // "RC2 Encrypt", - // "RC2 Decrypt", - // "RC4", - // "RC4 Drop", - "ROT13", - "ROT47", - // "XOR", - // "XOR Brute Force", - // "Vigenère Encode", - // "Vigenère Decode", - // "To Morse Code", - // "From Morse Code", - // "Bifid Cipher Encode", - // "Bifid Cipher Decode", - // "Affine Cipher Encode", - // "Affine Cipher Decode", - // "Atbash Cipher", - // "Substitute", - // "Derive PBKDF2 key", - // "Derive EVP key", - // "Bcrypt", - // "Scrypt", - // "Pseudo-Random Number Generator", - ] - }, - // { - // name: "Public Key", - // ops: [ - // "Parse X.509 certificate", - // "Parse ASN.1 hex string", - // "PEM to Hex", - // "Hex to PEM", - // "Hex to Object Identifier", - // "Object Identifier to Hex", - // ] - // }, - { - name: "Arithmetic / Logic", - ops: [ - "Set Union", - "Set Intersection", - "Set Difference", - "Symmetric Difference", - "Cartesian Product", - "Power Set", - // "XOR", - // "XOR Brute Force", - // "OR", - // "NOT", - // "AND", - // "ADD", - // "SUB", - // "Sum", - // "Subtract", - // "Multiply", - // "Divide", - // "Mean", - // "Median", - // "Standard Deviation", - // "Bit shift left", - // "Bit shift right", - "Rotate left", - "Rotate right", - "ROT13" - ] - }, - // { - // name: "Networking", - // ops: [ - // "HTTP request", - // "Strip HTTP headers", - // "Parse User Agent", - // "Parse IP range", - // "Parse IPv6 address", - // "Parse IPv4 header", - // "Parse URI", - // "URL Encode", - // "URL Decode", - // "Format MAC addresses", - // "Change IP format", - // "Group IP addresses", - // "Encode NetBIOS Name", - // "Decode NetBIOS Name", - // ] - // }, - // { - // name: "Language", - // ops: [ - // "Encode text", - // "Decode text", - // "Unescape Unicode Characters", - // ] - // }, - // { - // name: "Utils", - // ops: [ - // "Diff", - // "Remove whitespace", - // "Remove null bytes", - // "To Upper case", - // "To Lower case", - // "Add line numbers", - // "Remove line numbers", - // "Reverse", - // "Sort", - // "Unique", - // "Split", - // "Filter", - // "Head", - // "Tail", - // "Count occurrences", - // "Expand alphabet range", - // "Drop bytes", - // "Take bytes", - // "Pad lines", - // "Find / Replace", - // "Regular expression", - // "Offset checker", - // "Hamming Distance", - // "Convert distance", - // "Convert area", - // "Convert mass", - // "Convert speed", - // "Convert data units", - // "Parse UNIX file permissions", - // "Swap endianness", - // "Parse colour code", - // "Escape string", - // "Unescape string", - // "Pseudo-Random Number Generator", - // "Sleep", - // ] - // }, - // { - // name: "Date / Time", - // ops: [ - // "Parse DateTime", - // "Translate DateTime Format", - // "From UNIX Timestamp", - // "To UNIX Timestamp", - // "Windows Filetime to UNIX Timestamp", - // "UNIX Timestamp to Windows Filetime", - // "Extract dates", - // "Sleep", - // ] - // }, - // { - // name: "Extractors", - // ops: [ - // "Strings", - // "Extract IP addresses", - // "Extract email addresses", - // "Extract MAC addresses", - // "Extract URLs", - // "Extract domains", - // "Extract file paths", - // "Extract dates", - // "Regular expression", - // "XPath expression", - // "JPath expression", - // "CSS selector", - // "Extract EXIF", - // ] - // }, - { - name: "Compression", - ops: [ - "Raw Deflate", - "Raw Inflate", - "Zlib Deflate", - "Zlib Inflate", - "Gzip", - "Gunzip", - "Zip", - "Unzip", - // "Bzip2 Decompress", - // "Tar", - // "Untar", - ] - }, - // { - // name: "Hashing", - // ops: [ - // "Analyse hash", - // "Generate all hashes", - // "MD2", - // "MD4", - // "MD5", - // "MD6", - // "SHA0", - // "SHA1", - // "SHA2", - // "SHA3", - // "Keccak", - // "Shake", - // "RIPEMD", - // "HAS-160", - // "Whirlpool", - // "Snefru", - // "SSDEEP", - // "CTPH", - // "Compare SSDEEP hashes", - // "Compare CTPH hashes", - // "HMAC", - // "Bcrypt", - // "Bcrypt compare", - // "Bcrypt parse", - // "Scrypt", - // "Fletcher-8 Checksum", - // "Fletcher-16 Checksum", - // "Fletcher-32 Checksum", - // "Fletcher-64 Checksum", - // "Adler-32 Checksum", - // "CRC-16 Checksum", - // "CRC-32 Checksum", - // "TCP/IP Checksum", - // ] - // }, - // { - // name: "Code tidy", - // ops: [ - // "Syntax highlighter", - // "Generic Code Beautify", - // "JavaScript Parser", - // "JavaScript Beautify", - // "JavaScript Minify", - // "JSON Beautify", - // "JSON Minify", - // "XML Beautify", - // "XML Minify", - // "SQL Beautify", - // "SQL Minify", - // "CSS Beautify", - // "CSS Minify", - // "XPath expression", - // "JPath expression", - // "CSS selector", - // "PHP Deserialize", - // "Microsoft Script Decoder", - // "Strip HTML tags", - // "Diff", - // "To Snake case", - // "To Camel case", - // "To Kebab case", - // "BSON serialise", - // "BSON deserialise", - // ] - // }, - // { - // name: "Other", - // ops: [ - // "Entropy", - // "Frequency distribution", - // "Chi Square", - // "Detect File Type", - // "Scan for Embedded Files", - // "Disassemble x86", - // "Pseudo-Random Number Generator", - // "Generate UUID", - // "Generate TOTP", - // "Generate HOTP", - // "Render Image", - // "Remove EXIF", - // "Extract EXIF", - // "Numberwang", - // "XKCD Random Number", - // ] - // }, - // { - // name: "Flow control", - // ops: [ - // "Fork", - // "Merge", - // "Register", - // "Label", - // "Jump", - // "Conditional Jump", - // "Return", - // "Comment" - // ] - // }, -]; - -export default Categories; diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json new file mode 100755 index 00000000..9078e250 --- /dev/null +++ b/src/core/config/Categories.json @@ -0,0 +1,352 @@ +[ + { + "name": "Favourites", + "ops": [] + }, + { + "name": "Data format", + "ops": [ + "To Hexdump", + "From Hexdump", + "To Hex", + "From Hex", + "To Charcode", + "From Charcode", + "To Decimal", + "From Decimal", + "To Binary", + "From Binary", + "To Octal", + "From Octal", + "To Base64", + "From Base64", + "Show Base64 offsets", + "To Base32", + "From Base32", + "To Base58", + "From Base58", + "To Base", + "From Base", + "To BCD", + "From BCD", + "To HTML Entity", + "From HTML Entity", + "URL Encode", + "URL Decode", + "Escape Unicode Characters", + "Unescape Unicode Characters", + "To Quoted Printable", + "From Quoted Printable", + "To Punycode", + "From Punycode", + "To Hex Content", + "From Hex Content", + "PEM to Hex", + "Hex to PEM", + "Parse ASN.1 hex string", + "Change IP format", + "Encode text", + "Decode text", + "Swap endianness" + ] + }, + { + "name": "Encryption / Encoding", + "ops": [ + "AES Encrypt", + "AES Decrypt", + "Blowfish Encrypt", + "Blowfish Decrypt", + "DES Encrypt", + "DES Decrypt", + "Triple DES Encrypt", + "Triple DES Decrypt", + "RC2 Encrypt", + "RC2 Decrypt", + "RC4", + "RC4 Drop", + "ROT13", + "ROT47", + "XOR", + "XOR Brute Force", + "Vigenère Encode", + "Vigenère Decode", + "To Morse Code", + "From Morse Code", + "Bifid Cipher Encode", + "Bifid Cipher Decode", + "Affine Cipher Encode", + "Affine Cipher Decode", + "Atbash Cipher", + "Substitute", + "Derive PBKDF2 key", + "Derive EVP key", + "Bcrypt", + "Scrypt", + "Pseudo-Random Number Generator" + ] + }, + { + "name": "Public Key", + "ops": [ + "Parse X.509 certificate", + "Parse ASN.1 hex string", + "PEM to Hex", + "Hex to PEM", + "Hex to Object Identifier", + "Object Identifier to Hex", + "Generate PGP Key Pair", + "PGP Encrypt", + "PGP Decrypt", + "PGP Encrypt and Sign", + "PGP Decrypt and Verify" + ] + }, + { + "name": "Arithmetic / Logic", + "ops": [ + "Set Union", + "Set Intersection", + "Set Difference", + "Symmetric Difference", + "Cartesian Product", + "Power Set", + "XOR", + "XOR Brute Force", + "OR", + "NOT", + "AND", + "ADD", + "SUB", + "Sum", + "Subtract", + "Multiply", + "Divide", + "Mean", + "Median", + "Standard Deviation", + "Bit shift left", + "Bit shift right", + "Rotate left", + "Rotate right", + "ROT13" + ] + }, + { + "name": "Networking", + "ops": [ + "HTTP request", + "Strip HTTP headers", + "Parse User Agent", + "Parse IP range", + "Parse IPv6 address", + "Parse IPv4 header", + "Parse URI", + "URL Encode", + "URL Decode", + "Format MAC addresses", + "Change IP format", + "Group IP addresses", + "Encode NetBIOS Name", + "Decode NetBIOS Name" + ] + }, + { + "name": "Language", + "ops": [ + "Encode text", + "Decode text", + "Unescape Unicode Characters" + ] + }, + { + "name": "Utils", + "ops": [ + "Diff", + "Remove whitespace", + "Remove null bytes", + "To Upper case", + "To Lower case", + "Add line numbers", + "Remove line numbers", + "To Table", + "Reverse", + "Sort", + "Unique", + "Split", + "Filter", + "Head", + "Tail", + "Count occurrences", + "Expand alphabet range", + "Drop bytes", + "Take bytes", + "Pad lines", + "Find / Replace", + "Regular expression", + "Offset checker", + "Hamming Distance", + "Convert distance", + "Convert area", + "Convert mass", + "Convert speed", + "Convert data units", + "Parse UNIX file permissions", + "Swap endianness", + "Parse colour code", + "Escape string", + "Unescape string", + "Pseudo-Random Number Generator", + "Sleep" + ] + }, + { + "name": "Date / Time", + "ops": [ + "Parse DateTime", + "Translate DateTime Format", + "From UNIX Timestamp", + "To UNIX Timestamp", + "Windows Filetime to UNIX Timestamp", + "UNIX Timestamp to Windows Filetime", + "Extract dates", + "Sleep" + ] + }, + { + "name": "Extractors", + "ops": [ + "Strings", + "Extract IP addresses", + "Extract email addresses", + "Extract MAC addresses", + "Extract URLs", + "Extract domains", + "Extract file paths", + "Extract dates", + "Regular expression", + "XPath expression", + "JPath expression", + "CSS selector", + "Extract EXIF" + ] + }, + { + "name": "Compression", + "ops": [ + "Raw Deflate", + "Raw Inflate", + "Zlib Deflate", + "Zlib Inflate", + "Gzip", + "Gunzip", + "Zip", + "Unzip", + "Bzip2 Decompress", + "Tar", + "Untar" + ] + }, + { + "name": "Hashing", + "ops": [ + "Analyse hash", + "Generate all hashes", + "MD2", + "MD4", + "MD5", + "MD6", + "SHA0", + "SHA1", + "SHA2", + "SHA3", + "Keccak", + "Shake", + "RIPEMD", + "HAS-160", + "Whirlpool", + "Snefru", + "SSDEEP", + "CTPH", + "Compare SSDEEP hashes", + "Compare CTPH hashes", + "HMAC", + "Bcrypt", + "Bcrypt compare", + "Bcrypt parse", + "Scrypt", + "Fletcher-8 Checksum", + "Fletcher-16 Checksum", + "Fletcher-32 Checksum", + "Fletcher-64 Checksum", + "Adler-32 Checksum", + "CRC-16 Checksum", + "CRC-32 Checksum", + "TCP/IP Checksum" + ] + }, + { + "name": "Code tidy", + "ops": [ + "Syntax highlighter", + "Generic Code Beautify", + "JavaScript Parser", + "JavaScript Beautify", + "JavaScript Minify", + "JSON Beautify", + "JSON Minify", + "XML Beautify", + "XML Minify", + "SQL Beautify", + "SQL Minify", + "CSS Beautify", + "CSS Minify", + "XPath expression", + "JPath expression", + "CSS selector", + "PHP Deserialize", + "Microsoft Script Decoder", + "Strip HTML tags", + "Diff", + "To Snake case", + "To Camel case", + "To Kebab case", + "BSON serialise", + "BSON deserialise" + ] + }, + { + "name": "Other", + "ops": [ + "Entropy", + "Frequency distribution", + "Chi Square", + "Detect File Type", + "Scan for Embedded Files", + "Disassemble x86", + "Pseudo-Random Number Generator", + "Generate UUID", + "Generate TOTP", + "Generate HOTP", + "Render Image", + "Remove EXIF", + "Extract EXIF", + "Numberwang", + "XKCD Random Number" + ] + }, + { + "name": "Flow control", + "ops": [ + "Magic", + "Fork", + "Merge", + "Register", + "Label", + "Jump", + "Conditional Jump", + "Return", + "Comment" + ] + } +] diff --git a/src/core/config/scripts/generateConfig.mjs b/src/core/config/scripts/generateConfig.mjs index 778b6e30..2ee121ce 100644 --- a/src/core/config/scripts/generateConfig.mjs +++ b/src/core/config/scripts/generateConfig.mjs @@ -43,6 +43,10 @@ for (const opObj in Ops) { args: op.args }; + if (op.hasOwnProperty("patterns")) { + operationConfig[op.name].patterns = op.patterns; + } + if (!modules.hasOwnProperty(op.module)) modules[op.module] = {}; modules[op.module][op.name] = opObj; @@ -142,4107 +146,3 @@ fs.writeFileSync( opModulesCode ); console.log("Written OpModules.mjs"); - - - /*"Fork": { - module: "Default", - description: "Split the input data up based on the specified delimiter and run all subsequent operations on each branch separately.

For example, to decode multiple Base64 strings, enter them all on separate lines then add the 'Fork' and 'From Base64' operations to the recipe. Each string will be decoded separately.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Split delimiter", - type: "binaryShortString", - value: "\\n" - }, - { - name: "Merge delimiter", - type: "binaryShortString", - value: "\\n" - }, - { - name: "Ignore errors", - type: "boolean", - value: false - } - ] - }, - "Merge": { - module: "Default", - description: "Consolidate all branches back into a single trunk. The opposite of Fork.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [] - }, - "Register": { - module: "Default", - description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.

To use registers in arguments, refer to them using the notation $Rn where n is the register number, starting at 0.

For example:
Input: Test
Extractor: (.*)
Argument: $R0 becomes Test

Registers can be escaped in arguments using a backslash. e.g. \\$R0 would become $R0 rather than Test.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Extractor", - type: "binaryString", - value: "([\\s\\S]*)" - }, - { - name: "Case insensitive", - type: "boolean", - value: true - }, - { - name: "Multiline matching", - type: "boolean", - value: false - }, - ] - }, - "Jump": { - module: "Default", - description: "Jump forwards or backwards to the specified Label", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Label name", - type: "string", - value: "" - }, - { - name: "Maximum jumps (if jumping backwards)", - type: "number", - value: 10 - } - ] - }, - "Conditional Jump": { - module: "Default", - description: "Conditionally jump forwards or backwards to the specified Label based on whether the data matches the specified regular expression.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Match (regex)", - type: "string", - value: "" - }, - { - name: "Invert match", - type: "boolean", - value: false - }, - { - name: "Label name", - type: "shortString", - value: "" - }, - { - name: "Maximum jumps (if jumping backwards)", - type: "number", - value: 10 - } - ] - }, - "Label": { - module: "Default", - description: "Provides a location for conditional and fixed jumps to redirect execution to.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Name", - type: "shortString", - value: "" - } - ] - }, - "Return": { - module: "Default", - description: "End execution of operations at this point in the recipe.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [] - }, - "Comment": { - module: "Default", - description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "", - type: "text", - value: "" - } - ] - }, - "From Base64": { - module: "Default", - description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.

This operation decodes data from an ASCII Base64 string back into its raw format.

e.g. aGVsbG8= becomes hello", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: Base64.ALPHABET_OPTIONS - }, - { - name: "Remove non-alphabet chars", - type: "boolean", - value: Base64.REMOVE_NON_ALPH_CHARS - } - ] - }, - "To Base64": { - module: "Default", - description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.

This operation encodes data in an ASCII Base64 string.

e.g. hello becomes aGVsbG8=", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: Base64.ALPHABET_OPTIONS - }, - ] - }, -};*/ - -/* - "From Base58": { - module: "Default", - description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation decodes data from an ASCII string (with an alphabet of your choosing, presets included) back into its raw form.

e.g. StV1DL6CwTryKyV becomes hello world

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: Base58.ALPHABET_OPTIONS - }, - { - name: "Remove non-alphabet chars", - type: "boolean", - value: Base58.REMOVE_NON_ALPH_CHARS - } - ] - }, - "To Base58": { - module: "Default", - description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).

e.g. hello world becomes StV1DL6CwTryKyV

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: Base58.ALPHABET_OPTIONS - }, - ] - }, - "From Base32": { - module: "Default", - description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: Base64.BASE32_ALPHABET - }, - { - name: "Remove non-alphabet chars", - type: "boolean", - value: Base64.REMOVE_NON_ALPH_CHARS - } - ] - }, - "To Base32": { - module: "Default", - description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: Base64.BASE32_ALPHABET - } - ] - }, - "Show Base64 offsets": { - module: "Default", - description: "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.

This operation shows all possible offsets for a given string so that each possible encoding can be considered.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: Base64.ALPHABET - }, - { - name: "Show variable chars and padding", - type: "boolean", - value: Base64.OFFSETS_SHOW_VARIABLE - } - ] - }, - "Disassemble x86": { - module: "Shellcode", - description: "Disassembly is the process of translating machine language into assembly language.

This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.

Input should be in hexadecimal.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Bit mode", - type: "option", - value: Shellcode.MODE - }, - { - name: "Compatibility", - type: "option", - value: Shellcode.COMPATIBILITY - }, - { - name: "Code Segment (CS)", - type: "number", - value: 16 - }, - { - name: "Offset (IP)", - type: "number", - value: 0 - }, - { - name: "Show instruction hex", - type: "boolean", - value: true - }, - { - name: "Show instruction position", - type: "boolean", - value: true - } - ] - }, - "XOR": { - module: "Default", - description: "XOR the input with the given key.
e.g. fe023da5

Options
Null preserving: If the current byte is 0x00 or the same as the key, skip it.

Scheme:", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: BitwiseOp.KEY_FORMAT - }, - { - name: "Scheme", - type: "option", - value: BitwiseOp.XOR_SCHEME - }, - { - name: "Null preserving", - type: "boolean", - value: BitwiseOp.XOR_PRESERVE_NULLS - } - ] - }, - "XOR Brute Force": { - module: "Default", - description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.

Optionally enter a string that you expect to find in the plaintext to filter results (crib).", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Key length", - type: "number", - value: BitwiseOp.XOR_BRUTE_KEY_LENGTH - }, - { - name: "Sample length", - type: "number", - value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH - }, - { - name: "Sample offset", - type: "number", - value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET - }, - { - name: "Scheme", - type: "option", - value: BitwiseOp.XOR_SCHEME - }, - { - name: "Null preserving", - type: "boolean", - value: BitwiseOp.XOR_PRESERVE_NULLS - }, - { - name: "Print key", - type: "boolean", - value: BitwiseOp.XOR_BRUTE_PRINT_KEY - }, - { - name: "Output as hex", - type: "boolean", - value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX - }, - { - name: "Crib (known plaintext string)", - type: "binaryString", - value: "" - } - ] - }, - "NOT": { - module: "Default", - description: "Returns the inverse of each byte.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "AND": { - module: "Default", - description: "AND the input with the given key.
e.g. fe023da5", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: BitwiseOp.KEY_FORMAT - } - ] - }, - "OR": { - module: "Default", - description: "OR the input with the given key.
e.g. fe023da5", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: BitwiseOp.KEY_FORMAT - } - ] - }, - "ADD": { - module: "Default", - description: "ADD the input with the given key (e.g. fe023da5), MOD 255", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: BitwiseOp.KEY_FORMAT - } - ] - }, - "SUB": { - module: "Default", - description: "SUB the input with the given key (e.g. fe023da5), MOD 255", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: BitwiseOp.KEY_FORMAT - } - ] - }, - "Sum": { - module: "Default", - description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 18.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Subtract": { - module: "Default", - description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 1.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Multiply": { - module: "Default", - description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 40", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Divide": { - module: "Default", - description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 2.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Mean": { - module: "Default", - description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 .5 becomes 4.75", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Median": { - module: "Default", - description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 1 .5 becomes 4.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "Standard Deviation": { - module: "Default", - description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 4.089281382128433", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.DELIM_OPTIONS - } - ] - }, - "From Hex": { - module: "Default", - description: "Converts a hexadecimal byte string back into its raw value.

e.g. ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a becomes the UTF-8 encoded string Γειά σου", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.HEX_DELIM_OPTIONS - } - ] - }, - "To Hex": { - module: "Default", - description: "Converts the input string to hexadecimal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.HEX_DELIM_OPTIONS - } - ] - }, - "From Octal": { - module: "Default", - description: "Converts an octal byte string back into its raw value.

e.g. 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205 becomes the UTF-8 encoded string Γειά σου", - highlight: false, - highlightReverse: false, - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - } - ] - }, - "To Octal": { - module: "Default", - description: "Converts the input string to octal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205", - highlight: false, - highlightReverse: false, - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - } - ] - }, - "From Charcode": { - module: "Default", - description: "Converts unicode character codes back into text.

e.g. 0393 03b5 03b9 03ac 20 03c3 03bf 03c5 becomes Γειά σου", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - }, - { - name: "Base", - type: "number", - value: ByteRepr.CHARCODE_BASE - } - ] - }, - - "To Charcode": { - module: "Default", - description: "Converts text to its unicode character code equivalent.

e.g. Γειά σου becomes 0393 03b5 03b9 03ac 20 03c3 03bf 03c5", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - }, - { - name: "Base", - type: "number", - value: ByteRepr.CHARCODE_BASE - } - ] - }, - "From Binary": { - module: "Default", - description: "Converts a binary string back into its raw form.

e.g. 01001000 01101001 becomes Hi", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.BIN_DELIM_OPTIONS - } - ] - }, - "To Binary": { - module: "Default", - description: "Displays the input data as a binary string.

e.g. Hi becomes 01001000 01101001", - highlight: "func", - highlightReverse: "func", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.BIN_DELIM_OPTIONS - } - ] - }, - "From Decimal": { - module: "Default", - description: "Converts the data from an ordinal integer array back into its raw form.

e.g. 72 101 108 108 111 becomes Hello", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - } - ] - }, - "To Decimal": { - module: "Default", - description: "Converts the input data to an ordinal integer array.

e.g. Hello becomes 72 101 108 108 111", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: ByteRepr.DELIM_OPTIONS - } - ] - }, - "From Hexdump": { - module: "Default", - description: "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis.", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [] - }, - "To Hexdump": { - module: "Default", - description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Width", - type: "number", - value: Hexdump.WIDTH - }, - { - name: "Upper case hex", - type: "boolean", - value: Hexdump.UPPER_CASE - }, - { - name: "Include final length", - type: "boolean", - value: Hexdump.INCLUDE_FINAL_LENGTH - } - ] - }, - "From Base": { - module: "Default", - description: "Converts a number to decimal from a given numerical base.", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Radix", - type: "number", - value: Base.DEFAULT_RADIX - } - ] - }, - "To Base": { - module: "Default", - description: "Converts a decimal number to a given numerical base.", - inputType: "BigNumber", - outputType: "string", - args: [ - { - name: "Radix", - type: "number", - value: Base.DEFAULT_RADIX - } - ] - }, - "From HTML Entity": { - module: "Default", - description: "Converts HTML entities back to characters

e.g. &amp; becomes &", // tags required to stop the browser just printing & - inputType: "string", - outputType: "string", - args: [] - }, - "To HTML Entity": { - module: "Default", - description: "Converts characters to HTML entities

e.g. & becomes &amp;", // tags required to stop the browser just printing & - inputType: "string", - outputType: "string", - args: [ - { - name: "Convert all characters", - type: "boolean", - value: HTML.CONVERT_ALL - }, - { - name: "Convert to", - type: "option", - value: HTML.CONVERT_OPTIONS - } - ] - }, - "Strip HTML tags": { - module: "Default", - description: "Removes all HTML tags from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Remove indentation", - type: "boolean", - value: HTML.REMOVE_INDENTATION - }, - { - name: "Remove excess line breaks", - type: "boolean", - value: HTML.REMOVE_LINE_BREAKS - } - ] - }, - "URL Decode": { - module: "URL", - description: "Converts URI/URL percent-encoded characters back to their raw values.

e.g. %3d becomes =", - inputType: "string", - outputType: "string", - args: [] - }, - "URL Encode": { - module: "URL", - description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.

e.g. = becomes %3d", - inputType: "string", - outputType: "string", - args: [ - { - name: "Encode all special chars", - type: "boolean", - value: URL_.ENCODE_ALL - } - ] - }, - "Parse URI": { - module: "URL", - description: "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments.", - inputType: "string", - outputType: "string", - args: [] - }, - "Unescape Unicode Characters": { - module: "Default", - description: "Converts unicode-escaped character notation back into raw characters.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. \\u03c3\\u03bf\\u03c5 becomes σου", - inputType: "string", - outputType: "string", - args: [ - { - name: "Prefix", - type: "option", - value: Unicode.PREFIXES - } - ] - }, - "Escape Unicode Characters": { - module: "Default", - description: "Converts characters to their unicode-escaped notations.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. σου becomes \\u03C3\\u03BF\\u03C5", - inputType: "string", - outputType: "string", - args: [ - { - name: "Prefix", - type: "option", - value: Unicode.PREFIXES - }, - { - name: "Encode all chars", - type: "boolean", - value: false - }, - { - name: "Padding", - type: "number", - value: 4 - }, - { - name: "Uppercase hex", - type: "boolean", - value: true - } - ] - }, - "From Quoted Printable": { - module: "Default", - description: "Converts QP-encoded text back to standard text.", - inputType: "string", - outputType: "byteArray", - args: [] - }, - "To Quoted Printable": { - module: "Default", - description: "Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign '=') to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean. It is defined as a MIME content transfer encoding for use in e-mail.

QP works by using the equals sign '=' as an escape character. It also limits line length to 76, as some software has limits on line length.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "From Punycode": { - module: "Encodings", - description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. mnchen-3ya decodes to münchen", - inputType: "string", - outputType: "string", - args: [ - { - name: "Internationalised domain name", - type: "boolean", - value: Punycode.IDN - } - ] - }, - "To Punycode": { - module: "Encodings", - description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. münchen encodes to mnchen-3ya", - inputType: "string", - outputType: "string", - args: [ - { - name: "Internationalised domain name", - type: "boolean", - value: Punycode.IDN - } - ] - }, - "From Hex Content": { - module: "Default", - description: "Translates hexadecimal bytes in text back to raw bytes.

e.g. foo|3d|bar becomes foo=bar.", - inputType: "string", - outputType: "byteArray", - args: [] - }, - "To Hex Content": { - module: "Default", - description: "Converts special characters in a string to hexadecimal.

e.g. foo=bar becomes foo|3d|bar.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Convert", - type: "option", - value: ByteRepr.HEX_CONTENT_CONVERT_WHICH - }, - { - name: "Print spaces between bytes", - type: "boolean", - value: ByteRepr.HEX_CONTENT_SPACES_BETWEEN_BYTES - }, - ] - }, - "Change IP format": { - module: "JSBN", - description: "Convert an IP address from one format to another, e.g. 172.20.23.54 to ac141736", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input format", - type: "option", - value: IP.IP_FORMAT_LIST - }, - { - name: "Output format", - type: "option", - value: IP.IP_FORMAT_LIST - } - ] - }, - "Parse IP range": { - module: "JSBN", - description: "Given a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0), this operation provides network information and enumerates all IP addresses in the range.

IPv6 is supported but will not be enumerated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Include network info", - type: "boolean", - value: IP.INCLUDE_NETWORK_INFO - }, - { - name: "Enumerate IP addresses", - type: "boolean", - value: IP.ENUMERATE_ADDRESSES - }, - { - name: "Allow large queries", - type: "boolean", - value: IP.ALLOW_LARGE_LIST - } - ] - }, - "Group IP addresses": { - module: "JSBN", - description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: IP.DELIM_OPTIONS - }, - { - name: "Subnet (CIDR)", - type: "number", - value: IP.GROUP_CIDR - }, - { - name: "Only show the subnets", - type: "boolean", - value: IP.GROUP_ONLY_SUBNET - } - ] - }, - "Parse IPv6 address": { - module: "JSBN", - description: "Displays the longhand and shorthand versions of a valid IPv6 address.

Recognises all reserved ranges and parses encapsulated or tunnelled addresses including Teredo and 6to4.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse IPv4 header": { - module: "JSBN", - description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Input format", - type: "option", - value: IP.IP_HEADER_FORMAT - } - ] - }, - "Encode text": { - module: "CharEnc", - description: [ - "Encodes text into the chosen character encoding.", - "

", - "Supported charsets are:", - "
    ", - Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n"), - "
", - ].join("\n"), - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Encoding", - type: "option", - value: Object.keys(CharEnc.IO_FORMAT), - }, - ] - }, - "Decode text": { - module: "CharEnc", - description: [ - "Decodes text from the chosen character encoding.", - "

", - "Supported charsets are:", - "
    ", - Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n"), - "
", - ].join("\n"), - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Encoding", - type: "option", - value: Object.keys(CharEnc.IO_FORMAT), - }, - ] - }, - "AES Decrypt": { - module: "Ciphers", - description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256


IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.

GCM Tag: This field is ignored unless 'GCM' mode is used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.AES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT4 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "GCM Tag", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - ] - }, - "AES Encrypt": { - module: "Ciphers", - description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256
You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.AES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT4 - }, - ] - }, - "DES Decrypt": { - module: "Ciphers", - description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.DES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT4 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT3 - }, - ] - }, - "DES Encrypt": { - module: "Ciphers", - description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.DES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT4 - }, - ] - }, - "Triple DES Decrypt": { - module: "Ciphers", - description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.DES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT4 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT3 - }, - ] - }, - "Triple DES Encrypt": { - module: "Ciphers", - description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.DES_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT4 - }, - ] - }, - "Blowfish Decrypt": { - module: "Ciphers", - description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.BLOWFISH_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.BLOWFISH_OUTPUT_TYPES - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT3 - }, - ] - }, - "Blowfish Encrypt": { - module: "Ciphers", - description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Mode", - type: "option", - value: Cipher.BLOWFISH_MODES - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "Output", - type: "option", - value: Cipher.BLOWFISH_OUTPUT_TYPES - }, - ] - }, - "RC4": { - module: "Ciphers", - description: "RC4 (also known as ARC4) is a widely-used stream cipher designed by Ron Rivest. It is used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: Cipher.RC4_KEY_FORMAT - }, - { - name: "Input format", - type: "option", - value: Cipher.CJS_IO_FORMAT - }, - { - name: "Output format", - type: "option", - value: Cipher.CJS_IO_FORMAT - }, - ] - }, - "RC4 Drop": { - module: "Ciphers", - description: "It was discovered that the first few bytes of the RC4 keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: Cipher.RC4_KEY_FORMAT - }, - { - name: "Input format", - type: "option", - value: Cipher.CJS_IO_FORMAT - }, - { - name: "Output format", - type: "option", - value: Cipher.CJS_IO_FORMAT - }, - { - name: "Number of bytes to drop", - type: "number", - value: Cipher.RC4DROP_BYTES - }, - ] - }, - "RC2 Decrypt": { - module: "Ciphers", - description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT4 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT3 - }, - ] - }, - "RC2 Encrypt": { - module: "Ciphers", - description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

You can generate a password-based key using one of the KDF operations.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - { - name: "Input", - type: "option", - value: Cipher.IO_FORMAT3 - }, - { - name: "Output", - type: "option", - value: Cipher.IO_FORMAT4 - }, - ] - }, - "Pseudo-Random Number Generator": { - module: "Ciphers", - description: "A cryptographically-secure pseudo-random number generator (PRNG).

This operation uses the browser's built-in crypto.getRandomValues() method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Number of bytes", - type: "number", - value: Cipher.PRNG_BYTES - }, - { - name: "Output as", - type: "option", - value: Cipher.PRNG_OUTPUT - } - ] - }, - "Derive PBKDF2 key": { - module: "Ciphers", - description: "PBKDF2 is a password-based key derivation function. It is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's RFC 2898.

In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT2 - }, - { - name: "Key size", - type: "number", - value: Cipher.KDF_KEY_SIZE - }, - { - name: "Iterations", - type: "number", - value: Cipher.KDF_ITERATIONS - }, - { - name: "Hashing function", - type: "option", - value: Cipher.HASHERS - }, - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - ] - }, - "Derive EVP key": { - module: "Ciphers", - description: "EVP is a password-based key derivation function (PBKDF) used extensively in OpenSSL. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT2 - }, - { - name: "Key size", - type: "number", - value: Cipher.KDF_KEY_SIZE - }, - { - name: "Iterations", - type: "number", - value: Cipher.KDF_ITERATIONS - }, - { - name: "Hashing function", - type: "option", - value: Cipher.HASHERS - }, - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: Cipher.IO_FORMAT1 - }, - ] - }, - "Vigenère Encode": { - module: "Ciphers", - description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "Vigenère Decode": { - module: "Ciphers", - description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "Bifid Cipher Encode": { - module: "Ciphers", - description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Keyword", - type: "string", - value: "" - } - ] - }, - "Bifid Cipher Decode": { - module: "Ciphers", - description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Keyword", - type: "string", - value: "" - } - ] - }, - "Affine Cipher Encode": { - module: "Ciphers", - description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, (ax + b) % 26, and converted back to a letter.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "a", - type: "number", - value: Cipher.AFFINE_A - }, - { - name: "b", - type: "number", - value: Cipher.AFFINE_B - } - ] - }, - "Affine Cipher Decode": { - module: "Ciphers", - description: "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "a", - type: "number", - value: Cipher.AFFINE_A - }, - { - name: "b", - type: "number", - value: Cipher.AFFINE_B - } - ] - }, - "Atbash Cipher": { - module: "Ciphers", - description: "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [] - }, - "Rotate right": { - module: "Default", - description: "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: Rotate.ROTATE_AMOUNT - }, - { - name: "Carry through", - type: "boolean", - value: Rotate.ROTATE_CARRY - } - ] - }, - "Rotate left": { - module: "Default", - description: "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: Rotate.ROTATE_AMOUNT - }, - { - name: "Carry through", - type: "boolean", - value: Rotate.ROTATE_CARRY - } - ] - }, - "ROT13": { - module: "Default", - description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Rotate lower case chars", - type: "boolean", - value: Rotate.ROT13_LOWERCASE - }, - { - name: "Rotate upper case chars", - type: "boolean", - value: Rotate.ROT13_UPPERCASE - }, - { - name: "Amount", - type: "number", - value: Rotate.ROT13_AMOUNT - }, - ] - }, - "ROT47": { - module: "Default", - description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: Rotate.ROT47_AMOUNT - }, - ] - }, - "Strip HTTP headers": { - module: "HTTP", - description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse User Agent": { - module: "HTTP", - description: "Attempts to identify and categorise information contained in a user-agent string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Format MAC addresses": { - module: "Default", - description: "Displays given MAC addresses in multiple different formats.

Expects addresses in a list separated by newlines, spaces or commas.

WARNING: There are no validity checks.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output case", - type: "option", - value: MAC.OUTPUT_CASE - }, - { - name: "No delimiter", - type: "boolean", - value: MAC.NO_DELIM - }, - { - name: "Dash delimiter", - type: "boolean", - value: MAC.DASH_DELIM - }, - { - name: "Colon delimiter", - type: "boolean", - value: MAC.COLON_DELIM - }, - { - name: "Cisco style", - type: "boolean", - value: MAC.CISCO_STYLE - }, - { - name: "IPv6 interface ID", - type: "boolean", - value: MAC.IPV6_INTERFACE_ID - } - ] - }, - "Encode NetBIOS Name": { - module: "Default", - description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation carries out the first level of encoding. See RFC 1001 for full details.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Offset", - type: "number", - value: NetBIOS.OFFSET - } - ] - }, - "Decode NetBIOS Name": { - module: "Default", - description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation decodes the first level of encoding. See RFC 1001 for full details.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Offset", - type: "number", - value: NetBIOS.OFFSET - } - ] - }, - "Offset checker": { - module: "Default", - description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Sample delimiter", - type: "binaryString", - value: StrUtils.OFF_CHK_SAMPLE_DELIMITER - } - ] - }, - "Remove whitespace": { - module: "Default", - description: "Optionally removes all spaces, carriage returns, line feeds, tabs and form feeds from the input data.

This operation also supports the removal of full stops which are sometimes used to represent non-printable bytes in ASCII output.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Spaces", - type: "boolean", - value: Tidy.REMOVE_SPACES - }, - { - name: "Carriage returns (\\r)", - type: "boolean", - value: Tidy.REMOVE_CARIAGE_RETURNS - }, - { - name: "Line feeds (\\n)", - type: "boolean", - value: Tidy.REMOVE_LINE_FEEDS - }, - { - name: "Tabs", - type: "boolean", - value: Tidy.REMOVE_TABS - }, - { - name: "Form feeds (\\f)", - type: "boolean", - value: Tidy.REMOVE_FORM_FEEDS - }, - { - name: "Full stops", - type: "boolean", - value: Tidy.REMOVE_FULL_STOPS - } - ] - }, - "Remove null bytes": { - module: "Default", - description: "Removes all null bytes (0x00) from the input.", - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "Drop bytes": { - module: "Default", - description: "Cuts a slice of the specified number of bytes out of the data.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Start", - type: "number", - value: Tidy.DROP_START - }, - { - name: "Length", - type: "number", - value: Tidy.DROP_LENGTH - }, - { - name: "Apply to each line", - type: "boolean", - value: Tidy.APPLY_TO_EACH_LINE - } - ] - }, - "Take bytes": { - module: "Default", - description: "Takes a slice of the specified number of bytes from the data.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Start", - type: "number", - value: Tidy.TAKE_START - }, - { - name: "Length", - type: "number", - value: Tidy.TAKE_LENGTH - }, - { - name: "Apply to each line", - type: "boolean", - value: Tidy.APPLY_TO_EACH_LINE - } - ] - }, - "Pad lines": { - module: "Default", - description: "Add the specified number of the specified character to the beginning or end of each line", - inputType: "string", - outputType: "string", - args: [ - { - name: "Position", - type: "option", - value: Tidy.PAD_POSITION - }, - { - name: "Length", - type: "number", - value: Tidy.PAD_LENGTH - }, - { - name: "Character", - type: "binaryShortString", - value: Tidy.PAD_CHAR - } - ] - }, - "Reverse": { - module: "Default", - description: "Reverses the input string.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "By", - type: "option", - value: SeqUtils.REVERSE_BY - } - ] - }, - "Sort": { - module: "Default", - description: "Alphabetically sorts strings separated by the specified delimiter.

The IP address option supports IPv4 only.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: SeqUtils.DELIMITER_OPTIONS - }, - { - name: "Reverse", - type: "boolean", - value: SeqUtils.SORT_REVERSE - }, - { - name: "Order", - type: "option", - value: SeqUtils.SORT_ORDER - } - ] - }, - "Unique": { - module: "Default", - description: "Removes duplicate strings from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: SeqUtils.DELIMITER_OPTIONS - } - ] - }, - "Count occurrences": { - module: "Default", - description: "Counts the number of times the provided string occurs in the input.", - inputType: "string", - outputType: "number", - args: [ - { - name: "Search string", - type: "toggleString", - value: "", - toggleValues: SeqUtils.SEARCH_TYPE - } - ] - }, - "Add line numbers": { - module: "Default", - description: "Adds line numbers to the output.", - inputType: "string", - outputType: "string", - args: [] - }, - "Remove line numbers": { - module: "Default", - description: "Removes line numbers from the output if they can be trivially detected.", - inputType: "string", - outputType: "string", - args: [] - }, - "Find / Replace": { - module: "Regex", - description: "Replaces all occurrences of the first string with the second.

Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Find", - type: "toggleString", - value: "", - toggleValues: Regex.SEARCH_TYPE - }, - { - name: "Replace", - type: "binaryString", - value: "" - }, - { - name: "Global match", - type: "boolean", - value: Regex.FIND_REPLACE_GLOBAL, - }, - { - name: "Case insensitive", - type: "boolean", - value: Regex.FIND_REPLACE_CASE, - }, - { - name: "Multiline matching", - type: "boolean", - value: Regex.FIND_REPLACE_MULTILINE, - }, - - ] - }, - "To Upper case": { - module: "Default", - description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Scope", - type: "option", - value: StrUtils.CASE_SCOPE - } - ] - }, - "To Lower case": { - module: "Default", - description: "Converts every character in the input to lower case.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [] - }, - "Split": { - module: "Default", - description: "Splits a string into sections around a given delimiter.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Split delimiter", - type: "editableOption", - value: StrUtils.SPLIT_DELIM_OPTIONS - }, - { - name: "Join delimiter", - type: "editableOption", - value: StrUtils.JOIN_DELIM_OPTIONS - } - ] - }, - "Filter": { - module: "Default", - description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: StrUtils.DELIMITER_OPTIONS - }, - { - name: "Regex", - type: "string", - value: "" - }, - { - name: "Invert condition", - type: "boolean", - value: false - }, - ] - }, - "Strings": { - module: "Regex", - description: "Extracts all strings from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Encoding", - type: "option", - value: Extract.ENCODING_LIST - }, - { - name: "Minimum length", - type: "number", - value: Extract.MIN_STRING_LEN - }, - { - name: "Match", - type: "option", - value: Extract.STRING_MATCH_TYPE - }, - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract IP addresses": { - module: "Regex", - description: "Extracts all IPv4 and IPv6 addresses.

Warning: Given a string 710.65.0.456, this will match 10.65.0.45 so always check the original input!", - inputType: "string", - outputType: "string", - args: [ - { - name: "IPv4", - type: "boolean", - value: Extract.INCLUDE_IPV4 - }, - { - name: "IPv6", - type: "boolean", - value: Extract.INCLUDE_IPV6 - }, - { - name: "Remove local IPv4 addresses", - type: "boolean", - value: Extract.REMOVE_LOCAL - }, - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract email addresses": { - module: "Regex", - description: "Extracts all email addresses from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract MAC addresses": { - module: "Regex", - description: "Extracts all Media Access Control (MAC) addresses from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract URLs": { - module: "Regex", - description: "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract domains": { - module: "Regex", - description: "Extracts domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract file paths": { - module: "Regex", - description: "Extracts anything that looks like a Windows or UNIX file path.

Note that if UNIX is selected, there will likely be a lot of false positives.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Windows", - type: "boolean", - value: Extract.INCLUDE_WIN_PATH - }, - { - name: "UNIX", - type: "boolean", - value: Extract.INCLUDE_UNIX_PATH - }, - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Extract dates": { - module: "Regex", - description: "Extracts dates in the following formats
  • yyyy-mm-dd
  • dd/mm/yyyy
  • mm/dd/yyyy
Dividers can be any of /, -, . or space", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: Extract.DISPLAY_TOTAL - } - ] - }, - "Regular expression": { - module: "Regex", - description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.

Supports extended regex syntax including the 'dot matches all' flag, named capture groups, full unicode coverage (including \\p{} categories and scripts as well as astral codes) and recursive matching.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in regexes", - type: "populateOption", - value: Regex.REGEX_PRE_POPULATE, - target: 1, - }, - { - name: "Regex", - type: "text", - value: "" - }, - { - name: "Case insensitive", - type: "boolean", - value: true - }, - { - name: "^ and $ match at newlines", - type: "boolean", - value: true - }, - { - name: "Dot matches all", - type: "boolean", - value: false - }, - { - name: "Unicode support", - type: "boolean", - value: false - }, - { - name: "Astral support", - type: "boolean", - value: false - }, - { - name: "Display total", - type: "boolean", - value: Regex.DISPLAY_TOTAL - }, - { - name: "Output format", - type: "option", - value: Regex.OUTPUT_FORMAT - }, - ] - }, - "XPath expression": { - module: "Code", - description: "Extract information from an XML document with an XPath query", - inputType: "string", - outputType: "string", - args: [ - { - name: "XPath", - type: "string", - value: Code.XPATH_INITIAL - }, - { - name: "Result delimiter", - type: "binaryShortString", - value: Code.XPATH_DELIMITER - } - ] - }, - "JPath expression": { - module: "Code", - description: "Extract information from a JSON object with a JPath query.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Query", - type: "string", - value: Code.JPATH_INITIAL - }, - { - name: "Result delimiter", - type: "binaryShortString", - value: Code.JPATH_DELIMITER - } - ] - }, - "CSS selector": { - module: "Code", - description: "Extract information from an HTML document with a CSS selector", - inputType: "string", - outputType: "string", - args: [ - { - name: "CSS selector", - type: "string", - value: Code.CSS_SELECTOR_INITIAL - }, - { - name: "Delimiter", - type: "binaryShortString", - value: Code.CSS_QUERY_DELIMITER - }, - ] - }, - "From UNIX Timestamp": { - module: "Default", - description: "Converts a UNIX timestamp to a datetime string.

e.g. 978346800 becomes Mon 1 January 2001 11:00:00 UTC

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", - inputType: "number", - outputType: "string", - args: [ - { - name: "Units", - type: "option", - value: DateTime.UNITS - } - ] - }, - "To UNIX Timestamp": { - module: "Default", - description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.

e.g. Mon 1 January 2001 11:00:00 becomes 978346800

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Units", - type: "option", - value: DateTime.UNITS - }, - { - name: "Treat as UTC", - type: "boolean", - value: DateTime.TREAT_AS_UTC - }, - { - name: "Show parsed datetime", - type: "boolean", - value: true - } - ] - }, - "Sleep": { - module: "Default", - description: "Sleep causes the recipe to wait for a specified number of milliseconds before continuing execution.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Time (ms)", - type: "number", - value: 1000 - } - ] - }, - "Windows Filetime to UNIX Timestamp": { - module: "Default", - description: "Converts a Windows Filetime value to a UNIX timestamp.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output units", - type: "option", - value: Filetime.UNITS - }, - { - name: "Input format", - type: "option", - value: Filetime.FILETIME_FORMATS - } - ] - }, - "UNIX Timestamp to Windows Filetime": { - module: "Default", - description: "Converts a UNIX timestamp to a Windows Filetime value.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input units", - type: "option", - value: Filetime.UNITS - }, - { - name: "Output format", - type: "option", - value: Filetime.FILETIME_FORMATS - } - ] - }, - "Translate DateTime Format": { - module: "Default", - description: "Parses a datetime string in one format and re-writes it in another.

Run with no input to see the relevant format string examples.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in formats", - type: "populateOption", - value: DateTime.DATETIME_FORMATS, - target: 1 - }, - { - name: "Input format string", - type: "binaryString", - value: DateTime.INPUT_FORMAT_STRING - }, - { - name: "Input timezone", - type: "option", - value: DateTime.TIMEZONES - }, - { - name: "Output format string", - type: "binaryString", - value: DateTime.OUTPUT_FORMAT_STRING - }, - { - name: "Output timezone", - type: "option", - value: DateTime.TIMEZONES - } - ] - }, - "Parse DateTime": { - module: "Default", - description: "Parses a DateTime string in your specified format and displays it in whichever timezone you choose with the following information:
  • Date
  • Time
  • Period (AM/PM)
  • Timezone
  • UTC offset
  • Daylight Saving Time
  • Leap year
  • Days in this month
  • Day of year
  • Week number
  • Quarter
Run with no input to see format string examples if required.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in formats", - type: "populateOption", - value: DateTime.DATETIME_FORMATS, - target: 1 - }, - { - name: "Input format string", - type: "binaryString", - value: DateTime.INPUT_FORMAT_STRING - }, - { - name: "Input timezone", - type: "option", - value: DateTime.TIMEZONES - }, - ] - }, - "Convert distance": { - module: "Default", - description: "Converts a unit of distance to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: Convert.DISTANCE_UNITS - }, - { - name: "Output units", - type: "option", - value: Convert.DISTANCE_UNITS - } - ] - }, - "Convert area": { - module: "Default", - description: "Converts a unit of area to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: Convert.AREA_UNITS - }, - { - name: "Output units", - type: "option", - value: Convert.AREA_UNITS - } - ] - }, - "Convert mass": { - module: "Default", - description: "Converts a unit of mass to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: Convert.MASS_UNITS - }, - { - name: "Output units", - type: "option", - value: Convert.MASS_UNITS - } - ] - }, - "Convert speed": { - module: "Default", - description: "Converts a unit of speed to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: Convert.SPEED_UNITS - }, - { - name: "Output units", - type: "option", - value: Convert.SPEED_UNITS - } - ] - }, - "Convert data units": { - module: "Default", - description: "Converts a unit of data to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: Convert.DATA_UNITS - }, - { - name: "Output units", - type: "option", - value: Convert.DATA_UNITS - } - ] - }, - "Raw Deflate": { - module: "Compression", - description: "Compresses data using the deflate algorithm with no headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: Compress.COMPRESSION_TYPE - } - ] - }, - "Raw Inflate": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with no headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Start index", - type: "number", - value: Compress.INFLATE_INDEX - }, - { - name: "Initial output buffer size", - type: "number", - value: Compress.INFLATE_BUFFER_SIZE - }, - { - name: "Buffer expansion type", - type: "option", - value: Compress.INFLATE_BUFFER_TYPE - }, - { - name: "Resize buffer after decompression", - type: "boolean", - value: Compress.INFLATE_RESIZE - }, - { - name: "Verify result", - type: "boolean", - value: Compress.INFLATE_VERIFY - } - ] - }, - "Zlib Deflate": { - module: "Compression", - description: "Compresses data using the deflate algorithm adding zlib headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: Compress.COMPRESSION_TYPE - } - ] - }, - "Zlib Inflate": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Start index", - type: "number", - value: Compress.INFLATE_INDEX - }, - { - name: "Initial output buffer size", - type: "number", - value: Compress.INFLATE_BUFFER_SIZE - }, - { - name: "Buffer expansion type", - type: "option", - value: Compress.INFLATE_BUFFER_TYPE - }, - { - name: "Resize buffer after decompression", - type: "boolean", - value: Compress.INFLATE_RESIZE - }, - { - name: "Verify result", - type: "boolean", - value: Compress.INFLATE_VERIFY - } - ] - }, - "Gzip": { - module: "Compression", - description: "Compresses data using the deflate algorithm with gzip headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: Compress.COMPRESSION_TYPE - }, - { - name: "Filename (optional)", - type: "string", - value: "" - }, - { - name: "Comment (optional)", - type: "string", - value: "" - }, - { - name: "Include file checksum", - type: "boolean", - value: Compress.GZIP_CHECKSUM - } - ] - }, - "Gunzip": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "Zip": { - module: "Compression", - description: "Compresses data using the PKZIP algorithm with the given filename.

No support for multiple files at this time.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Filename", - type: "string", - value: Compress.PKZIP_FILENAME - }, - { - name: "Comment", - type: "string", - value: "" - }, - { - name: "Password", - type: "binaryString", - value: "" - }, - { - name: "Compression method", - type: "option", - value: Compress.COMPRESSION_METHOD - }, - { - name: "Operating system", - type: "option", - value: Compress.OS - }, - { - name: "Compression type", - type: "option", - value: Compress.COMPRESSION_TYPE - } - ] - }, - "Unzip": { - module: "Compression", - description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Password", - type: "binaryString", - value: "" - }, - { - name: "Verify result", - type: "boolean", - value: Compress.PKUNZIP_VERIFY - } - ] - }, - "Bzip2 Decompress": { - module: "Compression", - description: "Decompresses data using the Bzip2 algorithm.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Generic Code Beautify": { - module: "Code", - description: "Attempts to pretty print C-style languages such as C, C++, C#, Java, PHP, JavaScript etc.

This will not do a perfect job, and the resulting code may not work any more. This operation is designed purely to make obfuscated or minified code more easy to read and understand.

Things which will not work properly:
  • For loop formatting
  • Do-While loop formatting
  • Switch/Case indentation
  • Certain bit shift operators
", - inputType: "string", - outputType: "string", - args: [] - }, - "JavaScript Parser": { - module: "Code", - description: "Returns an Abstract Syntax Tree for valid JavaScript code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Location info", - type: "boolean", - value: JS.PARSE_LOC - }, - { - name: "Range info", - type: "boolean", - value: JS.PARSE_RANGE - }, - { - name: "Include tokens array", - type: "boolean", - value: JS.PARSE_TOKENS - }, - { - name: "Include comments array", - type: "boolean", - value: JS.PARSE_COMMENT - }, - { - name: "Report errors and try to continue", - type: "boolean", - value: JS.PARSE_TOLERANT - }, - ] - }, - "JavaScript Beautify": { - module: "Code", - description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: JS.BEAUTIFY_INDENT - }, - { - name: "Quotes", - type: "option", - value: JS.BEAUTIFY_QUOTES - }, - { - name: "Semicolons before closing braces", - type: "boolean", - value: JS.BEAUTIFY_SEMICOLONS - }, - { - name: "Include comments", - type: "boolean", - value: JS.BEAUTIFY_COMMENT - }, - ] - }, - "JavaScript Minify": { - module: "Code", - description: "Compresses JavaScript code.", - inputType: "string", - outputType: "string", - args: [] - }, - "XML Beautify": { - module: "Code", - description: "Indents and prettifies eXtensible Markup Language (XML) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: Code.BEAUTIFY_INDENT - } - ] - }, - "JSON Beautify": { - module: "Code", - description: "Indents and prettifies JavaScript Object Notation (JSON) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: Code.BEAUTIFY_INDENT - } - ] - }, - "CSS Beautify": { - module: "Code", - description: "Indents and prettifies Cascading Style Sheets (CSS) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: Code.BEAUTIFY_INDENT - } - ] - }, - "SQL Beautify": { - module: "Code", - description: "Indents and prettifies Structured Query Language (SQL) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: Code.BEAUTIFY_INDENT - } - ] - }, - "XML Minify": { - module: "Code", - description: "Compresses eXtensible Markup Language (XML) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Preserve comments", - type: "boolean", - value: Code.PRESERVE_COMMENTS - } - ] - }, - "JSON Minify": { - module: "Code", - description: "Compresses JavaScript Object Notation (JSON) code.", - inputType: "string", - outputType: "string", - args: [] - }, - "CSS Minify": { - module: "Code", - description: "Compresses Cascading Style Sheets (CSS) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Preserve comments", - type: "boolean", - value: Code.PRESERVE_COMMENTS - } - ] - }, - "SQL Minify": { - module: "Code", - description: "Compresses Structured Query Language (SQL) code.", - inputType: "string", - outputType: "string", - args: [] - }, - "Analyse hash": { - module: "Hashing", - description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.", - inputType: "string", - outputType: "string", - args: [] - }, - "MD2": { - module: "Hashing", - description: "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.

Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD4": { - module: "Hashing", - description: "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.

The security of MD4 has been severely compromised.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD5": { - module: "Hashing", - description: "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.

However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD6": { - module: "Hashing", - description: "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Size", - type: "number", - value: Hash.MD6_SIZE - }, - { - name: "Levels", - type: "number", - value: Hash.MD6_LEVELS - }, - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "SHA0": { - module: "Hashing", - description: "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "SHA1": { - module: "Hashing", - description: "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.

However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "SHA2": { - module: "Hashing", - description: "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.

  • SHA-512 operates on 64-bit words.
  • SHA-256 operates on 32-bit words.
  • SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.
  • SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.
  • SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.
", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: Hash.SHA2_SIZE - } - ] - }, - "SHA3": { - module: "Hashing", - description: "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.

SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: Hash.SHA3_SIZE - } - ] - }, - "Keccak": { - module: "Hashing", - description: "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún. It was selected as the winner of the SHA-3 design competition.

This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: Hash.KECCAK_SIZE - } - ] - }, - "Shake": { - module: "Hashing", - description: "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Capacity", - type: "option", - value: Hash.SHAKE_CAPACITY - }, - { - name: "Size", - type: "number", - value: Hash.SHAKE_SIZE - } - ] - - }, - "RIPEMD": { - module: "Hashing", - description: "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.

RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.

", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: Hash.RIPEMD_SIZE - } - ] - }, - "HAS-160": { - module: "Hashing", - description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.

HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.

The message digest algorithm consists of 80 rounds.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Whirlpool": { - module: "Hashing", - description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.

Several variants exist:
  • Whirlpool-0 is the original version released in 2000.
  • Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.
  • Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.
", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Variant", - type: "option", - value: Hash.WHIRLPOOL_VARIANT - } - ] - }, - "Snefru": { - module: "Hashing", - description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.

The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Rounds", - type: "option", - value: Hash.SNEFRU_ROUNDS - }, - { - name: "Size", - type: "option", - value: Hash.SNEFRU_SIZE - } - ] - }, - "SSDEEP": { - module: "Hashing", - description: "SSDEEP is a program for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

SSDEEP hashes are now widely used for simple identification purposes (e.g. the 'Basic Properties' section in VirusTotal). Although 'better' fuzzy hashes are available, SSDEEP is still one of the primary choices because of its speed and being a de facto standard.

This operation is fundamentally the same as the CTPH operation, however their outputs differ in format.", - inputType: "string", - outputType: "string", - args: [] - }, - "CTPH": { - module: "Hashing", - description: "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'.", - inputType: "string", - outputType: "string", - args: [] - }, - "Compare SSDEEP hashes": { - module: "Hashing", - description: "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", - inputType: "string", - outputType: "Number", - args: [ - { - name: "Delimiter", - type: "option", - value: Hash.DELIM_OPTIONS - } - ] - }, - "Compare CTPH hashes": { - module: "Hashing", - description: "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", - inputType: "string", - outputType: "Number", - args: [ - { - name: "Delimiter", - type: "option", - value: Hash.DELIM_OPTIONS - } - ] - }, - "HMAC": { - module: "Hashing", - description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Key", - type: "binaryString", - value: "" - }, - { - name: "Hashing function", - type: "option", - value: Hash.HMAC_FUNCTIONS - }, - ] - }, - "Fletcher-8 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-16 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-32 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-64 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Adler-32 Checksum": { - module: "Hashing", - description: "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).

Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "CRC-32 Checksum": { - module: "Hashing", - description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.", - inputType: "string", - outputType: "string", - args: [] - }, - "CRC-16 Checksum": { - module: "Hashing", - description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961.", - inputType: "string", - outputType: "string", - args: [] - }, - "Generate all hashes": { - module: "Hashing", - description: "Generates all available hashes and checksums for the input.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Entropy": { - module: "Default", - description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Chunk size", - type: "number", - value: Entropy.CHUNK_SIZE - } - ] - }, - "Frequency distribution": { - module: "Default", - description: "Displays the distribution of bytes in the data as a graph.", - inputType: "ArrayBuffer", - outputType: "html", - args: [ - { - name: "Show 0%'s", - type: "boolean", - value: Entropy.FREQ_ZEROS - } - ] - }, - "Chi Square": { - module: "Default", - description: "Calculates the Chi Square distribution of values.", - inputType: "ArrayBuffer", - outputType: "number", - args: [] - }, - "Numberwang": { - module: "Default", - description: "Based on the popular gameshow by Mitchell and Webb.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse X.509 certificate": { - module: "PublicKey", - description: "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.

This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input format", - type: "option", - value: PublicKey.X509_INPUT_FORMAT - } - ] - }, - "PEM to Hex": { - module: "PublicKey", - description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Hex to PEM": { - module: "PublicKey", - description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Header string", - type: "string", - value: PublicKey.PEM_HEADER_STRING - } - ] - }, - "Hex to Object Identifier": { - module: "PublicKey", - description: "Converts a hexadecimal string into an object identifier (OID).", - inputType: "string", - outputType: "string", - args: [] - }, - "Object Identifier to Hex": { - module: "PublicKey", - description: "Converts an object identifier (OID) into a hexadecimal string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse ASN.1 hex string": { - module: "PublicKey", - description: "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.

This operation parses arbitrary ASN.1 data and presents the resulting tree.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Starting index", - type: "number", - value: 0 - }, - { - name: "Truncate octet strings longer than", - type: "number", - value: PublicKey.ASN1_TRUNCATE_LENGTH - } - ] - }, - "Detect File Type": { - module: "Default", - description: "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.

Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Scan for Embedded Files": { - module: "Default", - description: "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.

WARNING: Files over about 100KB in size will take a VERY long time to process.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Ignore common byte sequences", - type: "boolean", - value: FileType.IGNORE_COMMON_BYTE_SEQUENCES - } - ] - }, - "Expand alphabet range": { - module: "Default", - description: "Expand an alphabet range string into a list of the characters in that range.

e.g. a-z becomes abcdefghijklmnopqrstuvwxyz.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "binaryString", - value: "" - } - ] - }, - "Diff": { - module: "Diff", - description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Sample delimiter", - type: "binaryString", - value: Diff.DIFF_SAMPLE_DELIMITER - }, - { - name: "Diff by", - type: "option", - value: Diff.DIFF_BY - }, - { - name: "Show added", - type: "boolean", - value: true - }, - { - name: "Show removed", - type: "boolean", - value: true - }, - { - name: "Ignore whitespace (relevant for word and line)", - type: "boolean", - value: false - } - ] - }, - "Parse UNIX file permissions": { - module: "Default", - description: "Given a UNIX/Linux file permission string in octal or textual format, this operation explains which permissions are granted to which user groups.

Input should be in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.", - inputType: "string", - outputType: "string", - args: [] - }, - "Swap endianness": { - module: "Default", - description: "Switches the data from big-endian to little-endian or vice-versa. Data can be read in as hexadecimal or raw bytes. It will be returned in the same format as it is entered.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Data format", - type: "option", - value: Endian.DATA_FORMAT - }, - { - name: "Word length (bytes)", - type: "number", - value: Endian.WORD_LENGTH - }, - { - name: "Pad incomplete words", - type: "boolean", - value: Endian.PAD_INCOMPLETE_WORDS - } - ] - }, - "Microsoft Script Decoder": { - module: "Default", - description: "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.

Sample

Encoded:
#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&@*eEI@#@&@#@&.jm.raY 214Wv:zms/obI0xEAAA==^#~@

Decoded:
var my_msg = "Testing <1><2><3>!";\n\nVScript.Echo(my_msg);", - inputType: "string", - outputType: "string", - args: [] - }, - "Syntax highlighter": { - module: "Code", - description: "Adds syntax highlighting to a range of source code languages. Note that this will not indent the code. Use one of the 'Beautify' operations for that.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "html", - args: [ - { - name: "Language", - type: "option", - value: Code.LANGUAGES - }, - ] - }, - "TCP/IP Checksum": { - module: "Hashing", - description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Parse colour code": { - module: "Default", - description: "Converts a colour code in a standard format to other standard formats and displays the colour itself.

Example inputs
  • #d9edf7
  • rgba(217,237,247,1)
  • hsla(200,65%,91%,1)
  • cmyk(0.12, 0.04, 0.00, 0.03)
", - inputType: "string", - outputType: "html", - args: [] - }, - "Generate UUID": { - module: "Default", - description: "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).

A version 4 UUID relies on random numbers, in this case generated using window.crypto if available and falling back to Math.random if not.", - inputType: "string", - outputType: "string", - args: [] - }, - "Substitute": { - module: "Ciphers", - description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.

Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.

Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either \\n or \\x0a.

Byte ranges can be specified using a hyphen. For example, the sequence 0123456789 can be written as 0-9.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Plaintext", - type: "binaryString", - value: Cipher.SUBS_PLAINTEXT - }, - { - name: "Ciphertext", - type: "binaryString", - value: Cipher.SUBS_CIPHERTEXT - } - ] - }, - "Escape string": { - module: "Default", - description: "Escapes special characters in a string so that they do not cause conflicts. For example, Don't stop me now becomes Don\\'t stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", - inputType: "string", - outputType: "string", - args: [ - { - name: "Escape level", - type: "option", - value: StrUtils.ESCAPE_LEVEL - }, - { - name: "Escape quote", - type: "option", - value: StrUtils.QUOTE_TYPES - }, - { - name: "JSON compatible", - type: "boolean", - value: false - }, - { - name: "ES6 compatible", - type: "boolean", - value: true - }, - { - name: "Uppercase hex", - type: "boolean", - value: false - } - ] - }, - "Unescape string": { - module: "Default", - description: "Unescapes characters in a string that have been escaped. For example, Don\\'t stop me now becomes Don't stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", - inputType: "string", - outputType: "string", - args: [] - }, - "To Morse Code": { - module: "Default", - description: "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ...", - inputType: "string", - outputType: "string", - args: [ - { - name: "Format options", - type: "option", - value: MorseCode.FORMAT_OPTIONS - }, - { - name: "Letter delimiter", - type: "option", - value: MorseCode.LETTER_DELIM_OPTIONS - }, - { - name: "Word delimiter", - type: "option", - value: MorseCode.WORD_DELIM_OPTIONS - } - ] - }, - "From Morse Code": { - module: "Default", - description: "Translates Morse Code into (upper case) alphanumeric characters.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Letter delimiter", - type: "option", - value: MorseCode.LETTER_DELIM_OPTIONS - }, - { - name: "Word delimiter", - type: "option", - value: MorseCode.WORD_DELIM_OPTIONS - } - ] - }, - "Tar": { - module: "Compression", - description: "Packs the input into a tarball.

No support for multiple files at this time.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Filename", - type: "string", - value: Compress.TAR_FILENAME - } - ] - }, - "Untar": { - module: "Compression", - description: "Unpacks a tarball and displays it per file.", - inputType: "byteArray", - outputType: "html", - args: [ - ] - }, - "Head": { - module: "Default", - description: [ - "Like the UNIX head utility.", - "
", - "Gets the first n lines.", - "
", - "You can select all but the last n lines by entering a negative value for n.", - "
", - "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: StrUtils.DELIMITER_OPTIONS - }, - { - name: "Number", - type: "number", - value: 10, - }, - ] - }, - "Tail": { - module: "Default", - description: [ - "Like the UNIX tail utility.", - "
", - "Gets the last n lines.", - "
", - "Optionally you can select all lines after line n by entering a negative value for n.", - "
", - "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: StrUtils.DELIMITER_OPTIONS - }, - { - name: "Number", - type: "number", - value: 10, - }, - ] - }, - "To Snake case": { - module: "Code", - description: [ - "Converts the input string to snake case.", - "

", - "Snake case is all lower case with underscores as word boundaries.", - "

", - "e.g. this_is_snake_case", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "To Camel case": { - module: "Code", - description: [ - "Converts the input string to camel case.", - "

", - "Camel case is all lower case except letters after word boundaries which are uppercase.", - "

", - "e.g. thisIsCamelCase", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "To Kebab case": { - module: "Code", - description: [ - "Converts the input string to kebab case.", - "

", - "Kebab case is all lower case with dashes as word boundaries.", - "

", - "e.g. this-is-kebab-case", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "Extract EXIF": { - module: "Image", - description: [ - "Extracts EXIF data from an image.", - "

", - "EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.", - "

", - "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.", - ].join("\n"), - inputType: "ArrayBuffer", - outputType: "string", - args: [], - }, - "Render Image": { - module: "Image", - description: "Displays the input as an image. Supports the following formats:

  • jpg/jpeg
  • png
  • gif
  • webp
  • bmp
  • ico
", - inputType: "string", - outputType: "html", - args: [ - { - name: "Input format", - type: "option", - value: Image.INPUT_FORMAT - } - ] - }, - "Remove EXIF": { - module: "Image", - description: [ - "Removes EXIF data from a JPEG image.", - "

", - "EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.", - ].join("\n"), - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "HTTP request": { - module: "HTTP", - description: [ - "Makes an HTTP request and returns the response.", - "

", - "This operation supports different HTTP verbs like GET, POST, PUT, etc.", - "

", - "You can add headers line by line in the format Key: Value", - "

", - "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.", - ].join("\n"), - inputType: "string", - outputType: "string", - manualBake: true, - args: [ - { - name: "Method", - type: "option", - value: HTTP.METHODS, - }, - { - name: "URL", - type: "string", - value: "", - }, - { - name: "Headers", - type: "text", - value: "", - }, - { - name: "Mode", - type: "option", - value: HTTP.MODE, - }, - { - name: "Show response metadata", - type: "boolean", - value: false, - } - ] - }, - "From BCD": { - module: "Default", - description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Scheme", - type: "option", - value: BCD.ENCODING_SCHEME - }, - { - name: "Packed", - type: "boolean", - value: true - }, - { - name: "Signed", - type: "boolean", - value: false - }, - { - name: "Input format", - type: "option", - value: BCD.FORMAT - } - ] - - }, - "To BCD": { - module: "Default", - description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign", - inputType: "BigNumber", - outputType: "string", - args: [ - { - name: "Scheme", - type: "option", - value: BCD.ENCODING_SCHEME - }, - { - name: "Packed", - type: "boolean", - value: true - }, - { - name: "Signed", - type: "boolean", - value: false - }, - { - name: "Output format", - type: "option", - value: BCD.FORMAT - } - ] - - }, - "Bit shift left": { - module: "Default", - description: "Shifts the bits in each byte towards the left by the specified amount.", - inputType: "byteArray", - outputType: "byteArray", - highlight: true, - highlightReverse: true, - args: [ - { - name: "Amount", - type: "number", - value: 1 - }, - ] - }, - "Bit shift right": { - module: "Default", - description: "Shifts the bits in each byte towards the right by the specified amount.

Logical shifts replace the leftmost bits with zeros.
Arithmetic shifts preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative).", - inputType: "byteArray", - outputType: "byteArray", - highlight: true, - highlightReverse: true, - args: [ - { - name: "Amount", - type: "number", - value: 1 - }, - { - name: "Type", - type: "option", - value: BitwiseOp.BIT_SHIFT_TYPE - } - ] - }, - "Generate TOTP": { - module: "Default", - description: "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Name", - type: "string", - value: "" - }, - { - name: "Key size", - type: "number", - value: 32 - }, - { - name: "Code length", - type: "number", - value: 6 - }, - { - name: "Epoch offset (T0)", - type: "number", - value: 0 - }, - { - name: "Interval (T1)", - type: "number", - value: 30 - } - ] - }, - "Generate HOTP": { - module: "Default", - description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Name", - type: "string", - value: "" - }, - { - name: "Key size", - type: "number", - value: 32 - }, - { - name: "Code length", - type: "number", - value: 6 - }, - { - name: "Counter", - type: "number", - value: 0 - } - ] - }, - "PHP Deserialize": { - module: "Default", - description: "Deserializes PHP serialized data, outputting keyed arrays as JSON.

This function does not support object tags.

Example:
a:2:{s:1:"a";i:10;i:0;a:1:{s:2:"ab";b:1;}}
becomes
{"a": 10,0: {"ab": true}}

Output valid JSON: JSON doesn't support integers as keys, whereas PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output valid JSON", - type: "boolean", - value: PHP.OUTPUT_VALID_JSON - } - ] - }, - "Hamming Distance": { - module: "Default", - description: "In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other. In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "binaryShortString", - value: StrUtils.HAMMING_DELIM - }, - { - name: "Unit", - type: "option", - value: StrUtils.HAMMING_UNIT - }, - { - name: "Input type", - type: "option", - value: StrUtils.HAMMING_INPUT_TYPE - } - ] - }, - "XKCD Random Number": { - module: "Default", - description: "RFC 1149.5 specifies 4 as the standard IEEE-vetted random number.

XKCD #221", - inputType: "string", - outputType: "number", - args: [] - }, - "Bcrypt": { - module: "Hashing", - description: "bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

Enter the password in the input to generate its hash.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Rounds", - type: "number", - value: Hash.BCRYPT_ROUNDS - } - ] - }, - "Bcrypt compare": { - module: "Hashing", - description: "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Hash", - type: "string", - value: "" - } - ] - }, - "Bcrypt parse": { - module: "Hashing", - description: "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash.", - inputType: "string", - outputType: "string", - args: [] - }, - "Scrypt": { - module: "Hashing", - description: "scrypt is a password-based key derivation function (PBKDF) created by Colin Percival. The algorithm was specifically designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory. In 2016, the scrypt algorithm was published by IETF as RFC 7914.

Enter the password in the input to generate its hash.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: Hash.KEY_FORMAT - }, - { - name: "Iterations (N)", - type: "number", - value: Hash.SCRYPT_ITERATIONS - }, - { - name: "Memory factor (r)", - type: "number", - value: Hash.SCRYPT_MEM_FACTOR - }, - { - name: "Parallelization factor (p)", - type: "number", - value: Hash.SCRYPT_PARALLEL_FACTOR - }, - { - name: "Key length", - type: "number", - value: Hash.SCRYPT_KEY_LENGTH - }, - ] - }, - "BSON serialise": { - module: "BSON", - description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be valid JSON.", - inputType: "string", - outputType: "ArrayBuffer", - args: [] - }, - "BSON deserialise": { - module: "BSON", - description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be in a raw bytes format.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, -}; -*/ - - -// /** -// * Exports the OperationConfig JSON object in val-loader format so that it can be loaded -// * into the app without also importing all the dependencies. -// * -// * See https://github.com/webpack-contrib/val-loader -// * -// * @returns {Object} -// */ -// function valExport() { -// return { -// code: "module.exports = " + JSON.stringify(OperationConfig) + ";" -// }; -// } - -// export default valExport; - -// export {operations}; diff --git a/src/core/config/scripts/portOperation.mjs b/src/core/config/scripts/portOperation.mjs new file mode 100644 index 00000000..cac7b1eb --- /dev/null +++ b/src/core/config/scripts/portOperation.mjs @@ -0,0 +1,4815 @@ +/** + * Given an existing operation name, this script generates a skeleton for that op + * in the new ESM format. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +/*eslint no-console: ["off"] */ + +import process from "process"; +import fs from "fs"; +import path from "path"; +import EscapeString from "../../operations/EscapeString"; + +if (process.argv.length < 4) { + console.log("Pass an operation name and legacy filename as arguments."); + console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs 'XOR' 'BitwiseOp'"); + process.exit(0); +} + +const dir = path.join(process.cwd() + "/src/core/config/"); +if (!fs.existsSync(dir)) { + console.log("\nCWD: " + process.cwd()); + console.log("Error: portOperation.mjs should be run from the project root"); + console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs"); + process.exit(1); +} + +/** + * Main function + */ +function main() { + const opName = process.argv[2]; + const legacyFilename = path.join(dir, `../operations/legacy/${process.argv[3]}.js`); + + if (!OP_CONFIG.hasOwnProperty(opName)) { + console.log(`${opName} cannot be found.`); + process.exit(0); + } + + const op = OP_CONFIG[opName]; + const moduleName = opName.replace(/\w\S*/g, txt => { + return txt.charAt(0).toUpperCase() + txt.substr(1); + }).replace(/[\s-/]/g, ""); + let legacyFile = ""; + + + // Read legacy file + try { + legacyFile = fs.readFileSync(legacyFilename, {encoding: "utf8"}); + } catch (err) { + console.log("Unable to read legacy file."); + console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs 'XOR' 'BitwiseOp'"); + process.exit(0); + } + + const author = legacyFile.match(/@author [^\n]+/)[0]; + const copyright = legacyFile.match(/@copyright [^\n]+/)[0]; + const utilsUsed = /Utils/.test(legacyFile); + const esc = new EscapeString(); + const desc = esc.run(op.description, ["Special chars", "Double"]); + const patterns = op.hasOwnProperty("patterns") ? ` + this.patterns = ${JSON.stringify(op.patterns, null, 4).split("\n").join("\n ")};` : ""; + + // Attempt to find the operation run function based on the JSDoc comment + const regex = `\\* ${opName} operation[^:]+:(?: function ?\\(input, args\\))? ?{([\\s\\S]+?)\n }`; + let runFunc = "\n"; + try { + runFunc = legacyFile.match(new RegExp(regex, "im"))[1]; + } catch (err) {} + + + // List all constants in legacyFile + const constants = []; + try { + const constantsRegex = /\* @constant[^/]+\/\s+([^\n]+)/gim; + let m; + + while ((m = constantsRegex.exec(legacyFile)) !== null) { + constants.push(m[1]); + } + } catch (err) {} + + const template = `/** + * ${author} + * ${copyright} + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +${utilsUsed ? 'import Utils from "../Utils";\n' : ""} +/** + * ${opName} operation + */ +class ${moduleName} extends Operation { + + /** + * ${moduleName} constructor + */ + constructor() { + super(); + + this.name = "${opName}";${op.flowControl ? "\n this.flowControl = true;" : ""} + this.module = "${op.module}"; + this.description = "${desc}"; + this.inputType = "${op.inputType}"; + this.outputType = "${op.outputType}";${op.manualBake ? "\n this.manualBake = true;" : ""} + this.args = ${JSON.stringify(op.args, null, 4).split("\n").join("\n ")};${patterns} + } + + /** + * @param {${op.inputType}} input + * @param {Object[]} args + * @returns {${op.outputType}} + */ + run(input, args) {${runFunc} + } +${op.highlight ? ` + /** + * Highlight ${opName} + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } +` : ""}${op.highlightReverse ? ` + /** + * Highlight ${opName} in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } +` : ""} +} + +export default ${moduleName}; +`; + + console.log("\nLegacy operation config\n-----------------------\n"); + console.log(JSON.stringify(op, null, 4)); + console.log("\n-----------------------\n"); + console.log("\nPotentially related constants\n-----------------------\n"); + console.log(constants.join("\n")); + console.log("\n-----------------------\n"); + + const filename = path.join(dir, `../operations/${moduleName}.mjs`); + if (fs.existsSync(filename)) { + console.log(`\x1b[31m\u274c ${filename} already exists. It has NOT been overwritten.\x1b[0m`); + process.exit(0); + } + fs.writeFileSync(filename, template); + + console.log("\x1b[32m\u2714\x1b[0m Operation written to \x1b[32m" + filename + "\x1b[0m"); + if (runFunc === "\n") { + console.log("\x1b[31m\u274c The run function could not be located automatically.\x1b[0m You will have to copy it accross manually."); + } else { + console.log("\x1b[32m\u2714\x1b[0m The run function was copied across. Double check that it was copied correctly. It may rely on other functions which have not been copied."); + } + console.log(`\nOpen \x1b[32m${legacyFilename}\x1b[0m and copy any relevant code over. Make sure you check imports, args and highlights. Code required by multiple operations should be stored in /src/core/lib/.\n\nDont't forget to run \x1b[36mgrunt lint\x1b[0m!`); +} + + +const OP_CONFIG = { + "Magic": { + module: "Default", + description: "The Magic operation attempts to detect various properties of the input data and suggests which operations could help to make more sense of it.

Options
Depth: If an operation appears to match the data, it will be run and the result will be analysed further. This argument controls the maximum number of levels of recursion.

Intensive mode: When this is turned on, various operations like XOR, bit rotates, and character encodings are brute-forced to attempt to detect valid data underneath. To improve performance, only the first 100 bytes of the data is brute-forced.

Extensive language support: At each stage, the relative byte frequencies of the data will be compared to average frequencies for a number of languages. The default set consists of ~40 of the most commonly used languages on the Internet. The extensive list consists of 284 languages and can result in many languages matching the data if their byte frequencies are similar.", + inputType: "ArrayBuffer", + outputType: "html", + flowControl: true, + args: [ + { + name: "Depth", + type: "number", + value: 3 + }, + { + name: "Intensive mode", + type: "boolean", + value: false + }, + { + name: "Extensive language support", + type: "boolean", + value: false + } + ] + }, + "Fork": { + module: "Default", + description: "Split the input data up based on the specified delimiter and run all subsequent operations on each branch separately.

For example, to decode multiple Base64 strings, enter them all on separate lines then add the 'Fork' and 'From Base64' operations to the recipe. Each string will be decoded separately.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Split delimiter", + type: "binaryShortString", + value: "\\n" + }, + { + name: "Merge delimiter", + type: "binaryShortString", + value: "\\n" + }, + { + name: "Ignore errors", + type: "boolean", + value: false + } + ] + }, + "Merge": { + module: "Default", + description: "Consolidate all branches back into a single trunk. The opposite of Fork.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [] + }, + "Register": { + module: "Default", + description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.

To use registers in arguments, refer to them using the notation $Rn where n is the register number, starting at 0.

For example:
Input: Test
Extractor: (.*)
Argument: $R0 becomes Test

Registers can be escaped in arguments using a backslash. e.g. \\$R0 would become $R0 rather than Test.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Extractor", + type: "binaryString", + value: "([\\s\\S]*)" + }, + { + name: "Case insensitive", + type: "boolean", + value: true + }, + { + name: "Multiline matching", + type: "boolean", + value: false + }, + ] + }, + "Jump": { + module: "Default", + description: "Jump forwards or backwards to the specified Label", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Label name", + type: "string", + value: "" + }, + { + name: "Maximum jumps (if jumping backwards)", + type: "number", + value: 10 + } + ] + }, + "Conditional Jump": { + module: "Default", + description: "Conditionally jump forwards or backwards to the specified Label based on whether the data matches the specified regular expression.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Match (regex)", + type: "string", + value: "" + }, + { + name: "Invert match", + type: "boolean", + value: false + }, + { + name: "Label name", + type: "shortString", + value: "" + }, + { + name: "Maximum jumps (if jumping backwards)", + type: "number", + value: 10 + } + ] + }, + "Label": { + module: "Default", + description: "Provides a location for conditional and fixed jumps to redirect execution to.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "Name", + type: "shortString", + value: "" + } + ] + }, + "Return": { + module: "Default", + description: "End execution of operations at this point in the recipe.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [] + }, + "Comment": { + module: "Default", + description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.", + inputType: "string", + outputType: "string", + flowControl: true, + args: [ + { + name: "", + type: "text", + value: "" + } + ] + }, + "From Base64": { + module: "Default", + description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.

This operation decodes data from an ASCII Base64 string back into its raw format.

e.g. aGVsbG8= becomes hello", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: "Base64.ALPHABET_OPTIONS" + }, + { + name: "Remove non-alphabet chars", + type: "boolean", + value: "Base64.REMOVE_NON_ALPH_CHARS" + } + ], + patterns: [ + { + match: "^(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["A-Za-z0-9+/=", false] + }, + { + match: "^[A-Z\\d\\-_]{20,}$", + flags: "i", + args: ["A-Za-z0-9-_", false] + }, + { + match: "^(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?$", + flags: "i", + args: ["A-Za-z0-9+\\-=", false] + }, + { + match: "^(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?$", + flags: "i", + args: ["./0-9A-Za-z=", false] + }, + { + match: "^[A-Z\\d_.]{20,}$", + flags: "i", + args: ["A-Za-z0-9_.", false] + }, + { + match: "^(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?$", + flags: "i", + args: ["A-Za-z0-9._-", false] + }, + { + match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["0-9a-zA-Z+/=", false] + }, + { + match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["0-9A-Za-z+/=", false] + }, + { + match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$", + flags: "", + args: [" -_", false] + }, + { + match: "^[A-Z\\d+\\-]{20,}$", + flags: "i", + args: ["+\\-0-9A-Za-z", false] + }, + { + match: "^[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}$", + flags: "", + args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", false] + }, + { + match: "^(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?$", + flags: "i", + args: ["N-ZA-Mn-za-m0-9+/=", false] + }, + { + match: "^[A-Z\\d./]{20,}$", + flags: "i", + args: ["./0-9A-Za-z", false] + }, + ] + }, + "To Base64": { + module: "Default", + description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.

This operation encodes data in an ASCII Base64 string.

e.g. hello becomes aGVsbG8=", + highlight: "func", + highlightReverse: "func", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: "Base64.ALPHABET_OPTIONS" + }, + ] + }, + "From Base58": { + module: "Default", + description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation decodes data from an ASCII string (with an alphabet of your choosing, presets included) back into its raw form.

e.g. StV1DL6CwTryKyV becomes hello world

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: "Base58.ALPHABET_OPTIONS" + }, + { + name: "Remove non-alphabet chars", + type: "boolean", + value: "Base58.REMOVE_NON_ALPH_CHARS" + } + ], + patterns: [ + { + match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false] + }, + { + match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false] + }, + ] + }, + "To Base58": { + module: "Default", + description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).

e.g. hello world becomes StV1DL6CwTryKyV

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: "Base58.ALPHABET_OPTIONS" + }, + ] + }, + "From Base32": { + module: "Default", + description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Alphabet", + type: "binaryString", + value: "Base64.BASE32_ALPHABET" + }, + { + name: "Remove non-alphabet chars", + type: "boolean", + value: "Base64.REMOVE_NON_ALPH_CHARS" + } + ], + patterns: [ + { + match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$", + flags: "", + args: ["A-Z2-7=", false] + }, + ] + }, + "To Base32": { + module: "Default", + description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Alphabet", + type: "binaryString", + value: "Base64.BASE32_ALPHABET" + } + ] + }, + "Show Base64 offsets": { + module: "Default", + description: "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.

This operation shows all possible offsets for a given string so that each possible encoding can be considered.", + inputType: "byteArray", + outputType: "html", + args: [ + { + name: "Alphabet", + type: "binaryString", + value: "Base64.ALPHABET" + }, + { + name: "Show variable chars and padding", + type: "boolean", + value: "Base64.OFFSETS_SHOW_VARIABLE" + } + ] + }, + "Disassemble x86": { + module: "Shellcode", + description: "Disassembly is the process of translating machine language into assembly language.

This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.

Input should be in hexadecimal.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Bit mode", + type: "option", + value: "Shellcode.MODE" + }, + { + name: "Compatibility", + type: "option", + value: "Shellcode.COMPATIBILITY" + }, + { + name: "Code Segment (CS)", + type: "number", + value: 16 + }, + { + name: "Offset (IP)", + type: "number", + value: 0 + }, + { + name: "Show instruction hex", + type: "boolean", + value: true + }, + { + name: "Show instruction position", + type: "boolean", + value: true + } + ] + }, + "XOR": { + module: "Default", + description: "XOR the input with the given key.
e.g. fe023da5

Options
Null preserving: If the current byte is 0x00 or the same as the key, skip it.

Scheme:
  • Standard - key is unchanged after each round
  • Input differential - key is set to the value of the previous unprocessed byte
  • Output differential - key is set to the value of the previous processed byte
", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "BitwiseOp.KEY_FORMAT" + }, + { + name: "Scheme", + type: "option", + value: "BitwiseOp.XOR_SCHEME" + }, + { + name: "Null preserving", + type: "boolean", + value: "BitwiseOp.XOR_PRESERVE_NULLS" + } + ] + }, + "XOR Brute Force": { + module: "Default", + description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.

Optionally enter a string that you expect to find in the plaintext to filter results (crib).", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Key length", + type: "number", + value: "BitwiseOp.XOR_BRUTE_KEY_LENGTH" + }, + { + name: "Sample length", + type: "number", + value: "BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH" + }, + { + name: "Sample offset", + type: "number", + value: "BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET" + }, + { + name: "Scheme", + type: "option", + value: "BitwiseOp.XOR_SCHEME" + }, + { + name: "Null preserving", + type: "boolean", + value: "BitwiseOp.XOR_PRESERVE_NULLS" + }, + { + name: "Print key", + type: "boolean", + value: "BitwiseOp.XOR_BRUTE_PRINT_KEY" + }, + { + name: "Output as hex", + type: "boolean", + value: "BitwiseOp.XOR_BRUTE_OUTPUT_HEX" + }, + { + name: "Crib (known plaintext string)", + type: "binaryString", + value: "" + } + ] + }, + "NOT": { + module: "Default", + description: "Returns the inverse of each byte.", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [] + }, + "AND": { + module: "Default", + description: "AND the input with the given key.
e.g. fe023da5", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "BitwiseOp.KEY_FORMAT" + } + ] + }, + "OR": { + module: "Default", + description: "OR the input with the given key.
e.g. fe023da5", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "BitwiseOp.KEY_FORMAT" + } + ] + }, + "ADD": { + module: "Default", + description: "ADD the input with the given key (e.g. fe023da5), MOD 255", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "BitwiseOp.KEY_FORMAT" + } + ] + }, + "SUB": { + module: "Default", + description: "SUB the input with the given key (e.g. fe023da5), MOD 255", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "BitwiseOp.KEY_FORMAT" + } + ] + }, + "Sum": { + module: "Default", + description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 18.5", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Subtract": { + module: "Default", + description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 1.5", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Multiply": { + module: "Default", + description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 40", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Divide": { + module: "Default", + description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 2.5", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Mean": { + module: "Default", + description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 .5 becomes 4.75", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Median": { + module: "Default", + description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 1 .5 becomes 4.5", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "Standard Deviation": { + module: "Default", + description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 4.089281382128433", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Delimiter", + type: "option", + value: "Arithmetic.DELIM_OPTIONS" + } + ] + }, + "To Table": { + module: "Default", + description: "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.

Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to \\t to support TSV (Tab Separated Values) or | for PSV (Pipe Separated Values).

You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Cell delimiters", + type: "binaryShortString", + value: "," + }, + { + name: "Row delimiters", + type: "binaryShortString", + value: "\\n\\r" + }, + { + name: "Make first row header", + type: "boolean", + value: false + }, + { + name: "Format", + type: "option", + value: "ToTable.FORMATS" + } + ] + }, + "From Hex": { + module: "Default", + description: "Converts a hexadecimal byte string back into its raw value.

e.g. ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a becomes the UTF-8 encoded string Γειά σου", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.HEX_DELIM_OPTIONS" + } + ], + patterns: [ + { + match: "^(?:[\\dA-F]{2})+$", + flags: "i", + args: ["None"] + }, + { + match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$", + flags: "i", + args: ["Space"] + }, + { + match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$", + flags: "i", + args: ["Comma"] + }, + { + match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$", + flags: "i", + args: ["Semi-colon"] + }, + { + match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$", + flags: "i", + args: ["Colon"] + }, + { + match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$", + flags: "i", + args: ["Line feed"] + }, + { + match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$", + flags: "i", + args: ["CRLF"] + }, + { + match: "^[\\dA-F]{2}(?:0x[\\dA-F]{2})*$", + flags: "i", + args: ["0x"] + }, + { + match: "^[\\dA-F]{2}(?:\\\\x[\\dA-F]{2})*$", + flags: "i", + args: ["\\x"] + } + ] + }, + "To Hex": { + module: "Default", + description: "Converts the input string to hexadecimal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a", + highlight: "func", + highlightReverse: "func", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.HEX_DELIM_OPTIONS" + } + ] + }, + "From Octal": { + module: "Default", + description: "Converts an octal byte string back into its raw value.

e.g. 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205 becomes the UTF-8 encoded string Γειά σου", + highlight: false, + highlightReverse: false, + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + } + ], + patterns: [ + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["CRLF"] + }, + ] + }, + "To Octal": { + module: "Default", + description: "Converts the input string to octal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205", + highlight: false, + highlightReverse: false, + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + } + ] + }, + "From Charcode": { + module: "Default", + description: "Converts unicode character codes back into text.

e.g. 0393 03b5 03b9 03ac 20 03c3 03bf 03c5 becomes Γειά σου", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + }, + { + name: "Base", + type: "number", + value: "ByteRepr.CHARCODE_BASE" + } + ] + }, + "To Charcode": { + module: "Default", + description: "Converts text to its unicode character code equivalent.

e.g. Γειά σου becomes 0393 03b5 03b9 03ac 20 03c3 03bf 03c5", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + }, + { + name: "Base", + type: "number", + value: "ByteRepr.CHARCODE_BASE" + } + ] + }, + "From Binary": { + module: "Default", + description: "Converts a binary string back into its raw form.

e.g. 01001000 01101001 becomes Hi", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.BIN_DELIM_OPTIONS" + } + ], + patterns: [ + { + match: "^(?:[01]{8})+$", + flags: "", + args: ["None"] + }, + { + match: "^(?:[01]{8})(?: [01]{8})*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:[01]{8})(?:,[01]{8})*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:[01]{8})(?:;[01]{8})*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:[01]{8})(?::[01]{8})*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:[01]{8})(?:\\n[01]{8})*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$", + flags: "", + args: ["CRLF"] + }, + ] + }, + "To Binary": { + module: "Default", + description: "Displays the input data as a binary string.

e.g. Hi becomes 01001000 01101001", + highlight: "func", + highlightReverse: "func", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.BIN_DELIM_OPTIONS" + } + ] + }, + "From Decimal": { + module: "Default", + description: "Converts the data from an ordinal integer array back into its raw form.

e.g. 72 101 108 108 111 becomes Hello", + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + } + ], + patterns: [ + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["CRLF"] + }, + ] + }, + "To Decimal": { + module: "Default", + description: "Converts the input data to an ordinal integer array.

e.g. Hello becomes 72 101 108 108 111", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "ByteRepr.DELIM_OPTIONS" + } + ] + }, + "From Hexdump": { + module: "Default", + description: "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis.", + highlight: "func", + highlightReverse: "func", + inputType: "string", + outputType: "byteArray", + args: [], + patterns: [ + { + match: "^(?:(?:[\\dA-F]{4,16}:?)?\\s*((?:[\\dA-F]{2}\\s){1,8}(?:\\s|[\\dA-F]{2}-)(?:[\\dA-F]{2}\\s){1,8}|(?:[\\dA-F]{2}\\s|[\\dA-F]{4}\\s)+)[^\\n]*\\n?)+$", + flags: "i", + args: [] + }, + ] + }, + "To Hexdump": { + module: "Default", + description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.", + highlight: "func", + highlightReverse: "func", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Width", + type: "number", + value: "Hexdump.WIDTH" + }, + { + name: "Upper case hex", + type: "boolean", + value: "Hexdump.UPPER_CASE" + }, + { + name: "Include final length", + type: "boolean", + value: "Hexdump.INCLUDE_FINAL_LENGTH" + } + ] + }, + "From Base": { + module: "Default", + description: "Converts a number to decimal from a given numerical base.", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Radix", + type: "number", + value: "Base.DEFAULT_RADIX" + } + ] + }, + "To Base": { + module: "Default", + description: "Converts a decimal number to a given numerical base.", + inputType: "BigNumber", + outputType: "string", + args: [ + { + name: "Radix", + type: "number", + value: "Base.DEFAULT_RADIX" + } + ] + }, + "From HTML Entity": { + module: "Default", + description: "Converts HTML entities back to characters

e.g. &amp; becomes &", // tags required to stop the browser just printing & + inputType: "string", + outputType: "string", + args: [], + patterns: [ + { + match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});", + flags: "i", + args: [] + }, + ] + }, + "To HTML Entity": { + module: "Default", + description: "Converts characters to HTML entities

e.g. & becomes &amp;", // tags required to stop the browser just printing & + inputType: "string", + outputType: "string", + args: [ + { + name: "Convert all characters", + type: "boolean", + value: "HTML.CONVERT_ALL" + }, + { + name: "Convert to", + type: "option", + value: "HTML.CONVERT_OPTIONS" + } + ] + }, + "Strip HTML tags": { + module: "Default", + description: "Removes all HTML tags from the input.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Remove indentation", + type: "boolean", + value: "HTML.REMOVE_INDENTATION" + }, + { + name: "Remove excess line breaks", + type: "boolean", + value: "HTML.REMOVE_LINE_BREAKS" + } + ] + }, + "URL Decode": { + module: "URL", + description: "Converts URI/URL percent-encoded characters back to their raw values.

e.g. %3d becomes =", + inputType: "string", + outputType: "string", + args: [], + patterns: [ + { + match: ".*(?:%[\\da-f]{2}.*){4}", + flags: "i", + args: [] + }, + ] + }, + "URL Encode": { + module: "URL", + description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.

e.g. = becomes %3d", + inputType: "string", + outputType: "string", + args: [ + { + name: "Encode all special chars", + type: "boolean", + value: "URL_.ENCODE_ALL" + } + ] + }, + "Parse URI": { + module: "URL", + description: "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments.", + inputType: "string", + outputType: "string", + args: [] + }, + "Unescape Unicode Characters": { + module: "Default", + description: "Converts unicode-escaped character notation back into raw characters.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. \\u03c3\\u03bf\\u03c5 becomes σου", + inputType: "string", + outputType: "string", + args: [ + { + name: "Prefix", + type: "option", + value: "Unicode.PREFIXES" + } + ] + }, + "Escape Unicode Characters": { + module: "Default", + description: "Converts characters to their unicode-escaped notations.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. σου becomes \\u03C3\\u03BF\\u03C5", + inputType: "string", + outputType: "string", + args: [ + { + name: "Prefix", + type: "option", + value: "Unicode.PREFIXES" + }, + { + name: "Encode all chars", + type: "boolean", + value: false + }, + { + name: "Padding", + type: "number", + value: 4 + }, + { + name: "Uppercase hex", + type: "boolean", + value: true + } + ], + patterns: [ + { + match: "\\\\u(?:[\\da-f]{4,6})", + flags: "i", + args: ["\\u"] + }, + { + match: "%u(?:[\\da-f]{4,6})", + flags: "i", + args: ["%u"] + }, + { + match: "U\\+(?:[\\da-f]{4,6})", + flags: "i", + args: ["U+"] + }, + ] + }, + "From Quoted Printable": { + module: "Default", + description: "Converts QP-encoded text back to standard text.", + inputType: "string", + outputType: "byteArray", + args: [], + patterns: [ + { + match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]*(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$", + flags: "i", + args: [] + }, + ] + }, + "To Quoted Printable": { + module: "Default", + description: "Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign '=') to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean. It is defined as a MIME content transfer encoding for use in e-mail.

QP works by using the equals sign '=' as an escape character. It also limits line length to 76, as some software has limits on line length.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "From Punycode": { + module: "Encodings", + description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. mnchen-3ya decodes to münchen", + inputType: "string", + outputType: "string", + args: [ + { + name: "Internationalised domain name", + type: "boolean", + value: "Punycode.IDN" + } + ] + }, + "To Punycode": { + module: "Encodings", + description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. münchen encodes to mnchen-3ya", + inputType: "string", + outputType: "string", + args: [ + { + name: "Internationalised domain name", + type: "boolean", + value: "Punycode.IDN" + } + ] + }, + "From Hex Content": { + module: "Default", + description: "Translates hexadecimal bytes in text back to raw bytes.

e.g. foo|3d|bar becomes foo=bar.", + inputType: "string", + outputType: "byteArray", + args: [] + }, + "To Hex Content": { + module: "Default", + description: "Converts special characters in a string to hexadecimal.

e.g. foo=bar becomes foo|3d|bar.", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Convert", + type: "option", + value: "ByteRepr.HEX_CONTENT_CONVERT_WHICH" + }, + { + name: "Print spaces between bytes", + type: "boolean", + value: "ByteRepr.HEX_CONTENT_SPACES_BETWEEN_BYTES" + }, + ] + }, + "Change IP format": { + module: "JSBN", + description: "Convert an IP address from one format to another, e.g. 172.20.23.54 to ac141736", + inputType: "string", + outputType: "string", + args: [ + { + name: "Input format", + type: "option", + value: "IP.IP_FORMAT_LIST" + }, + { + name: "Output format", + type: "option", + value: "IP.IP_FORMAT_LIST" + } + ] + }, + "Parse IP range": { + module: "JSBN", + description: "Given a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0), this operation provides network information and enumerates all IP addresses in the range.

IPv6 is supported but will not be enumerated.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Include network info", + type: "boolean", + value: "IP.INCLUDE_NETWORK_INFO" + }, + { + name: "Enumerate IP addresses", + type: "boolean", + value: "IP.ENUMERATE_ADDRESSES" + }, + { + name: "Allow large queries", + type: "boolean", + value: "IP.ALLOW_LARGE_LIST" + } + ] + }, + "Group IP addresses": { + module: "JSBN", + description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "IP.DELIM_OPTIONS" + }, + { + name: "Subnet (CIDR)", + type: "number", + value: "IP.GROUP_CIDR" + }, + { + name: "Only show the subnets", + type: "boolean", + value: "IP.GROUP_ONLY_SUBNET" + } + ] + }, + "Parse IPv6 address": { + module: "JSBN", + description: "Displays the longhand and shorthand versions of a valid IPv6 address.

Recognises all reserved ranges and parses encapsulated or tunnelled addresses including Teredo and 6to4.", + inputType: "string", + outputType: "string", + args: [] + }, + "Parse IPv4 header": { + module: "JSBN", + description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Input format", + type: "option", + value: "IP.IP_HEADER_FORMAT" + } + ] + }, + "Encode text": { + module: "CharEnc", + description: [ + "Encodes text into the chosen character encoding.", + "

", + "Supported charsets are:", + "
    ", + 'TODO -----------------------Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n")', + "
", + ].join("\n"), + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Encoding", + type: "option", + value: "Object.keys(CharEnc.IO_FORMAT)," + }, + ], + }, + "Decode text": { + module: "CharEnc", + description: [ + "Decodes text from the chosen character encoding.", + "

", + "Supported charsets are:", + "
    ", + 'TODO -----------------------Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n")', + "
", + ].join("\n"), + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Encoding", + type: "option", + value: "Object.keys(CharEnc.IO_FORMAT)," + }, + ] + }, + "AES Decrypt": { + module: "Ciphers", + description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256


IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.

GCM Tag: This field is ignored unless 'GCM' mode is used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.AES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "GCM Tag", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + ] + }, + "AES Encrypt": { + module: "Ciphers", + description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256
You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.AES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + ] + }, + "DES Decrypt": { + module: "Ciphers", + description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.DES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + ] + }, + "DES Encrypt": { + module: "Ciphers", + description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.DES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + ] + }, + "Triple DES Decrypt": { + module: "Ciphers", + description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.DES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + ] + }, + "Triple DES Encrypt": { + module: "Ciphers", + description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.DES_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + ] + }, + "Blowfish Decrypt": { + module: "Ciphers", + description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.BLOWFISH_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.BLOWFISH_OUTPUT_TYPES" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + ] + }, + "Blowfish Encrypt": { + module: "Ciphers", + description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Mode", + type: "option", + value: "Cipher.BLOWFISH_MODES" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "Output", + type: "option", + value: "Cipher.BLOWFISH_OUTPUT_TYPES" + }, + ] + }, + "RC4": { + module: "Ciphers", + description: "RC4 (also known as ARC4) is a widely-used stream cipher designed by Ron Rivest. It is used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Passphrase", + type: "toggleString", + value: "", + toggleValues: "Cipher.RC4_KEY_FORMAT" + }, + { + name: "Input format", + type: "option", + value: "Cipher.CJS_IO_FORMAT" + }, + { + name: "Output format", + type: "option", + value: "Cipher.CJS_IO_FORMAT" + }, + ] + }, + "RC4 Drop": { + module: "Ciphers", + description: "It was discovered that the first few bytes of the RC4 keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Passphrase", + type: "toggleString", + value: "", + toggleValues: "Cipher.RC4_KEY_FORMAT" + }, + { + name: "Input format", + type: "option", + value: "Cipher.CJS_IO_FORMAT" + }, + { + name: "Output format", + type: "option", + value: "Cipher.CJS_IO_FORMAT" + }, + { + name: "Number of bytes to drop", + type: "number", + value: "Cipher.RC4DROP_BYTES" + }, + ] + }, + "RC2 Decrypt": { + module: "Ciphers", + description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + ] + }, + "RC2 Encrypt": { + module: "Ciphers", + description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

You can generate a password-based key using one of the KDF operations.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "IV", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + { + name: "Input", + type: "option", + value: "Cipher.IO_FORMAT3" + }, + { + name: "Output", + type: "option", + value: "Cipher.IO_FORMAT4" + }, + ] + }, + "Pseudo-Random Number Generator": { + module: "Ciphers", + description: "A cryptographically-secure pseudo-random number generator (PRNG).

This operation uses the browser's built-in crypto.getRandomValues() method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Number of bytes", + type: "number", + value: "Cipher.PRNG_BYTES" + }, + { + name: "Output as", + type: "option", + value: "Cipher.PRNG_OUTPUT" + } + ] + }, + "Derive PBKDF2 key": { + module: "Ciphers", + description: "PBKDF2 is a password-based key derivation function. It is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's RFC 2898.

In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Passphrase", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT2" + }, + { + name: "Key size", + type: "number", + value: "Cipher.KDF_KEY_SIZE" + }, + { + name: "Iterations", + type: "number", + value: "Cipher.KDF_ITERATIONS" + }, + { + name: "Hashing function", + type: "option", + value: "Cipher.HASHERS" + }, + { + name: "Salt", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + ] + }, + "Derive EVP key": { + module: "Ciphers", + description: "EVP is a password-based key derivation function (PBKDF) used extensively in OpenSSL. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Passphrase", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT2" + }, + { + name: "Key size", + type: "number", + value: "Cipher.KDF_KEY_SIZE" + }, + { + name: "Iterations", + type: "number", + value: "Cipher.KDF_ITERATIONS" + }, + { + name: "Hashing function", + type: "option", + value: "Cipher.HASHERS" + }, + { + name: "Salt", + type: "toggleString", + value: "", + toggleValues: "Cipher.IO_FORMAT1" + }, + ] + }, + "Vigenère Encode": { + module: "Ciphers", + description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "string", + value: "" + } + ] + }, + "Vigenère Decode": { + module: "Ciphers", + description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Key", + type: "string", + value: "" + } + ] + }, + "Bifid Cipher Encode": { + module: "Ciphers", + description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Keyword", + type: "string", + value: "" + } + ] + }, + "Bifid Cipher Decode": { + module: "Ciphers", + description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Keyword", + type: "string", + value: "" + } + ] + }, + "Affine Cipher Encode": { + module: "Ciphers", + description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, (ax + b) % 26, and converted back to a letter.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "a", + type: "number", + value: "Cipher.AFFINE_A" + }, + { + name: "b", + type: "number", + value: "Cipher.AFFINE_B" + } + ] + }, + "Affine Cipher Decode": { + module: "Ciphers", + description: "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "a", + type: "number", + value: "Cipher.AFFINE_A" + }, + { + name: "b", + type: "number", + value: "Cipher.AFFINE_B" + } + ] + }, + "Atbash Cipher": { + module: "Ciphers", + description: "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [] + }, + "Rotate right": { + module: "Default", + description: "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Amount", + type: "number", + value: "Rotate.ROTATE_AMOUNT" + }, + { + name: "Carry through", + type: "boolean", + value: "Rotate.ROTATE_CARRY" + } + ] + }, + "Rotate left": { + module: "Default", + description: "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Amount", + type: "number", + value: "Rotate.ROTATE_AMOUNT" + }, + { + name: "Carry through", + type: "boolean", + value: "Rotate.ROTATE_CARRY" + } + ] + }, + "ROT13": { + module: "Default", + description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Rotate lower case chars", + type: "boolean", + value: "Rotate.ROT13_LOWERCASE" + }, + { + name: "Rotate upper case chars", + type: "boolean", + value: "Rotate.ROT13_UPPERCASE" + }, + { + name: "Amount", + type: "number", + value: "Rotate.ROT13_AMOUNT" + }, + ] + }, + "ROT47": { + module: "Default", + description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.", + highlight: true, + highlightReverse: true, + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Amount", + type: "number", + value: "Rotate.ROT47_AMOUNT" + }, + ] + }, + "Strip HTTP headers": { + module: "HTTP", + description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.", + inputType: "string", + outputType: "string", + args: [] + }, + "Parse User Agent": { + module: "HTTP", + description: "Attempts to identify and categorise information contained in a user-agent string.", + inputType: "string", + outputType: "string", + args: [] + }, + "Format MAC addresses": { + module: "Default", + description: "Displays given MAC addresses in multiple different formats.

Expects addresses in a list separated by newlines, spaces or commas.

WARNING: There are no validity checks.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Output case", + type: "option", + value: "MAC.OUTPUT_CASE" + }, + { + name: "No delimiter", + type: "boolean", + value: "MAC.NO_DELIM" + }, + { + name: "Dash delimiter", + type: "boolean", + value: "MAC.DASH_DELIM" + }, + { + name: "Colon delimiter", + type: "boolean", + value: "MAC.COLON_DELIM" + }, + { + name: "Cisco style", + type: "boolean", + value: "MAC.CISCO_STYLE" + }, + { + name: "IPv6 interface ID", + type: "boolean", + value: "MAC.IPV6_INTERFACE_ID" + } + ] + }, + "Encode NetBIOS Name": { + module: "Default", + description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation carries out the first level of encoding. See RFC 1001 for full details.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Offset", + type: "number", + value: "NetBIOS.OFFSET" + } + ] + }, + "Decode NetBIOS Name": { + module: "Default", + description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation decodes the first level of encoding. See RFC 1001 for full details.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Offset", + type: "number", + value: "NetBIOS.OFFSET" + } + ] + }, + "Offset checker": { + module: "Default", + description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Sample delimiter", + type: "binaryString", + value: "StrUtils.OFF_CHK_SAMPLE_DELIMITER" + } + ] + }, + "Remove whitespace": { + module: "Default", + description: "Optionally removes all spaces, carriage returns, line feeds, tabs and form feeds from the input data.

This operation also supports the removal of full stops which are sometimes used to represent non-printable bytes in ASCII output.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Spaces", + type: "boolean", + value: "Tidy.REMOVE_SPACES" + }, + { + name: "Carriage returns (\\r)", + type: "boolean", + value: "Tidy.REMOVE_CARIAGE_RETURNS" + }, + { + name: "Line feeds (\\n)", + type: "boolean", + value: "Tidy.REMOVE_LINE_FEEDS" + }, + { + name: "Tabs", + type: "boolean", + value: "Tidy.REMOVE_TABS" + }, + { + name: "Form feeds (\\f)", + type: "boolean", + value: "Tidy.REMOVE_FORM_FEEDS" + }, + { + name: "Full stops", + type: "boolean", + value: "Tidy.REMOVE_FULL_STOPS" + } + ] + }, + "Remove null bytes": { + module: "Default", + description: "Removes all null bytes (0x00) from the input.", + inputType: "byteArray", + outputType: "byteArray", + args: [] + }, + "Drop bytes": { + module: "Default", + description: "Cuts a slice of the specified number of bytes out of the data.", + inputType: "ArrayBuffer", + outputType: "ArrayBuffer", + args: [ + { + name: "Start", + type: "number", + value: "Tidy.DROP_START" + }, + { + name: "Length", + type: "number", + value: "Tidy.DROP_LENGTH" + }, + { + name: "Apply to each line", + type: "boolean", + value: "Tidy.APPLY_TO_EACH_LINE" + } + ] + }, + "Take bytes": { + module: "Default", + description: "Takes a slice of the specified number of bytes from the data.", + inputType: "ArrayBuffer", + outputType: "ArrayBuffer", + args: [ + { + name: "Start", + type: "number", + value: "Tidy.TAKE_START" + }, + { + name: "Length", + type: "number", + value: "Tidy.TAKE_LENGTH" + }, + { + name: "Apply to each line", + type: "boolean", + value: "Tidy.APPLY_TO_EACH_LINE" + } + ] + }, + "Pad lines": { + module: "Default", + description: "Add the specified number of the specified character to the beginning or end of each line", + inputType: "string", + outputType: "string", + args: [ + { + name: "Position", + type: "option", + value: "Tidy.PAD_POSITION" + }, + { + name: "Length", + type: "number", + value: "Tidy.PAD_LENGTH" + }, + { + name: "Character", + type: "binaryShortString", + value: "Tidy.PAD_CHAR" + } + ] + }, + "Reverse": { + module: "Default", + description: "Reverses the input string.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "By", + type: "option", + value: "SeqUtils.REVERSE_BY" + } + ] + }, + "Sort": { + module: "Default", + description: "Alphabetically sorts strings separated by the specified delimiter.

The IP address option supports IPv4 only.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "SeqUtils.DELIMITER_OPTIONS" + }, + { + name: "Reverse", + type: "boolean", + value: "SeqUtils.SORT_REVERSE" + }, + { + name: "Order", + type: "option", + value: "SeqUtils.SORT_ORDER" + } + ] + }, + "Unique": { + module: "Default", + description: "Removes duplicate strings from the input.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "SeqUtils.DELIMITER_OPTIONS" + } + ] + }, + "Count occurrences": { + module: "Default", + description: "Counts the number of times the provided string occurs in the input.", + inputType: "string", + outputType: "number", + args: [ + { + name: "Search string", + type: "toggleString", + value: "", + toggleValues: "SeqUtils.SEARCH_TYPE" + } + ] + }, + "Add line numbers": { + module: "Default", + description: "Adds line numbers to the output.", + inputType: "string", + outputType: "string", + args: [] + }, + "Remove line numbers": { + module: "Default", + description: "Removes line numbers from the output if they can be trivially detected.", + inputType: "string", + outputType: "string", + args: [] + }, + "Find / Replace": { + module: "Regex", + description: "Replaces all occurrences of the first string with the second.

Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).", + inputType: "string", + outputType: "string", + args: [ + { + name: "Find", + type: "toggleString", + value: "", + toggleValues: "Regex.SEARCH_TYPE" + }, + { + name: "Replace", + type: "binaryString", + value: "" + }, + { + name: "Global match", + type: "boolean", + value: "Regex.FIND_REPLACE_GLOBAL," + }, + { + name: "Case insensitive", + type: "boolean", + value: "Regex.FIND_REPLACE_CASE," + }, + { + name: "Multiline matching", + type: "boolean", + value: "Regex.FIND_REPLACE_MULTILINE," + }, + + ] + }, + "To Upper case": { + module: "Default", + description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Scope", + type: "option", + value: "StrUtils.CASE_SCOPE" + } + ] + }, + "To Lower case": { + module: "Default", + description: "Converts every character in the input to lower case.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [] + }, + "Split": { + module: "Default", + description: "Splits a string into sections around a given delimiter.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Split delimiter", + type: "editableOption", + value: "StrUtils.SPLIT_DELIM_OPTIONS" + }, + { + name: "Join delimiter", + type: "editableOption", + value: "StrUtils.JOIN_DELIM_OPTIONS" + } + ] + }, + "Filter": { + module: "Default", + description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "StrUtils.DELIMITER_OPTIONS" + }, + { + name: "Regex", + type: "string", + value: "" + }, + { + name: "Invert condition", + type: "boolean", + value: false + }, + ] + }, + "Strings": { + module: "Regex", + description: "Extracts all strings from the input.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Encoding", + type: "option", + value: "Extract.ENCODING_LIST" + }, + { + name: "Minimum length", + type: "number", + value: "Extract.MIN_STRING_LEN" + }, + { + name: "Match", + type: "option", + value: "Extract.STRING_MATCH_TYPE" + }, + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract IP addresses": { + module: "Regex", + description: "Extracts all IPv4 and IPv6 addresses.

Warning: Given a string 710.65.0.456, this will match 10.65.0.45 so always check the original input!", + inputType: "string", + outputType: "string", + args: [ + { + name: "IPv4", + type: "boolean", + value: "Extract.INCLUDE_IPV4" + }, + { + name: "IPv6", + type: "boolean", + value: "Extract.INCLUDE_IPV6" + }, + { + name: "Remove local IPv4 addresses", + type: "boolean", + value: "Extract.REMOVE_LOCAL" + }, + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract email addresses": { + module: "Regex", + description: "Extracts all email addresses from the input.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract MAC addresses": { + module: "Regex", + description: "Extracts all Media Access Control (MAC) addresses from the input.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract URLs": { + module: "Regex", + description: "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract domains": { + module: "Regex", + description: "Extracts domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract file paths": { + module: "Regex", + description: "Extracts anything that looks like a Windows or UNIX file path.

Note that if UNIX is selected, there will likely be a lot of false positives.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Windows", + type: "boolean", + value: "Extract.INCLUDE_WIN_PATH" + }, + { + name: "UNIX", + type: "boolean", + value: "Extract.INCLUDE_UNIX_PATH" + }, + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Extract dates": { + module: "Regex", + description: "Extracts dates in the following formats
  • yyyy-mm-dd
  • dd/mm/yyyy
  • mm/dd/yyyy
Dividers can be any of /, -, . or space", + inputType: "string", + outputType: "string", + args: [ + { + name: "Display total", + type: "boolean", + value: "Extract.DISPLAY_TOTAL" + } + ] + }, + "Regular expression": { + module: "Regex", + description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.

Supports extended regex syntax including the 'dot matches all' flag, named capture groups, full unicode coverage (including \\p{} categories and scripts as well as astral codes) and recursive matching.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Built in regexes", + type: "populateOption", + value: "Regex.REGEX_PRE_POPULATE", + target: 1, + }, + { + name: "Regex", + type: "text", + value: "" + }, + { + name: "Case insensitive", + type: "boolean", + value: true + }, + { + name: "^ and $ match at newlines", + type: "boolean", + value: true + }, + { + name: "Dot matches all", + type: "boolean", + value: false + }, + { + name: "Unicode support", + type: "boolean", + value: false + }, + { + name: "Astral support", + type: "boolean", + value: false + }, + { + name: "Display total", + type: "boolean", + value: "Regex.DISPLAY_TOTAL" + }, + { + name: "Output format", + type: "option", + value: "Regex.OUTPUT_FORMAT" + }, + ] + }, + "XPath expression": { + module: "Code", + description: "Extract information from an XML document with an XPath query", + inputType: "string", + outputType: "string", + args: [ + { + name: "XPath", + type: "string", + value: "Code.XPATH_INITIAL" + }, + { + name: "Result delimiter", + type: "binaryShortString", + value: "Code.XPATH_DELIMITER" + } + ] + }, + "JPath expression": { + module: "Code", + description: "Extract information from a JSON object with a JPath query.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Query", + type: "string", + value: "Code.JPATH_INITIAL" + }, + { + name: "Result delimiter", + type: "binaryShortString", + value: "Code.JPATH_DELIMITER" + } + ] + }, + "CSS selector": { + module: "Code", + description: "Extract information from an HTML document with a CSS selector", + inputType: "string", + outputType: "string", + args: [ + { + name: "CSS selector", + type: "string", + value: "Code.CSS_SELECTOR_INITIAL" + }, + { + name: "Delimiter", + type: "binaryShortString", + value: "Code.CSS_QUERY_DELIMITER" + }, + ] + }, + "From UNIX Timestamp": { + module: "Default", + description: "Converts a UNIX timestamp to a datetime string.

e.g. 978346800 becomes Mon 1 January 2001 11:00:00 UTC

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", + inputType: "number", + outputType: "string", + args: [ + { + name: "Units", + type: "option", + value: "DateTime.UNITS" + } + ], + patterns: [ + { + match: "^1?\\d{9}$", + flags: "", + args: ["Seconds (s)"] + }, + { + match: "^1?\\d{12}$", + flags: "", + args: ["Milliseconds (ms)"] + }, + { + match: "^1?\\d{15}$", + flags: "", + args: ["Microseconds (μs)"] + }, + { + match: "^1?\\d{18}$", + flags: "", + args: ["Nanoseconds (ns)"] + }, + ] + }, + "To UNIX Timestamp": { + module: "Default", + description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.

e.g. Mon 1 January 2001 11:00:00 becomes 978346800

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", + inputType: "string", + outputType: "string", + args: [ + { + name: "Units", + type: "option", + value: "DateTime.UNITS" + }, + { + name: "Treat as UTC", + type: "boolean", + value: "DateTime.TREAT_AS_UTC" + }, + { + name: "Show parsed datetime", + type: "boolean", + value: true + } + ] + }, + "Sleep": { + module: "Default", + description: "Sleep causes the recipe to wait for a specified number of milliseconds before continuing execution.", + inputType: "ArrayBuffer", + outputType: "ArrayBuffer", + args: [ + { + name: "Time (ms)", + type: "number", + value: 1000 + } + ] + }, + "Windows Filetime to UNIX Timestamp": { + module: "Default", + description: "Converts a Windows Filetime value to a UNIX timestamp.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Output units", + type: "option", + value: "Filetime.UNITS" + }, + { + name: "Input format", + type: "option", + value: "Filetime.FILETIME_FORMATS" + } + ] + }, + "UNIX Timestamp to Windows Filetime": { + module: "Default", + description: "Converts a UNIX timestamp to a Windows Filetime value.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Input units", + type: "option", + value: "Filetime.UNITS" + }, + { + name: "Output format", + type: "option", + value: "Filetime.FILETIME_FORMATS" + } + ] + }, + "Translate DateTime Format": { + module: "Default", + description: "Parses a datetime string in one format and re-writes it in another.

Run with no input to see the relevant format string examples.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Built in formats", + type: "populateOption", + value: "DateTime.DATETIME_FORMATS", + target: 1 + }, + { + name: "Input format string", + type: "binaryString", + value: "DateTime.INPUT_FORMAT_STRING" + }, + { + name: "Input timezone", + type: "option", + value: "DateTime.TIMEZONES" + }, + { + name: "Output format string", + type: "binaryString", + value: "DateTime.OUTPUT_FORMAT_STRING" + }, + { + name: "Output timezone", + type: "option", + value: "DateTime.TIMEZONES" + } + ] + }, + "Parse DateTime": { + module: "Default", + description: "Parses a DateTime string in your specified format and displays it in whichever timezone you choose with the following information:
  • Date
  • Time
  • Period (AM/PM)
  • Timezone
  • UTC offset
  • Daylight Saving Time
  • Leap year
  • Days in this month
  • Day of year
  • Week number
  • Quarter
Run with no input to see format string examples if required.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Built in formats", + type: "populateOption", + value: "DateTime.DATETIME_FORMATS", + target: 1 + }, + { + name: "Input format string", + type: "binaryString", + value: "DateTime.INPUT_FORMAT_STRING" + }, + { + name: "Input timezone", + type: "option", + value: "DateTime.TIMEZONES" + }, + ] + }, + "Convert distance": { + module: "Default", + description: "Converts a unit of distance to another format.", + inputType: "BigNumber", + outputType: "BigNumber", + args: [ + { + name: "Input units", + type: "option", + value: "Convert.DISTANCE_UNITS" + }, + { + name: "Output units", + type: "option", + value: "Convert.DISTANCE_UNITS" + } + ] + }, + "Convert area": { + module: "Default", + description: "Converts a unit of area to another format.", + inputType: "BigNumber", + outputType: "BigNumber", + args: [ + { + name: "Input units", + type: "option", + value: "Convert.AREA_UNITS" + }, + { + name: "Output units", + type: "option", + value: "Convert.AREA_UNITS" + } + ] + }, + "Convert mass": { + module: "Default", + description: "Converts a unit of mass to another format.", + inputType: "BigNumber", + outputType: "BigNumber", + args: [ + { + name: "Input units", + type: "option", + value: "Convert.MASS_UNITS" + }, + { + name: "Output units", + type: "option", + value: "Convert.MASS_UNITS" + } + ] + }, + "Convert speed": { + module: "Default", + description: "Converts a unit of speed to another format.", + inputType: "BigNumber", + outputType: "BigNumber", + args: [ + { + name: "Input units", + type: "option", + value: "Convert.SPEED_UNITS" + }, + { + name: "Output units", + type: "option", + value: "Convert.SPEED_UNITS" + } + ] + }, + "Convert data units": { + module: "Default", + description: "Converts a unit of data to another format.", + inputType: "BigNumber", + outputType: "BigNumber", + args: [ + { + name: "Input units", + type: "option", + value: "Convert.DATA_UNITS" + }, + { + name: "Output units", + type: "option", + value: "Convert.DATA_UNITS" + } + ] + }, + "Raw Deflate": { + module: "Compression", + description: "Compresses data using the deflate algorithm with no headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Compression type", + type: "option", + value: "Compress.COMPRESSION_TYPE" + } + ] + }, + "Raw Inflate": { + module: "Compression", + description: "Decompresses data which has been compressed using the deflate algorithm with no headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Start index", + type: "number", + value: "Compress.INFLATE_INDEX" + }, + { + name: "Initial output buffer size", + type: "number", + value: "Compress.INFLATE_BUFFER_SIZE" + }, + { + name: "Buffer expansion type", + type: "option", + value: "Compress.INFLATE_BUFFER_TYPE" + }, + { + name: "Resize buffer after decompression", + type: "boolean", + value: "Compress.INFLATE_RESIZE" + }, + { + name: "Verify result", + type: "boolean", + value: "Compress.INFLATE_VERIFY" + } + ] + }, + "Zlib Deflate": { + module: "Compression", + description: "Compresses data using the deflate algorithm adding zlib headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Compression type", + type: "option", + value: "Compress.COMPRESSION_TYPE" + } + ] + }, + "Zlib Inflate": { + module: "Compression", + description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Start index", + type: "number", + value: "Compress.INFLATE_INDEX" + }, + { + name: "Initial output buffer size", + type: "number", + value: "Compress.INFLATE_BUFFER_SIZE" + }, + { + name: "Buffer expansion type", + type: "option", + value: "Compress.INFLATE_BUFFER_TYPE" + }, + { + name: "Resize buffer after decompression", + type: "boolean", + value: "Compress.INFLATE_RESIZE" + }, + { + name: "Verify result", + type: "boolean", + value: "Compress.INFLATE_VERIFY" + } + ], + patterns: [ + { + match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)", + flags: "", + args: [0, 0, "Adaptive", false, false] + }, + ] + }, + "Gzip": { + module: "Compression", + description: "Compresses data using the deflate algorithm with gzip headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Compression type", + type: "option", + value: "Compress.COMPRESSION_TYPE" + }, + { + name: "Filename (optional)", + type: "string", + value: "" + }, + { + name: "Comment (optional)", + type: "string", + value: "" + }, + { + name: "Include file checksum", + type: "boolean", + value: "Compress.GZIP_CHECKSUM" + } + ] + }, + "Gunzip": { + module: "Compression", + description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.", + inputType: "byteArray", + outputType: "byteArray", + args: [], + patterns: [ + { + match: "^\\x1f\\x8b\\x08", + flags: "", + args: [] + }, + ] + }, + "Zip": { + module: "Compression", + description: "Compresses data using the PKZIP algorithm with the given filename.

No support for multiple files at this time.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Filename", + type: "string", + value: "Compress.PKZIP_FILENAME" + }, + { + name: "Comment", + type: "string", + value: "" + }, + { + name: "Password", + type: "binaryString", + value: "" + }, + { + name: "Compression method", + type: "option", + value: "Compress.COMPRESSION_METHOD" + }, + { + name: "Operating system", + type: "option", + value: "Compress.OS" + }, + { + name: "Compression type", + type: "option", + value: "Compress.COMPRESSION_TYPE" + } + ] + }, + "Unzip": { + module: "Compression", + description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.", + inputType: "byteArray", + outputType: "html", + args: [ + { + name: "Password", + type: "binaryString", + value: "" + }, + { + name: "Verify result", + type: "boolean", + value: "Compress.PKUNZIP_VERIFY" + } + ], + patterns: [ + { + match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)", + flags: "", + args: ["", false] + }, + ] + }, + "Bzip2 Decompress": { + module: "Compression", + description: "Decompresses data using the Bzip2 algorithm.", + inputType: "byteArray", + outputType: "string", + args: [], + patterns: [ + { + match: "^\\x42\\x5a\\x68", + flags: "", + args: [] + }, + ] + }, + "Generic Code Beautify": { + module: "Code", + description: "Attempts to pretty print C-style languages such as C, C++, C#, Java, PHP, JavaScript etc.

This will not do a perfect job, and the resulting code may not work any more. This operation is designed purely to make obfuscated or minified code more easy to read and understand.

Things which will not work properly:
  • For loop formatting
  • Do-While loop formatting
  • Switch/Case indentation
  • Certain bit shift operators
", + inputType: "string", + outputType: "string", + args: [] + }, + "JavaScript Parser": { + module: "Code", + description: "Returns an Abstract Syntax Tree for valid JavaScript code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Location info", + type: "boolean", + value: "JS.PARSE_LOC" + }, + { + name: "Range info", + type: "boolean", + value: "JS.PARSE_RANGE" + }, + { + name: "Include tokens array", + type: "boolean", + value: "JS.PARSE_TOKENS" + }, + { + name: "Include comments array", + type: "boolean", + value: "JS.PARSE_COMMENT" + }, + { + name: "Report errors and try to continue", + type: "boolean", + value: "JS.PARSE_TOLERANT" + }, + ] + }, + "JavaScript Beautify": { + module: "Code", + description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).", + inputType: "string", + outputType: "string", + args: [ + { + name: "Indent string", + type: "binaryShortString", + value: "JS.BEAUTIFY_INDENT" + }, + { + name: "Quotes", + type: "option", + value: "JS.BEAUTIFY_QUOTES" + }, + { + name: "Semicolons before closing braces", + type: "boolean", + value: "JS.BEAUTIFY_SEMICOLONS" + }, + { + name: "Include comments", + type: "boolean", + value: "JS.BEAUTIFY_COMMENT" + }, + ] + }, + "JavaScript Minify": { + module: "Code", + description: "Compresses JavaScript code.", + inputType: "string", + outputType: "string", + args: [] + }, + "XML Beautify": { + module: "Code", + description: "Indents and prettifies eXtensible Markup Language (XML) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Indent string", + type: "binaryShortString", + value: "Code.BEAUTIFY_INDENT" + } + ] + }, + "JSON Beautify": { + module: "Code", + description: "Indents and prettifies JavaScript Object Notation (JSON) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Indent string", + type: "binaryShortString", + value: "Code.BEAUTIFY_INDENT" + } + ] + }, + "CSS Beautify": { + module: "Code", + description: "Indents and prettifies Cascading Style Sheets (CSS) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Indent string", + type: "binaryShortString", + value: "Code.BEAUTIFY_INDENT" + } + ] + }, + "SQL Beautify": { + module: "Code", + description: "Indents and prettifies Structured Query Language (SQL) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Indent string", + type: "binaryShortString", + value: "Code.BEAUTIFY_INDENT" + } + ] + }, + "XML Minify": { + module: "Code", + description: "Compresses eXtensible Markup Language (XML) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Preserve comments", + type: "boolean", + value: "Code.PRESERVE_COMMENTS" + } + ] + }, + "JSON Minify": { + module: "Code", + description: "Compresses JavaScript Object Notation (JSON) code.", + inputType: "string", + outputType: "string", + args: [] + }, + "CSS Minify": { + module: "Code", + description: "Compresses Cascading Style Sheets (CSS) code.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Preserve comments", + type: "boolean", + value: "Code.PRESERVE_COMMENTS" + } + ] + }, + "SQL Minify": { + module: "Code", + description: "Compresses Structured Query Language (SQL) code.", + inputType: "string", + outputType: "string", + args: [] + }, + "Analyse hash": { + module: "Hashing", + description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.", + inputType: "string", + outputType: "string", + args: [] + }, + "MD2": { + module: "Hashing", + description: "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.

Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "MD4": { + module: "Hashing", + description: "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.

The security of MD4 has been severely compromised.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "MD5": { + module: "Hashing", + description: "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.

However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "MD6": { + module: "Hashing", + description: "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Size", + type: "number", + value: "Hash.MD6_SIZE" + }, + { + name: "Levels", + type: "number", + value: "Hash.MD6_LEVELS" + }, + { + name: "Key", + type: "string", + value: "" + } + ] + }, + "SHA0": { + module: "Hashing", + description: "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "SHA1": { + module: "Hashing", + description: "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.

However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "SHA2": { + module: "Hashing", + description: "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.

  • SHA-512 operates on 64-bit words.
  • SHA-256 operates on 32-bit words.
  • SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.
  • SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.
  • SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.
", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Size", + type: "option", + value: "Hash.SHA2_SIZE" + } + ] + }, + "SHA3": { + module: "Hashing", + description: "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.

SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Size", + type: "option", + value: "Hash.SHA3_SIZE" + } + ] + }, + "Keccak": { + module: "Hashing", + description: "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún. It was selected as the winner of the SHA-3 design competition.

This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Size", + type: "option", + value: "Hash.KECCAK_SIZE" + } + ] + }, + "Shake": { + module: "Hashing", + description: "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Capacity", + type: "option", + value: "Hash.SHAKE_CAPACITY" + }, + { + name: "Size", + type: "number", + value: "Hash.SHAKE_SIZE" + } + ] + + }, + "RIPEMD": { + module: "Hashing", + description: "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.

RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.

", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Size", + type: "option", + value: "Hash.RIPEMD_SIZE" + } + ] + }, + "HAS-160": { + module: "Hashing", + description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.

HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.

The message digest algorithm consists of 80 rounds.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "Whirlpool": { + module: "Hashing", + description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.

Several variants exist:
  • Whirlpool-0 is the original version released in 2000.
  • Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.
  • Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.
", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Variant", + type: "option", + value: "Hash.WHIRLPOOL_VARIANT" + } + ] + }, + "Snefru": { + module: "Hashing", + description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.

The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Rounds", + type: "option", + value: "Hash.SNEFRU_ROUNDS" + }, + { + name: "Size", + type: "option", + value: "Hash.SNEFRU_SIZE" + } + ] + }, + "SSDEEP": { + module: "Hashing", + description: "SSDEEP is a program for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

SSDEEP hashes are now widely used for simple identification purposes (e.g. the 'Basic Properties' section in VirusTotal). Although 'better' fuzzy hashes are available, SSDEEP is still one of the primary choices because of its speed and being a de facto standard.

This operation is fundamentally the same as the CTPH operation, however their outputs differ in format.", + inputType: "string", + outputType: "string", + args: [] + }, + "CTPH": { + module: "Hashing", + description: "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'.", + inputType: "string", + outputType: "string", + args: [] + }, + "Compare SSDEEP hashes": { + module: "Hashing", + description: "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", + inputType: "string", + outputType: "Number", + args: [ + { + name: "Delimiter", + type: "option", + value: "Hash.DELIM_OPTIONS" + } + ] + }, + "Compare CTPH hashes": { + module: "Hashing", + description: "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", + inputType: "string", + outputType: "Number", + args: [ + { + name: "Delimiter", + type: "option", + value: "Hash.DELIM_OPTIONS" + } + ] + }, + "HMAC": { + module: "Hashing", + description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Key", + type: "binaryString", + value: "" + }, + { + name: "Hashing function", + type: "option", + value: "Hash.HMAC_FUNCTIONS" + }, + ] + }, + "Fletcher-8 Checksum": { + module: "Hashing", + description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "Fletcher-16 Checksum": { + module: "Hashing", + description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "Fletcher-32 Checksum": { + module: "Hashing", + description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "Fletcher-64 Checksum": { + module: "Hashing", + description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "Adler-32 Checksum": { + module: "Hashing", + description: "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).

Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "CRC-32 Checksum": { + module: "Hashing", + description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "CRC-16 Checksum": { + module: "Hashing", + description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "Generate all hashes": { + module: "Hashing", + description: "Generates all available hashes and checksums for the input.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "Entropy": { + module: "Default", + description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.", + inputType: "byteArray", + outputType: "html", + args: [ + { + name: "Chunk size", + type: "number", + value: "Entropy.CHUNK_SIZE" + } + ] + }, + "Frequency distribution": { + module: "Default", + description: "Displays the distribution of bytes in the data as a graph.", + inputType: "ArrayBuffer", + outputType: "html", + args: [ + { + name: "Show 0%'s", + type: "boolean", + value: "Entropy.FREQ_ZEROS" + } + ] + }, + "Chi Square": { + module: "Default", + description: "Calculates the Chi-Squared distribution of values.", + inputType: "ArrayBuffer", + outputType: "number", + args: [] + }, + "Numberwang": { + module: "Default", + description: "Based on the popular gameshow by Mitchell and Webb.", + inputType: "string", + outputType: "string", + args: [] + }, + "Parse X.509 certificate": { + module: "PublicKey", + description: "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.

This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool.

Tags: X509, server hello, handshake", + inputType: "string", + outputType: "string", + args: [ + { + name: "Input format", + type: "option", + value: "PublicKey.X509_INPUT_FORMAT" + } + ], + patterns: [ + { + match: "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$", + flags: "i", + args: ["PEM"] + }, + ] + }, + "PEM to Hex": { + module: "PublicKey", + description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.", + inputType: "string", + outputType: "string", + args: [] + }, + "Hex to PEM": { + module: "PublicKey", + description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Header string", + type: "string", + value: "PublicKey.PEM_HEADER_STRING" + } + ] + }, + "Hex to Object Identifier": { + module: "PublicKey", + description: "Converts a hexadecimal string into an object identifier (OID).", + inputType: "string", + outputType: "string", + args: [] + }, + "Object Identifier to Hex": { + module: "PublicKey", + description: "Converts an object identifier (OID) into a hexadecimal string.", + inputType: "string", + outputType: "string", + args: [] + }, + "Parse ASN.1 hex string": { + module: "PublicKey", + description: "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.

This operation parses arbitrary ASN.1 data and presents the resulting tree.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Starting index", + type: "number", + value: 0 + }, + { + name: "Truncate octet strings longer than", + type: "number", + value: "PublicKey.ASN1_TRUNCATE_LENGTH" + } + ] + }, + "Detect File Type": { + module: "Default", + description: "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.

Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "Scan for Embedded Files": { + module: "Default", + description: "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.

WARNING: Files over about 100KB in size will take a VERY long time to process.", + inputType: "ArrayBuffer", + outputType: "string", + args: [ + { + name: "Ignore common byte sequences", + type: "boolean", + value: "FileType.IGNORE_COMMON_BYTE_SEQUENCES" + } + ] + }, + "Expand alphabet range": { + module: "Default", + description: "Expand an alphabet range string into a list of the characters in that range.

e.g. a-z becomes abcdefghijklmnopqrstuvwxyz.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "binaryString", + value: "" + } + ] + }, + "Diff": { + module: "Diff", + description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.", + inputType: "string", + outputType: "html", + args: [ + { + name: "Sample delimiter", + type: "binaryString", + value: "Diff.DIFF_SAMPLE_DELIMITER" + }, + { + name: "Diff by", + type: "option", + value: "Diff.DIFF_BY" + }, + { + name: "Show added", + type: "boolean", + value: true + }, + { + name: "Show removed", + type: "boolean", + value: true + }, + { + name: "Ignore whitespace (relevant for word and line)", + type: "boolean", + value: false + } + ] + }, + "Parse UNIX file permissions": { + module: "Default", + description: "Given a UNIX/Linux file permission string in octal or textual format, this operation explains which permissions are granted to which user groups.

Input should be in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.", + inputType: "string", + outputType: "string", + args: [] + }, + "Swap endianness": { + module: "Default", + description: "Switches the data from big-endian to little-endian or vice-versa. Data can be read in as hexadecimal or raw bytes. It will be returned in the same format as it is entered.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "string", + args: [ + { + name: "Data format", + type: "option", + value: "Endian.DATA_FORMAT" + }, + { + name: "Word length (bytes)", + type: "number", + value: "Endian.WORD_LENGTH" + }, + { + name: "Pad incomplete words", + type: "boolean", + value: "Endian.PAD_INCOMPLETE_WORDS" + } + ] + }, + "Microsoft Script Decoder": { + module: "Default", + description: "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.

Sample

Encoded:
#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&@*eEI@#@&@#@&.jm.raY 214Wv:zms/obI0xEAAA==^#~@

Decoded:
var my_msg = "Testing <1><2><3>!";\n\nVScript.Echo(my_msg);", + inputType: "string", + outputType: "string", + args: [] + }, + "Syntax highlighter": { + module: "Code", + description: "Adds syntax highlighting to a range of source code languages. Note that this will not indent the code. Use one of the 'Beautify' operations for that.", + highlight: true, + highlightReverse: true, + inputType: "string", + outputType: "html", + args: [ + { + name: "Language", + type: "option", + value: "Code.LANGUAGES" + }, + ] + }, + "TCP/IP Checksum": { + module: "Hashing", + description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.", + inputType: "byteArray", + outputType: "string", + args: [] + }, + "Parse colour code": { + module: "Default", + description: "Converts a colour code in a standard format to other standard formats and displays the colour itself.

Example inputs
  • #d9edf7
  • rgba(217,237,247,1)
  • hsla(200,65%,91%,1)
  • cmyk(0.12, 0.04, 0.00, 0.03)
", + inputType: "string", + outputType: "html", + args: [] + }, + "Generate UUID": { + module: "Default", + description: "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).

A version 4 UUID relies on random numbers, in this case generated using window.crypto if available and falling back to Math.random if not.", + inputType: "string", + outputType: "string", + args: [] + }, + "Substitute": { + module: "Ciphers", + description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.

Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.

Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either \\n or \\x0a.

Byte ranges can be specified using a hyphen. For example, the sequence 0123456789 can be written as 0-9.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Plaintext", + type: "binaryString", + value: "Cipher.SUBS_PLAINTEXT" + }, + { + name: "Ciphertext", + type: "binaryString", + value: "Cipher.SUBS_CIPHERTEXT" + } + ] + }, + "Escape string": { + module: "Default", + description: "Escapes special characters in a string so that they do not cause conflicts. For example, Don't stop me now becomes Don\\'t stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", + inputType: "string", + outputType: "string", + args: [ + { + name: "Escape level", + type: "option", + value: "StrUtils.ESCAPE_LEVEL" + }, + { + name: "Escape quote", + type: "option", + value: "StrUtils.QUOTE_TYPES" + }, + { + name: "JSON compatible", + type: "boolean", + value: false + }, + { + name: "ES6 compatible", + type: "boolean", + value: true + }, + { + name: "Uppercase hex", + type: "boolean", + value: false + } + ] + }, + "Unescape string": { + module: "Default", + description: "Unescapes characters in a string that have been escaped. For example, Don\\'t stop me now becomes Don't stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", + inputType: "string", + outputType: "string", + args: [] + }, + "To Morse Code": { + module: "Default", + description: "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ...", + inputType: "string", + outputType: "string", + args: [ + { + name: "Format options", + type: "option", + value: "MorseCode.FORMAT_OPTIONS" + }, + { + name: "Letter delimiter", + type: "option", + value: "MorseCode.LETTER_DELIM_OPTIONS" + }, + { + name: "Word delimiter", + type: "option", + value: "MorseCode.WORD_DELIM_OPTIONS" + } + ] + }, + "From Morse Code": { + module: "Default", + description: "Translates Morse Code into (upper case) alphanumeric characters.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Letter delimiter", + type: "option", + value: "MorseCode.LETTER_DELIM_OPTIONS" + }, + { + name: "Word delimiter", + type: "option", + value: "MorseCode.WORD_DELIM_OPTIONS" + } + ], + patterns: [ + { + match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)", + flags: "i", + args: ["Space", "Line feed"] + }, + ] + }, + "Tar": { + module: "Compression", + description: "Packs the input into a tarball.

No support for multiple files at this time.", + inputType: "byteArray", + outputType: "byteArray", + args: [ + { + name: "Filename", + type: "string", + value: "Compress.TAR_FILENAME" + } + ] + }, + "Untar": { + module: "Compression", + description: "Unpacks a tarball and displays it per file.", + inputType: "byteArray", + outputType: "html", + args: [], + patterns: [ + { + match: "^.{257}\\x75\\x73\\x74\\x61\\x72", + flags: "", + args: [] + }, + ] + }, + "Head": { + module: "Default", + description: [ + "Like the UNIX head utility.", + "
", + "Gets the first n lines.", + "
", + "You can select all but the last n lines by entering a negative value for n.", + "
", + "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "StrUtils.DELIMITER_OPTIONS" + }, + { + name: "Number", + type: "number", + value: 10, + }, + ] + }, + "Tail": { + module: "Default", + description: [ + "Like the UNIX tail utility.", + "
", + "Gets the last n lines.", + "
", + "Optionally you can select all lines after line n by entering a negative value for n.", + "
", + "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: "StrUtils.DELIMITER_OPTIONS" + }, + { + name: "Number", + type: "number", + value: 10, + }, + ] + }, + "To Snake case": { + module: "Code", + description: [ + "Converts the input string to snake case.", + "

", + "Snake case is all lower case with underscores as word boundaries.", + "

", + "e.g. this_is_snake_case", + "

", + "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Attempt to be context aware", + type: "boolean", + value: false, + }, + ] + }, + "To Camel case": { + module: "Code", + description: [ + "Converts the input string to camel case.", + "

", + "Camel case is all lower case except letters after word boundaries which are uppercase.", + "

", + "e.g. thisIsCamelCase", + "

", + "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Attempt to be context aware", + type: "boolean", + value: false, + }, + ] + }, + "To Kebab case": { + module: "Code", + description: [ + "Converts the input string to kebab case.", + "

", + "Kebab case is all lower case with dashes as word boundaries.", + "

", + "e.g. this-is-kebab-case", + "

", + "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Attempt to be context aware", + type: "boolean", + value: false, + }, + ] + }, + "Extract EXIF": { + module: "Image", + description: [ + "Extracts EXIF data from an image.", + "

", + "EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.", + "

", + "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.", + ].join("\n"), + inputType: "ArrayBuffer", + outputType: "string", + args: [], + }, + "Render Image": { + module: "Image", + description: "Displays the input as an image. Supports the following formats:

  • jpg/jpeg
  • png
  • gif
  • webp
  • bmp
  • ico
", + inputType: "string", + outputType: "html", + args: [ + { + name: "Input format", + type: "option", + value: "Image.INPUT_FORMAT" + } + ], + patterns: [ + { + match: "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)", + flags: "", + args: ["Raw"], + useful: true + }, + ] + }, + "Remove EXIF": { + module: "Image", + description: [ + "Removes EXIF data from a JPEG image.", + "

", + "EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.", + ].join("\n"), + inputType: "byteArray", + outputType: "byteArray", + args: [] + }, + "HTTP request": { + module: "HTTP", + description: [ + "Makes an HTTP request and returns the response.", + "

", + "This operation supports different HTTP verbs like GET, POST, PUT, etc.", + "

", + "You can add headers line by line in the format Key: Value", + "

", + "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.", + ].join("\n"), + inputType: "string", + outputType: "string", + manualBake: true, + args: [ + { + name: "Method", + type: "option", + value: "HTTP.METHODS," + }, + { + name: "URL", + type: "string", + value: "", + }, + { + name: "Headers", + type: "text", + value: "", + }, + { + name: "Mode", + type: "option", + value: "HTTP.MODE," + }, + { + name: "Show response metadata", + type: "boolean", + value: false, + } + ] + }, + "From BCD": { + module: "Default", + description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.", + inputType: "string", + outputType: "BigNumber", + args: [ + { + name: "Scheme", + type: "option", + value: "BCD.ENCODING_SCHEME" + }, + { + name: "Packed", + type: "boolean", + value: true + }, + { + name: "Signed", + type: "boolean", + value: false + }, + { + name: "Input format", + type: "option", + value: "BCD.FORMAT" + } + ], + patterns: [ + { + match: "^(?:\\d{4} ){3,}\\d{4}$", + flags: "", + args: ["8 4 2 1", true, false, "Nibbles"] + }, + ] + }, + "To BCD": { + module: "Default", + description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign", + inputType: "BigNumber", + outputType: "string", + args: [ + { + name: "Scheme", + type: "option", + value: "BCD.ENCODING_SCHEME" + }, + { + name: "Packed", + type: "boolean", + value: true + }, + { + name: "Signed", + type: "boolean", + value: false + }, + { + name: "Output format", + type: "option", + value: "BCD.FORMAT" + } + ] + + }, + "Bit shift left": { + module: "Default", + description: "Shifts the bits in each byte towards the left by the specified amount.", + inputType: "byteArray", + outputType: "byteArray", + highlight: true, + highlightReverse: true, + args: [ + { + name: "Amount", + type: "number", + value: 1 + }, + ] + }, + "Bit shift right": { + module: "Default", + description: "Shifts the bits in each byte towards the right by the specified amount.

Logical shifts replace the leftmost bits with zeros.
Arithmetic shifts preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative).", + inputType: "byteArray", + outputType: "byteArray", + highlight: true, + highlightReverse: true, + args: [ + { + name: "Amount", + type: "number", + value: 1 + }, + { + name: "Type", + type: "option", + value: "BitwiseOp.BIT_SHIFT_TYPE" + } + ] + }, + "Generate TOTP": { + module: "Default", + description: "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds.", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Name", + type: "string", + value: "" + }, + { + name: "Key size", + type: "number", + value: 32 + }, + { + name: "Code length", + type: "number", + value: 6 + }, + { + name: "Epoch offset (T0)", + type: "number", + value: 0 + }, + { + name: "Interval (T1)", + type: "number", + value: 30 + } + ] + }, + "Generate HOTP": { + module: "Default", + description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated.", + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Name", + type: "string", + value: "" + }, + { + name: "Key size", + type: "number", + value: 32 + }, + { + name: "Code length", + type: "number", + value: 6 + }, + { + name: "Counter", + type: "number", + value: 0 + } + ] + }, + "PHP Deserialize": { + module: "Default", + description: "Deserializes PHP serialized data, outputting keyed arrays as JSON.

This function does not support object tags.

Example:
a:2:{s:1:"a";i:10;i:0;a:1:{s:2:"ab";b:1;}}
becomes
{"a": 10,0: {"ab": true}}

Output valid JSON: JSON doesn't support integers as keys, whereas PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Output valid JSON", + type: "boolean", + value: "PHP.OUTPUT_VALID_JSON" + } + ] + }, + "Hamming Distance": { + module: "Default", + description: "In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other. In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Delimiter", + type: "binaryShortString", + value: "StrUtils.HAMMING_DELIM" + }, + { + name: "Unit", + type: "option", + value: "StrUtils.HAMMING_UNIT" + }, + { + name: "Input type", + type: "option", + value: "StrUtils.HAMMING_INPUT_TYPE" + } + ] + }, + "XKCD Random Number": { + module: "Default", + description: "RFC 1149.5 specifies 4 as the standard IEEE-vetted random number.

XKCD #221", + inputType: "string", + outputType: "number", + args: [] + }, + "Bcrypt": { + module: "Hashing", + description: "bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

Enter the password in the input to generate its hash.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Rounds", + type: "number", + value: "Hash.BCRYPT_ROUNDS" + } + ] + }, + "Bcrypt compare": { + module: "Hashing", + description: "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Hash", + type: "string", + value: "" + } + ] + }, + "Bcrypt parse": { + module: "Hashing", + description: "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash.", + inputType: "string", + outputType: "string", + args: [] + }, + "Scrypt": { + module: "Hashing", + description: "scrypt is a password-based key derivation function (PBKDF) created by Colin Percival. The algorithm was specifically designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory. In 2016, the scrypt algorithm was published by IETF as RFC 7914.

Enter the password in the input to generate its hash.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Salt", + type: "toggleString", + value: "", + toggleValues: "Hash.KEY_FORMAT" + }, + { + name: "Iterations (N)", + type: "number", + value: "Hash.SCRYPT_ITERATIONS" + }, + { + name: "Memory factor (r)", + type: "number", + value: "Hash.SCRYPT_MEM_FACTOR" + }, + { + name: "Parallelization factor (p)", + type: "number", + value: "Hash.SCRYPT_PARALLEL_FACTOR" + }, + { + name: "Key length", + type: "number", + value: "Hash.SCRYPT_KEY_LENGTH" + }, + ] + }, + "BSON serialise": { + module: "BSON", + description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be valid JSON.", + inputType: "string", + outputType: "ArrayBuffer", + args: [] + }, + "BSON deserialise": { + module: "BSON", + description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be in a raw bytes format.", + inputType: "ArrayBuffer", + outputType: "string", + args: [] + }, + "Generate PGP Key Pair": { + module: "PGP", + description: "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.", + inputType: "string", + outputType: "string", + args: [ + { + name: "Key type", + type: "option", + value: "PGP.KEY_TYPES" + }, + { + name: "Password (optional)", + type: "string", + value: "" + }, + { + name: "Name (optional)", + type: "string", + value: "" + }, + { + name: "Email (optional)", + type: "string", + value: "" + }, + ] + }, + "PGP Encrypt": { + module: "PGP", + description: [ + "Input: the message you want to encrypt.", + "

", + "Arguments: the ASCII-armoured PGP public key of the recipient.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Public key of recipient", + type: "text", + value: "" + }, + ] + }, + "PGP Decrypt": { + module: "PGP", + description: [ + "Input: the ASCII-armoured PGP message you want to decrypt.", + "

", + "Arguments: the ASCII-armoured PGP private key of the recipient, ", + "(and the private key password if necessary).", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Private key of recipient", + type: "text", + value: "" + }, + { + name: "Private key passphrase", + type: "string", + value: "" + }, + ] + }, + "PGP Encrypt and Sign": { + module: "PGP", + description: [ + "Input: the cleartext you want to sign.", + "

", + "Arguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)", + "and the ASCII-armoured PGP public key of the recipient.", + "

", + "This operation uses PGP to produce an encrypted digital signature.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Private key of signer", + type: "text", + value: "" + }, + { + name: "Private key passphrase", + type: "string", + value: "" + }, + { + name: "Public key of recipient", + type: "text", + value: "" + }, + ] + }, + "PGP Decrypt and Verify": { + module: "PGP", + description: [ + "Input: the ASCII-armoured encrypted PGP message you want to verify.", + "

", + "Arguments: the ASCII-armoured PGP public key of the signer, ", + "the ASCII-armoured private key of the recipient (and the private key password if necessary).", + "

", + "This operation uses PGP to decrypt and verify an encrypted digital signature.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"), + inputType: "string", + outputType: "string", + args: [ + { + name: "Public key of signer", + type: "text", + value: "", + }, + { + name: "Private key of recipient", + type: "text", + value: "", + }, + { + name: "Private key password", + type: "string", + value: "", + }, + ] + }, +}; + +main(); diff --git a/src/core/errors/OperationError.mjs b/src/core/errors/OperationError.mjs index 71405718..cffd0607 100644 --- a/src/core/errors/OperationError.mjs +++ b/src/core/errors/OperationError.mjs @@ -15,6 +15,8 @@ class OperationError extends Error { constructor(...args) { super(...args); + this.type = "OperationError"; + if (Error.captureStackTrace) { Error.captureStackTrace(this, OperationError); } diff --git a/src/core/lib/Arithmetic.mjs b/src/core/lib/Arithmetic.mjs new file mode 100644 index 00000000..3ee2372f --- /dev/null +++ b/src/core/lib/Arithmetic.mjs @@ -0,0 +1,139 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmailcom] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Utils from "../Utils"; +import BigNumber from "bignumber.js"; + + +/** + * Converts a string array to a number array. + * + * @param {string[]} input + * @param {string} delim + * @returns {BigNumber[]} + */ +export function createNumArray(input, delim) { + delim = Utils.charRep(delim || "Space"); + const splitNumbers = input.split(delim); + const numbers = []; + let num; + + splitNumbers.map((number) => { + try { + num = BigNumber(number.trim()); + if (!num.isNaN()) { + numbers.push(num); + } + } catch (err) { + // This line is not a valid number + } + }); + return numbers; +} + + +/** + * Adds an array of numbers and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function sum(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc.plus(curr)); + } +} + + +/** + * Subtracts an array of numbers and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function sub(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc.minus(curr)); + } +} + + +/** + * Multiplies an array of numbers and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function multi(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc.times(curr)); + } +} + + +/** + * Divides an array of numbers and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function div(data) { + if (data.length > 0) { + return data.reduce((acc, curr) => acc.div(curr)); + } +} + + +/** + * Computes mean of a number array and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function mean(data) { + if (data.length > 0) { + return sum(data).div(data.length); + } +} + + +/** + * Computes median of a number array and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function median(data) { + if ((data.length % 2) === 0 && data.length > 0) { + data.sort(function(a, b){ + return a.minus(b); + }); + const first = data[Math.floor(data.length / 2)]; + const second = data[Math.floor(data.length / 2) - 1]; + return mean([first, second]); + } else { + return data[Math.floor(data.length / 2)]; + } +} + + +/** + * Computes standard deviation of a number array and returns the value. + * + * @param {BigNumber[]} data + * @returns {BigNumber} + */ +export function stdDev(data) { + if (data.length > 0) { + const avg = mean(data); + let devSum = new BigNumber(0); + data.map((datum) => { + devSum = devSum.plus(datum.minus(avg).pow(2)); + }); + return devSum.div(data.length).sqrt(); + } +} diff --git a/src/core/lib/BCD.mjs b/src/core/lib/BCD.mjs new file mode 100755 index 00000000..623a90c7 --- /dev/null +++ b/src/core/lib/BCD.mjs @@ -0,0 +1,48 @@ +/** + * Binary Code Decimal resources. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +/** + * BCD encoding schemes. + */ +export const ENCODING_SCHEME = [ + "8 4 2 1", + "7 4 2 1", + "4 2 2 1", + "2 4 2 1", + "8 4 -2 -1", + "Excess-3", + "IBM 8 4 2 1", +]; + +/** + * Lookup table for the binary value of each digit representation. + * + * I wrote a very nice algorithm to generate 8 4 2 1 encoding programatically, + * but unfortunately it's much easier (if less elegant) to use lookup tables + * when supporting multiple encoding schemes. + * + * "Practicality beats purity" - PEP 20 + * + * In some schemes it is possible to represent the same value in multiple ways. + * For instance, in 4 2 2 1 encoding, 0100 and 0010 both represent 2. Support + * has not yet been added for this. + */ +export const ENCODING_LOOKUP = { + "8 4 2 1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + "7 4 2 1": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10], + "4 2 2 1": [0, 1, 4, 5, 8, 9, 12, 13, 14, 15], + "2 4 2 1": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15], + "8 4 -2 -1": [0, 7, 6, 5, 4, 11, 10, 9, 8, 15], + "Excess-3": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12], + "IBM 8 4 2 1": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9], +}; + +/** + * BCD formats. + */ +export const FORMAT = ["Nibbles", "Bytes", "Raw"]; diff --git a/src/core/lib/Base58.mjs b/src/core/lib/Base58.mjs new file mode 100755 index 00000000..b4eb4b41 --- /dev/null +++ b/src/core/lib/Base58.mjs @@ -0,0 +1,22 @@ +/** + * Base58 resources. + * + * @author tlwr [toby@toby.codes] + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +/** + * Base58 alphabet options. + */ +export const ALPHABET_OPTIONS = [ + { + name: "Bitcoin", + value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + }, + { + name: "Ripple", + value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", + }, +]; diff --git a/src/core/lib/CanvasComponents.mjs b/src/core/lib/CanvasComponents.mjs new file mode 100755 index 00000000..04664c3d --- /dev/null +++ b/src/core/lib/CanvasComponents.mjs @@ -0,0 +1,204 @@ +/** + * Various components for drawing diagrams on an HTML5 canvas. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Draws a line from one point to another + * + * @param ctx + * @param startX + * @param startY + * @param endX + * @param endY + */ +export function drawLine(ctx, startX, startY, endX, endY) { + ctx.beginPath(); + ctx.moveTo(startX, startY); + ctx.lineTo(endX, endY); + ctx.closePath(); + ctx.stroke(); +} + +/** + * Draws a bar chart on the canvas. + * + * @param canvas + * @param scores + * @param xAxisLabel + * @param yAxisLabel + * @param numXLabels + * @param numYLabels + * @param fontSize + */ +export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels, numYLabels, fontSize) { + fontSize = fontSize || 15; + if (!numXLabels || numXLabels > Math.round(canvas.width / 50)) { + numXLabels = Math.round(canvas.width / 50); + } + if (!numYLabels || numYLabels > Math.round(canvas.width / 50)) { + numYLabels = Math.round(canvas.height / 50); + } + + // Graph properties + const ctx = canvas.getContext("2d"), + leftPadding = canvas.width * 0.08, + rightPadding = canvas.width * 0.03, + topPadding = canvas.height * 0.08, + bottomPadding = canvas.height * 0.15, + graphHeight = canvas.height - topPadding - bottomPadding, + graphWidth = canvas.width - leftPadding - rightPadding, + base = topPadding + graphHeight, + ceil = topPadding; + + ctx.font = fontSize + "px Arial"; + + // Draw axis + ctx.lineWidth = "1.0"; + ctx.strokeStyle = "#444"; + drawLine(ctx, leftPadding, base, graphWidth + leftPadding, base); // x + drawLine(ctx, leftPadding, base, leftPadding, ceil); // y + + // Bar properties + const barPadding = graphWidth * 0.003, + barWidth = (graphWidth - (barPadding * scores.length)) / scores.length, + max = Math.max.apply(Math, scores); + let currX = leftPadding + barPadding; + + // Draw bars + ctx.fillStyle = "green"; + for (let i = 0; i < scores.length; i++) { + const h = scores[i] / max * graphHeight; + ctx.fillRect(currX, base - h, barWidth, h); + currX += barWidth + barPadding; + } + + // Mark x axis + ctx.fillStyle = "black"; + ctx.textAlign = "center"; + currX = leftPadding + barPadding; + if (numXLabels >= scores.length) { + // Mark every score + for (let i = 0; i <= scores.length; i++) { + ctx.fillText(i, currX, base + (bottomPadding * 0.3)); + currX += barWidth + barPadding; + } + } else { + // Mark some scores + for (let i = 0; i <= numXLabels; i++) { + const val = Math.ceil((scores.length / numXLabels) * i); + currX = (graphWidth / numXLabels) * i + leftPadding; + ctx.fillText(val, currX, base + (bottomPadding * 0.3)); + } + } + + // Mark y axis + ctx.textAlign = "right"; + let currY; + if (numYLabels >= max) { + // Mark every increment + for (let i = 0; i <= max; i++) { + currY = base - (i / max * graphHeight) + fontSize / 3; + ctx.fillText(i, leftPadding * 0.8, currY); + } + } else { + // Mark some increments + for (let i = 0; i <= numYLabels; i++) { + const val = Math.ceil((max / numYLabels) * i); + currY = base - (val / max * graphHeight) + fontSize / 3; + ctx.fillText(val, leftPadding * 0.8, currY); + } + } + + // Label x axis + if (xAxisLabel) { + ctx.textAlign = "center"; + ctx.fillText(xAxisLabel, graphWidth / 2 + leftPadding, base + bottomPadding * 0.8); + } + + // Label y axis + if (yAxisLabel) { + ctx.save(); + const x = leftPadding * 0.3, + y = graphHeight / 2 + topPadding; + ctx.translate(x, y); + ctx.rotate(-Math.PI / 2); + ctx.textAlign = "center"; + ctx.fillText(yAxisLabel, 0, 0); + ctx.restore(); + } +} + +/** + * Draws a scale bar on the canvas. + * + * @param canvas + * @param score + * @param max + * @param markings + */ +export function drawScaleBar(canvas, score, max, markings) { + // Bar properties + const ctx = canvas.getContext("2d"), + leftPadding = canvas.width * 0.01, + rightPadding = canvas.width * 0.01, + topPadding = canvas.height * 0.1, + bottomPadding = canvas.height * 0.3, + barHeight = canvas.height - topPadding - bottomPadding, + barWidth = canvas.width - leftPadding - rightPadding; + + // Scale properties + const proportion = score / max; + + // Draw bar outline + ctx.strokeRect(leftPadding, topPadding, barWidth, barHeight); + + // Shade in up to proportion + const grad = ctx.createLinearGradient(leftPadding, 0, barWidth + leftPadding, 0); + grad.addColorStop(0, "green"); + grad.addColorStop(0.5, "gold"); + grad.addColorStop(1, "red"); + ctx.fillStyle = grad; + ctx.fillRect(leftPadding, topPadding, barWidth * proportion, barHeight); + + // Add markings + let x0, y0, x1, y1; + ctx.fillStyle = "black"; + ctx.textAlign = "center"; + ctx.font = "13px Arial"; + for (let i = 0; i < markings.length; i++) { + // Draw min line down + x0 = barWidth / max * markings[i].min + leftPadding; + y0 = topPadding + barHeight + (bottomPadding * 0.1); + x1 = x0; + y1 = topPadding + barHeight + (bottomPadding * 0.3); + drawLine(ctx, x0, y0, x1, y1); + + // Draw max line down + x0 = barWidth / max * markings[i].max + leftPadding; + x1 = x0; + drawLine(ctx, x0, y0, x1, y1); + + // Join min and max lines + x0 = barWidth / max * markings[i].min + leftPadding; + y0 = topPadding + barHeight + (bottomPadding * 0.3); + x1 = barWidth / max * markings[i].max + leftPadding; + y1 = y0; + drawLine(ctx, x0, y0, x1, y1); + + // Add label + if (markings[i].max >= max * 0.9) { + ctx.textAlign = "right"; + x0 = x1; + } else if (markings[i].max <= max * 0.1) { + ctx.textAlign = "left"; + } else { + x0 = x0 + (x1 - x0) / 2; + } + y0 = topPadding + barHeight + (bottomPadding * 0.8); + ctx.fillText(markings[i].label, x0, y0); + } +} diff --git a/src/core/lib/ChrEnc.mjs b/src/core/lib/ChrEnc.mjs new file mode 100644 index 00000000..02b2e9a2 --- /dev/null +++ b/src/core/lib/ChrEnc.mjs @@ -0,0 +1,58 @@ +/** + * Character encoding resources. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Character encoding format mappings. + */ +export const IO_FORMAT = { + "UTF-8 (65001)": 65001, + "UTF-7 (65000)": 65000, + "UTF16LE (1200)": 1200, + "UTF16BE (1201)": 1201, + "UTF16 (1201)": 1201, + "IBM EBCDIC International (500)": 500, + "IBM EBCDIC US-Canada (37)": 37, + "Windows-874 Thai (874)": 874, + "Japanese Shift-JIS (932)": 932, + "Simplified Chinese GBK (936)": 936, + "Korean (949)": 949, + "Traditional Chinese Big5 (950)": 950, + "Windows-1250 Central European (1250)": 1250, + "Windows-1251 Cyrillic (1251)": 1251, + "Windows-1252 Latin (1252)": 1252, + "Windows-1253 Greek (1253)": 1253, + "Windows-1254 Turkish (1254)": 1254, + "Windows-1255 Hebrew (1255)": 1255, + "Windows-1256 Arabic (1256)": 1256, + "Windows-1257 Baltic (1257)": 1257, + "Windows-1258 Vietnam (1258)": 1258, + "US-ASCII (20127)": 20127, + "Simplified Chinese GB2312 (20936)": 20936, + "KOI8-R Russian Cyrillic (20866)": 20866, + "KOI8-U Ukrainian Cyrillic (21866)": 21866, + "ISO-8859-1 Latin 1 Western European (28591)": 28591, + "ISO-8859-2 Latin 2 Central European (28592)": 28592, + "ISO-8859-3 Latin 3 South European (28593)": 28593, + "ISO-8859-4 Latin 4 North European (28594)": 28594, + "ISO-8859-5 Latin/Cyrillic (28595)": 28595, + "ISO-8859-6 Latin/Arabic (28596)": 28596, + "ISO-8859-7 Latin/Greek (28597)": 28597, + "ISO-8859-8 Latin/Hebrew (28598)": 28598, + "ISO-8859-9 Latin 5 Turkish (28599)": 28599, + "ISO-8859-10 Latin 6 Nordic (28600)": 28600, + "ISO-8859-11 Latin/Thai (28601)": 28601, + "ISO-8859-13 Latin 7 Baltic Rim (28603)": 28603, + "ISO-8859-14 Latin 8 Celtic (28604)": 28604, + "ISO-8859-15 Latin 9 (28605)": 28605, + "ISO-8859-16 Latin 10 (28606)": 28606, + "ISO-2022 JIS Japanese (50222)": 50222, + "EUC Japanese (51932)": 51932, + "EUC Korean (51949)": 51949, + "Simplified Chinese GB18030 (54936)": 54936, +}; + diff --git a/src/core/lib/Ciphers.mjs b/src/core/lib/Ciphers.mjs new file mode 100644 index 00000000..3edd6983 --- /dev/null +++ b/src/core/lib/Ciphers.mjs @@ -0,0 +1,82 @@ +/** + * Cipher functions. + * + * @author Matt C [matt@artemisbot.uk] + * @author n1474335 [n1474335@gmail.com] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + * + */ + +import OperationError from "../errors/OperationError"; +import CryptoJS from "crypto-js"; + +/** + * Affine Cipher Encode operation. + * + * @author Matt C [matt@artemisbot.uk] + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ +export function affineEncode(input, args) { + const alphabet = "abcdefghijklmnopqrstuvwxyz", + a = args[0], + b = args[1]; + let output = ""; + + if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) { + throw new OperationError("The values of a and b can only be integers."); + } + + for (let i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + // Uses the affine function ax+b % m = y (where m is length of the alphabet) + output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26]; + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + // Same as above, accounting for uppercase + output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase(); + } else { + // Non-alphabetic characters + output += input[i]; + } + } + return output; +} + +/** + * Generates a polybius square for the given keyword + * + * @private + * @author Matt C [matt@artemisbot.uk] + * @param {string} keyword - Must be upper case + * @returns {string} + */ +export function genPolybiusSquare (keyword) { + const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ", + polArray = `${keyword}${alpha}`.split("").unique(), + polybius = []; + + for (let i = 0; i < 5; i++) { + polybius[i] = polArray.slice(i*5, i*5 + 5); + } + + return polybius; +} + +/** + * A mapping of string formats to their classes in the CryptoJS library. + * + * @private + * @constant + */ +export const format = { + "Hex": CryptoJS.enc.Hex, + "Base64": CryptoJS.enc.Base64, + "UTF8": CryptoJS.enc.Utf8, + "UTF16": CryptoJS.enc.Utf16, + "UTF16LE": CryptoJS.enc.Utf16LE, + "UTF16BE": CryptoJS.enc.Utf16BE, + "Latin1": CryptoJS.enc.Latin1, +}; diff --git a/src/core/lib/DateTime.mjs b/src/core/lib/DateTime.mjs new file mode 100644 index 00000000..89b0e3c6 --- /dev/null +++ b/src/core/lib/DateTime.mjs @@ -0,0 +1,313 @@ +/** + * DateTime resources. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * DateTime units. + */ +export const UNITS = ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"]; + +/** + * DateTime formats. + */ +export const DATETIME_FORMATS = [ + { + name: "Standard date and time", + value: "DD/MM/YYYY HH:mm:ss" + }, + { + name: "American-style date and time", + value: "MM/DD/YYYY HH:mm:ss" + }, + { + name: "International date and time", + value: "YYYY-MM-DD HH:mm:ss" + }, + { + name: "Verbose date and time", + value: "dddd Do MMMM YYYY HH:mm:ss Z z" + }, + { + name: "UNIX timestamp (seconds)", + value: "X" + }, + { + name: "UNIX timestamp offset (milliseconds)", + value: "x" + }, + { + name: "Automatic", + value: "" + }, +]; + +/** + * MomentJS DateTime formatting examples. + */ +export const FORMAT_EXAMPLES = `Format string tokens: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryTokenOutput
MonthM1 2 ... 11 12
Mo1st 2nd ... 11th 12th
MM01 02 ... 11 12
MMMJan Feb ... Nov Dec
MMMMJanuary February ... November December
QuarterQ1 2 3 4
Day of MonthD1 2 ... 30 31
Do1st 2nd ... 30th 31st
DD01 02 ... 30 31
Day of YearDDD1 2 ... 364 365
DDDo1st 2nd ... 364th 365th
DDDD001 002 ... 364 365
Day of Weekd0 1 ... 5 6
do0th 1st ... 5th 6th
ddSu Mo ... Fr Sa
dddSun Mon ... Fri Sat
ddddSunday Monday ... Friday Saturday
Day of Week (Locale)e0 1 ... 5 6
Day of Week (ISO)E1 2 ... 6 7
Week of Yearw1 2 ... 52 53
wo1st 2nd ... 52nd 53rd
ww01 02 ... 52 53
Week of Year (ISO)W1 2 ... 52 53
Wo1st 2nd ... 52nd 53rd
WW01 02 ... 52 53
YearYY70 71 ... 29 30
YYYY1970 1971 ... 2029 2030
Week Yeargg70 71 ... 29 30
gggg1970 1971 ... 2029 2030
Week Year (ISO)GG70 71 ... 29 30
GGGG1970 1971 ... 2029 2030
AM/PMAAM PM
aam pm
HourH0 1 ... 22 23
HH00 01 ... 22 23
h1 2 ... 11 12
hh01 02 ... 11 12
Minutem0 1 ... 58 59
mm00 01 ... 58 59
Seconds0 1 ... 58 59
ss00 01 ... 58 59
Fractional SecondS0 1 ... 8 9
SS00 01 ... 98 99
SSS000 001 ... 998 999
SSSS ... SSSSSSSSS000[0..] 001[0..] ... 998[0..] 999[0..]
Timezonez or zzEST CST ... MST PST
Z-07:00 -06:00 ... +06:00 +07:00
ZZ-0700 -0600 ... +0600 +0700
Unix TimestampX1360013296
Unix Millisecond Timestampx1360013296123
`; + diff --git a/src/core/lib/Delim.mjs b/src/core/lib/Delim.mjs new file mode 100644 index 00000000..192d3582 --- /dev/null +++ b/src/core/lib/Delim.mjs @@ -0,0 +1,69 @@ +/** + * Various delimiters + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +/** + * Generic sequence delimiters. + */ +export const DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"]; + +/** + * Binary sequence delimiters. + */ +export const BIN_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"]; + +/** + * Letter sequence delimiters. + */ +export const LETTER_DELIM_OPTIONS = ["Space", "Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"]; + +/** + * Word sequence delimiters. + */ +export const WORD_DELIM_OPTIONS = ["Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"]; + +/** + * Input sequence delimiters. + */ +export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"]; + +/** + * Armithmetic sequence delimiters + */ +export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"]; + +/** + * Hash delimiters + */ +export const HASH_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma"]; + +/** + * Split delimiters. + */ +export const SPLIT_DELIM_OPTIONS = [ + {name: "Comma", value: ","}, + {name: "Space", value: " "}, + {name: "Line feed", value: "\\n"}, + {name: "CRLF", value: "\\r\\n"}, + {name: "Semi-colon", value: ";"}, + {name: "Colon", value: ":"}, + {name: "Nothing (separate chars)", value: ""} +]; + +/** + * Join delimiters. + */ +export const JOIN_DELIM_OPTIONS = [ + {name: "Line feed", value: "\\n"}, + {name: "CRLF", value: "\\r\\n"}, + {name: "Space", value: " "}, + {name: "Comma", value: ","}, + {name: "Semi-colon", value: ";"}, + {name: "Colon", value: ":"}, + {name: "Nothing (join chars)", value: ""} +]; + diff --git a/src/core/lib/Extract.mjs b/src/core/lib/Extract.mjs new file mode 100644 index 00000000..ba57d758 --- /dev/null +++ b/src/core/lib/Extract.mjs @@ -0,0 +1,41 @@ +/** + * Identifier extraction functions + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + * + */ + +/** + * Runs search operations across the input data using regular expressions. + * + * @param {string} input + * @param {RegExp} searchRegex + * @param {RegExp} removeRegex - A regular expression defining results to remove from the + * final list + * @param {boolean} includeTotal - Whether or not to include the total number of results + * @returns {string} + */ +export function search (input, searchRegex, removeRegex, includeTotal) { + let output = "", + total = 0, + match; + + while ((match = searchRegex.exec(input))) { + // Moves pointer when an empty string is matched (prevents infinite loop) + if (match.index === searchRegex.lastIndex) { + searchRegex.lastIndex++; + } + + if (removeRegex && removeRegex.test(match[0])) + continue; + total++; + output += match[0] + "\n"; + } + + if (includeTotal) + output = "Total found: " + total + "\n\n" + output; + + return output; +} diff --git a/src/core/lib/FlowControl.mjs b/src/core/lib/FlowControl.mjs new file mode 100644 index 00000000..56679ece --- /dev/null +++ b/src/core/lib/FlowControl.mjs @@ -0,0 +1,20 @@ +/** + * Flow control functions + * + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +/** + * Returns the index of a label. + * + * @param {Object} state - The current state of the recipe. + * @param {string} name - The label name to look for. + * @returns {number} + */ +export function getLabelIndex(name, state) { + return state.opList.findIndex((operation) => { + return (operation.name === "Label") && (name === operation.ingValues[0]); + }); +} diff --git a/src/core/lib/Hash.mjs b/src/core/lib/Hash.mjs new file mode 100644 index 00000000..4af48d13 --- /dev/null +++ b/src/core/lib/Hash.mjs @@ -0,0 +1,28 @@ +/** + * Hashing resources. + * + * @author n1474335 [n1474335@gmail.com] + * + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Utils from "../Utils"; +import CryptoApi from "crypto-api/src/crypto-api"; + + +/** + * Generic hash function. + * + * @param {string} name + * @param {ArrayBuffer} input + * @param {Object} [options={}] + * @returns {string} + */ +export function runHash(name, input, options={}) { + const msg = Utils.arrayBufferToStr(input, false), + hasher = CryptoApi.getHasher(name, options); + hasher.update(msg); + return CryptoApi.encoder.toHex(hasher.finalize()); +} + diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 242d434a..538ba44b 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -84,9 +84,9 @@ export function toHexFast(data) { * fromHex("0a:14:1e", "Colon"); */ export function fromHex(data, delim, byteLen=2) { - delim = delim || (data.indexOf(" ") >= 0 ? "Space" : "None"); + delim = delim || "Auto"; if (delim !== "None") { - const delimRegex = Utils.regexRep(delim); + const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep(delim); data = data.replace(delimRegex, ""); } @@ -99,6 +99,12 @@ export function fromHex(data, delim, byteLen=2) { /** - * Hexadecimal delimiters. + * To Hexadecimal delimiters. */ -export const HEX_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"]; +export const TO_HEX_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"]; + + +/** + * From Hexadecimal delimiters. + */ +export const FROM_HEX_DELIM_OPTIONS = ["Auto"].concat(TO_HEX_DELIM_OPTIONS); diff --git a/src/core/lib/Magic.mjs b/src/core/lib/Magic.mjs new file mode 100644 index 00000000..43e9dfe4 --- /dev/null +++ b/src/core/lib/Magic.mjs @@ -0,0 +1,1535 @@ +import OperationConfig from "../config/OperationConfig.json"; +import Utils from "../Utils"; +import Recipe from "../Recipe"; +import Dish from "../Dish"; +import chiSquared from "chi-squared"; + +/** + * A class for detecting encodings, file types and byte frequencies and + * speculatively executing recipes. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +class Magic { + + /** + * Magic constructor. + * + * @param {ArrayBuffer} buf + * @param {Object[]} [opPatterns] + */ + constructor(buf, opPatterns) { + this.inputBuffer = new Uint8Array(buf); + this.inputStr = Utils.arrayBufferToStr(buf); + this.opPatterns = opPatterns || Magic._generateOpPatterns(); + } + + /** + * Finds operations that claim to be able to decode the input based on regular + * expression matches. + * + * @returns {Object[]} + */ + findMatchingOps() { + const matches = []; + + for (let i = 0; i < this.opPatterns.length; i++) { + const pattern = this.opPatterns[i], + regex = new RegExp(pattern.match, pattern.flags); + + if (regex.test(this.inputStr)) { + matches.push(pattern); + } + } + + return matches; + } + + /** + * Attempts to detect the language of the input by comparing its byte frequency + * to that of several known languages. + * + * @param {boolean} [extLang=false] - Extensive language support (false = only check the most + * common Internet languages) + * @returns {Object[]} + */ + detectLanguage(extLang = false) { + if (!this.inputBuffer.length) return [{ + lang: "Unknown", + score: Math.MAX_VALUE, + probability: Math.MIN_VALUE + }]; + + const inputFreq = this._freqDist(); + const langFreqs = extLang ? EXTENSIVE_LANG_FREQS : COMMON_LANG_FREQS; + const chiSqrs = []; + + for (const lang in langFreqs) { + const [score, prob] = Magic._chiSqr(inputFreq, langFreqs[lang]); + chiSqrs.push({ + lang: lang, + score: score, + probability: prob + }); + } + + // Sort results so that the most likely match is at the top + chiSqrs.sort((a, b) => { + return a.score - b.score; + }); + + return chiSqrs; + } + + /** + * Detects any matching file types for the input. + * + * @returns {Object} type + * @returns {string} type.ext - File extension + * @returns {string} type.mime - Mime type + * @returns {string} [type.desc] - Description + */ + detectFileType() { + return Magic.magicFileType(this.inputBuffer); + } + + /** + * Detects whether the input buffer is valid UTF8. + * + * @returns {boolean} + */ + isUTF8() { + const bytes = new Uint8Array(this.inputBuffer); + let i = 0; + while (i < bytes.length) { + if (( // ASCII + bytes[i] === 0x09 || + bytes[i] === 0x0A || + bytes[i] === 0x0D || + (0x20 <= bytes[i] && bytes[i] <= 0x7E) + )) { + i += 1; + continue; + } + + if (( // non-overlong 2-byte + (0xC2 <= bytes[i] && bytes[i] <= 0xDF) && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0xBF) + )) { + i += 2; + continue; + } + + if (( // excluding overlongs + bytes[i] === 0xE0 && + (0xA0 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) + ) || + ( // straight 3-byte + ((0xE1 <= bytes[i] && bytes[i] <= 0xEC) || + bytes[i] === 0xEE || + bytes[i] === 0xEF) && + (0x80 <= bytes[i + 1] && bytes[i+1] <= 0xBF) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + ) || + ( // excluding surrogates + bytes[i] === 0xED && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0x9F) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + )) { + i += 3; + continue; + } + + if (( // planes 1-3 + bytes[i] === 0xF0 && + (0x90 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + ( // planes 4-15 + (0xF1 <= bytes[i] && bytes[i] <= 0xF3) && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + ( // plane 16 + bytes[i] === 0xF4 && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0x8F) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + )) { + i += 4; + continue; + } + + return false; + } + + return true; + } + + /** + * Calculates the Shannon entropy of the input data. + * + * @returns {number} + */ + calcEntropy() { + const prob = this._freqDist(); + let entropy = 0, + p; + + for (let i = 0; i < prob.length; i++) { + p = prob[i] / 100; + if (p === 0) continue; + entropy += p * Math.log(p) / Math.log(2); + } + return -entropy; + } + + /** + * Generate various simple brute-forced encodings of the data (trucated to 100 bytes). + * + * @returns {Object[]} - The encoded data and an operation config to generate it. + */ + async bruteForce() { + const sample = new Uint8Array(this.inputBuffer).slice(0, 100); + const results = []; + + // 1-byte XOR + for (let i = 1; i < 256; i++) { + results.push({ + data: sample.map(b => b ^ i).buffer, + conf: { + op: "XOR", + args: [{"option": "Hex", "string": i.toString(16)}, "Standard", false] + } + }); + } + + // Bit rotate + for (let i = 1; i < 8; i++) { + results.push({ + data: sample.map(b => (b >> i) | ((b & (Math.pow(2, i) - 1)) << (8 - i))).buffer, + conf: { + op: "Rotate right", + args: [i, false] + } + }); + } + + // Character encodings + const encodings = OperationConfig["Encode text"].args[0].value; + + /** + * Test character encodings and add them if they change the data. + */ + const testEnc = async op => { + for (let i = 0; i < encodings.length; i++) { + const conf = { + op: op, + args: [encodings[i]] + }, + data = await this._runRecipe([conf], sample.buffer); + + // Only add to the results if it changed the data + if (!_buffersEqual(data, sample.buffer)) { + results.push({ + data: data, + conf: conf + }); + } + } + }; + + await testEnc("Encode text"); + await testEnc("Decode text"); + + return results; + } + + /** + * Speculatively executes matching operations, recording metadata of each result. + * + * @param {number} [depth=0] - How many levels to try to execute + * @param {boolean} [extLang=false] - Extensive language support (false = only check the most + * common Internet languages) + * @param {boolean} [intensive=false] - Run brute-forcing on each branch (significantly affects + * performance) + * @param {Object[]} [recipeConfig=[]] - The recipe configuration up to this point + * @param {boolean} [useful=false] - Whether the current recipe should be scored highly + * @returns {Object[]} - A sorted list of the recipes most likely to result in correct decoding + */ + async speculativeExecution(depth=0, extLang=false, intensive=false, recipeConfig=[], useful=false) { + if (depth < 0) return []; + + // Find any operations that can be run on this data + const matchingOps = this.findMatchingOps(); + + let results = []; + + // Record the properties of the current data + results.push({ + recipe: recipeConfig, + data: this.inputStr.slice(0, 100), + languageScores: this.detectLanguage(extLang), + fileType: this.detectFileType(), + isUTF8: this.isUTF8(), + entropy: this.calcEntropy(), + matchingOps: matchingOps, + useful: useful + }); + + // Execute each of the matching operations, then recursively call the speculativeExecution() + // method on the resulting data, recording the properties of each option. + await Promise.all(matchingOps.map(async op => { + const opConfig = { + op: op.op, + args: op.args + }, + output = await this._runRecipe([opConfig]), + magic = new Magic(output, this.opPatterns), + speculativeResults = await magic.speculativeExecution( + depth-1, extLang, intensive, [...recipeConfig, opConfig], op.useful); + + results = results.concat(speculativeResults); + })); + + if (intensive) { + // Run brute forcing of various types on the data and create a new branch for each option + const bfEncodings = await this.bruteForce(); + + await Promise.all(bfEncodings.map(async enc => { + const magic = new Magic(enc.data, this.opPatterns), + bfResults = await magic.speculativeExecution( + depth-1, extLang, false, [...recipeConfig, enc.conf]); + + results = results.concat(bfResults); + })); + } + + // Prune branches that do not match anything + results = results.filter(r => + r.languageScores[0].probability > 0 || + r.fileType || + r.isUTF8 || + r.matchingOps.length || + r.useful); + + // Return a sorted list of possible recipes along with their properties + return results.sort((a, b) => { + // Each option is sorted based on its most likely language (lower is better) + let aScore = a.languageScores[0].score, + bScore = b.languageScores[0].score; + + // If a recipe results in a file being detected, it receives a relatively good score + if (a.fileType) aScore = 500; + if (b.fileType) bScore = 500; + + // If the result is valid UTF8, its score gets boosted (lower being better) + if (a.isUTF8) aScore -= 100; + if (b.isUTF8) bScore -= 100; + + // If the option is marked useful, give it a good score + if (a.useful) aScore = 100; + if (b.useful) bScore = 100; + + // Shorter recipes are better, so we add the length of the recipe to the score + aScore += a.recipe.length; + bScore += b.recipe.length; + + // Lower entropy is "better", so we add the entropy to the score + aScore += a.entropy; + bScore += b.entropy; + + return aScore - bScore; + }); + } + + /** + * Runs the given recipe over the input buffer and returns the output. + * + * @param {Object[]} recipeConfig + * @param {ArrayBuffer} [input=this.inputBuffer] + * @returns {ArrayBuffer} + */ + async _runRecipe(recipeConfig, input=this.inputBuffer) { + const dish = new Dish(); + dish.set(input.buffer, Dish.ARRAY_BUFFER); + + if (ENVIRONMENT_IS_WORKER()) self.loadRequiredModules(recipeConfig); + + const recipe = new Recipe(recipeConfig); + try { + await recipe.execute(dish, 0); + return dish.get(Dish.ARRAY_BUFFER); + } catch (err) { + // If there are errors, return an empty buffer + return new ArrayBuffer(); + } + } + + /** + * Calculates the number of times each byte appears in the input as a percentage + * + * @private + * @returns {number[]} + */ + _freqDist() { + if (this.freqDist) return this.freqDist; + + const len = this.inputBuffer.length; + let i = len; + const counts = new Array(256).fill(0); + + if (!len) return counts; + + while (i--) { + counts[this.inputBuffer[i]]++; + } + + this.freqDist = counts.map(c => { + return c / len * 100; + }); + return this.freqDist; + } + + /** + * Generates a list of all patterns that operations claim to be able to decode. + * + * @private + * @returns {Object[]} + */ + static _generateOpPatterns() { + const opPatterns = []; + + for (const op in OperationConfig) { + if (!OperationConfig[op].hasOwnProperty("patterns")) continue; + + OperationConfig[op].patterns.forEach(pattern => { + opPatterns.push({ + op: op, + match: pattern.match, + flags: pattern.flags, + args: pattern.args, + useful: pattern.useful || false + }); + }); + } + + return opPatterns; + } + + /** + * Calculates Pearson's Chi-Squared test for two frequency arrays. + * https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test + * + * @private + * @param {number[]} observed + * @param {number[]} expected + * @param {number} ddof - Delta degrees of freedom + * @returns {number[]} - The score and the probability + */ + static _chiSqr(observed, expected, ddof=0) { + let tmp, + score = 0; + + for (let i = 0; i < observed.length; i++) { + tmp = observed[i] - expected[i]; + score += tmp * tmp / expected[i]; + } + + return [ + score, + 1 - chiSquared.cdf(score, observed.length - 1 - ddof) + ]; + } + + /** + * Translates ISO 639(-ish) codes to their full language names as used by Wikipedia + * Accurate up to 2018-02 + * Taken from http://wikistats.wmflabs.org/display.php?t=wp + * + * @param {string} code - ISO 639 code + * @returns {string} The full name of the languge + */ + static codeToLanguage(code) { + return { + "aa": "Afar", + "ab": "Abkhazian", + "ace": "Acehnese", + "ady": "Adyghe", + "af": "Afrikaans", + "ak": "Akan", + "als": "Alemannic", + "am": "Amharic", + "an": "Aragonese", + "ang": "Anglo-Saxon", + "ar": "Arabic", + "arc": "Aramaic", + "arz": "Egyptian Arabic", + "as": "Assamese", + "ast": "Asturian", + "atj": "Atikamekw", + "av": "Avar", + "ay": "Aymara", + "az": "Azerbaijani", + "azb": "South Azerbaijani", + "ba": "Bashkir", + "bar": "Bavarian", + "bat-smg": "Samogitian", + "bcl": "Central_Bicolano", + "be": "Belarusian", + "be-tarask": "Belarusian (Taraškievica)", + "bg": "Bulgarian", + "bh": "Bihari", + "bi": "Bislama", + "bjn": "Banjar", + "bm": "Bambara", + "bn": "Bengali", + "bo": "Tibetan", + "bpy": "Bishnupriya Manipuri", + "br": "Breton", + "bs": "Bosnian", + "bug": "Buginese", + "bxr": "Buryat (Russia)", + "ca": "Catalan", + "cbk-zam": "Zamboanga Chavacano", + "cdo": "Min Dong", + "ce": "Chechen", + "ceb": "Cebuano", + "ch": "Chamorro", + "cho": "Choctaw", + "chr": "Cherokee", + "chy": "Cheyenne", + "ckb": "Sorani", + "co": "Corsican", + "cr": "Cree", + "crh": "Crimean Tatar", + "cs": "Czech", + "csb": "Kashubian", + "cu": "Old Church Slavonic", + "cv": "Chuvash", + "cy": "Welsh", + "da": "Danish", + "de": "German", + "din": "Dinka", + "diq": "Zazaki", + "dsb": "Lower Sorbian", + "dty": "Doteli", + "dv": "Divehi", + "dz": "Dzongkha", + "ee": "Ewe", + "el": "Greek", + "eml": "Emilian-Romagnol", + "en": "English", + "eo": "Esperanto", + "es": "Spanish", + "et": "Estonian", + "eu": "Basque", + "ext": "Extremaduran", + "fa": "Persian", + "ff": "Fula", + "fi": "Finnish", + "fiu-vro": "Võro", + "fj": "Fijian", + "fo": "Faroese", + "fr": "French", + "frp": "Franco-Provençal/Arpitan", + "frr": "North Frisian", + "fur": "Friulian", + "fy": "West Frisian", + "ga": "Irish", + "gag": "Gagauz", + "gan": "Gan", + "gd": "Scottish Gaelic", + "gl": "Galician", + "glk": "Gilaki", + "gn": "Guarani", + "gom": "Goan Konkani", + "got": "Gothic", + "gu": "Gujarati", + "gv": "Manx", + "ha": "Hausa", + "hak": "Hakka", + "haw": "Hawaiian", + "he": "Hebrew", + "hi": "Hindi", + "hif": "Fiji Hindi", + "ho": "Hiri Motu", + "hr": "Croatian", + "hsb": "Upper Sorbian", + "ht": "Haitian", + "hu": "Hungarian", + "hy": "Armenian", + "hz": "Herero", + "ia": "Interlingua", + "id": "Indonesian", + "ie": "Interlingue", + "ig": "Igbo", + "ii": "Sichuan Yi", + "ik": "Inupiak", + "ilo": "Ilokano", + "io": "Ido", + "is": "Icelandic", + "it": "Italian", + "iu": "Inuktitut", + "ja": "Japanese", + "jam": "Jamaican", + "jbo": "Lojban", + "jv": "Javanese", + "ka": "Georgian", + "kaa": "Karakalpak", + "kab": "Kabyle", + "kbd": "Kabardian Circassian", + "kbp": "Kabiye", + "kg": "Kongo", + "ki": "Kikuyu", + "kj": "Kuanyama", + "kk": "Kazakh", + "kl": "Greenlandic", + "km": "Khmer", + "kn": "Kannada", + "ko": "Korean", + "koi": "Komi-Permyak", + "kr": "Kanuri", + "krc": "Karachay-Balkar", + "ks": "Kashmiri", + "ksh": "Ripuarian", + "ku": "Kurdish", + "kv": "Komi", + "kw": "Cornish", + "ky": "Kirghiz", + "la": "Latin", + "lad": "Ladino", + "lb": "Luxembourgish", + "lbe": "Lak", + "lez": "Lezgian", + "lg": "Luganda", + "li": "Limburgish", + "lij": "Ligurian", + "lmo": "Lombard", + "ln": "Lingala", + "lo": "Lao", + "lrc": "Northern Luri", + "lt": "Lithuanian", + "ltg": "Latgalian", + "lv": "Latvian", + "mai": "Maithili", + "map-bms": "Banyumasan", + "mdf": "Moksha", + "mg": "Malagasy", + "mh": "Marshallese", + "mhr": "Meadow Mari", + "mi": "Maori", + "min": "Minangkabau", + "mk": "Macedonian", + "ml": "Malayalam", + "mn": "Mongolian", + "mo": "Moldovan", + "mr": "Marathi", + "mrj": "Hill Mari", + "ms": "Malay", + "mt": "Maltese", + "mus": "Muscogee", + "mwl": "Mirandese", + "my": "Burmese", + "myv": "Erzya", + "mzn": "Mazandarani", + "na": "Nauruan", + "nah": "Nahuatl", + "nap": "Neapolitan", + "nds": "Low Saxon", + "nds-nl": "Dutch Low Saxon", + "ne": "Nepali", + "new": "Newar / Nepal Bhasa", + "ng": "Ndonga", + "nl": "Dutch", + "nn": "Norwegian (Nynorsk)", + "no": "Norwegian (Bokmål)", + "nov": "Novial", + "nrm": "Norman", + "nso": "Northern Sotho", + "nv": "Navajo", + "ny": "Chichewa", + "oc": "Occitan", + "olo": "Livvi-Karelian", + "om": "Oromo", + "or": "Oriya", + "os": "Ossetian", + "pa": "Punjabi", + "pag": "Pangasinan", + "pam": "Kapampangan", + "pap": "Papiamentu", + "pcd": "Picard", + "pdc": "Pennsylvania German", + "pfl": "Palatinate German", + "pi": "Pali", + "pih": "Norfolk", + "pl": "Polish", + "pms": "Piedmontese", + "pnb": "Western Panjabi", + "pnt": "Pontic", + "ps": "Pashto", + "pt": "Portuguese", + "qu": "Quechua", + "rm": "Romansh", + "rmy": "Romani", + "rn": "Kirundi", + "ro": "Romanian", + "roa-rup": "Aromanian", + "roa-tara": "Tarantino", + "ru": "Russian", + "rue": "Rusyn", + "rw": "Kinyarwanda", + "sa": "Sanskrit", + "sah": "Sakha", + "sc": "Sardinian", + "scn": "Sicilian", + "sco": "Scots", + "sd": "Sindhi", + "se": "Northern Sami", + "sg": "Sango", + "sh": "Serbo-Croatian", + "si": "Sinhalese", + "simple": "Simple English", + "sk": "Slovak", + "sl": "Slovenian", + "sm": "Samoan", + "sn": "Shona", + "so": "Somali", + "sq": "Albanian", + "sr": "Serbian", + "srn": "Sranan", + "ss": "Swati", + "st": "Sesotho", + "stq": "Saterland Frisian", + "su": "Sundanese", + "sv": "Swedish", + "sw": "Swahili", + "szl": "Silesian", + "ta": "Tamil", + "tcy": "Tulu", + "te": "Telugu", + "tet": "Tetum", + "tg": "Tajik", + "th": "Thai", + "ti": "Tigrinya", + "tk": "Turkmen", + "tl": "Tagalog", + "tn": "Tswana", + "to": "Tongan", + "tpi": "Tok Pisin", + "tr": "Turkish", + "ts": "Tsonga", + "tt": "Tatar", + "tum": "Tumbuka", + "tw": "Twi", + "ty": "Tahitian", + "tyv": "Tuvan", + "udm": "Udmurt", + "ug": "Uyghur", + "uk": "Ukrainian", + "ur": "Urdu", + "uz": "Uzbek", + "ve": "Venda", + "vec": "Venetian", + "vep": "Vepsian", + "vi": "Vietnamese", + "vls": "West Flemish", + "vo": "Volapük", + "wa": "Walloon", + "war": "Waray-Waray", + "wo": "Wolof", + "wuu": "Wu", + "xal": "Kalmyk", + "xh": "Xhosa", + "xmf": "Mingrelian", + "yi": "Yiddish", + "yo": "Yoruba", + "za": "Zhuang", + "zea": "Zeelandic", + "zh": "Chinese", + "zh-classical": "Classical Chinese", + "zh-min-nan": "Min Nan", + "zh-yue": "Cantonese", + "zu": "Zulu", + }[code]; + } + + + /** + * Given a buffer, detects magic byte sequences at specific positions and returns the + * extension and mime type. + * + * @param {Uint8Array} buf + * @returns {Object} type + * @returns {string} type.ext - File extension + * @returns {string} type.mime - Mime type + * @returns {string} [type.desc] - Description + */ + static magicFileType(buf) { + if (!(buf && buf.length > 1)) { + return null; + } + + if (buf[0] === 0xFF && buf[1] === 0xD8 && buf[2] === 0xFF) { + return { + ext: "jpg", + mime: "image/jpeg" + }; + } + + if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4E && buf[3] === 0x47) { + return { + ext: "png", + mime: "image/png" + }; + } + + if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46) { + return { + ext: "gif", + mime: "image/gif" + }; + } + + if (buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) { + return { + ext: "webp", + mime: "image/webp" + }; + } + + // needs to be before `tif` check + if (((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) && buf[8] === 0x43 && buf[9] === 0x52) { + return { + ext: "cr2", + mime: "image/x-canon-cr2" + }; + } + + if ((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) { + return { + ext: "tif", + mime: "image/tiff" + }; + } + + if (buf[0] === 0x42 && buf[1] === 0x4D) { + return { + ext: "bmp", + mime: "image/bmp" + }; + } + + if (buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0xBC) { + return { + ext: "jxr", + mime: "image/vnd.ms-photo" + }; + } + + if (buf[0] === 0x38 && buf[1] === 0x42 && buf[2] === 0x50 && buf[3] === 0x53) { + return { + ext: "psd", + mime: "image/vnd.adobe.photoshop" + }; + } + + // needs to be before `zip` check + if (buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x6D && buf[31] === 0x69 && buf[32] === 0x6D && buf[33] === 0x65 && buf[34] === 0x74 && buf[35] === 0x79 && buf[36] === 0x70 && buf[37] === 0x65 && buf[38] === 0x61 && buf[39] === 0x70 && buf[40] === 0x70 && buf[41] === 0x6C && buf[42] === 0x69 && buf[43] === 0x63 && buf[44] === 0x61 && buf[45] === 0x74 && buf[46] === 0x69 && buf[47] === 0x6F && buf[48] === 0x6E && buf[49] === 0x2F && buf[50] === 0x65 && buf[51] === 0x70 && buf[52] === 0x75 && buf[53] === 0x62 && buf[54] === 0x2B && buf[55] === 0x7A && buf[56] === 0x69 && buf[57] === 0x70) { + return { + ext: "epub", + mime: "application/epub+zip" + }; + } + + if (buf[0] === 0x50 && buf[1] === 0x4B && (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) && (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)) { + return { + ext: "zip", + mime: "application/zip" + }; + } + + if (buf[257] === 0x75 && buf[258] === 0x73 && buf[259] === 0x74 && buf[260] === 0x61 && buf[261] === 0x72) { + return { + ext: "tar", + mime: "application/x-tar" + }; + } + + if (buf[0] === 0x52 && buf[1] === 0x61 && buf[2] === 0x72 && buf[3] === 0x21 && buf[4] === 0x1A && buf[5] === 0x7 && (buf[6] === 0x0 || buf[6] === 0x1)) { + return { + ext: "rar", + mime: "application/x-rar-compressed" + }; + } + + if (buf[0] === 0x1F && buf[1] === 0x8B && buf[2] === 0x8) { + return { + ext: "gz", + mime: "application/gzip" + }; + } + + if (buf[0] === 0x42 && buf[1] === 0x5A && buf[2] === 0x68) { + return { + ext: "bz2", + mime: "application/x-bzip2" + }; + } + + if (buf[0] === 0x37 && buf[1] === 0x7A && buf[2] === 0xBC && buf[3] === 0xAF && buf[4] === 0x27 && buf[5] === 0x1C) { + return { + ext: "7z", + mime: "application/x-7z-compressed" + }; + } + + if (buf[0] === 0x78 && buf[1] === 0x01) { + return { + ext: "dmg, zlib", + mime: "application/x-apple-diskimage, application/x-deflate" + }; + } + + if ((buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && (buf[3] === 0x18 || buf[3] === 0x20) && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) || (buf[0] === 0x33 && buf[1] === 0x67 && buf[2] === 0x70 && buf[3] === 0x35) || (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && buf[11] === 0x32 && buf[16] === 0x6D && buf[17] === 0x70 && buf[18] === 0x34 && buf[19] === 0x31 && buf[20] === 0x6D && buf[21] === 0x70 && buf[22] === 0x34 && buf[23] === 0x32 && buf[24] === 0x69 && buf[25] === 0x73 && buf[26] === 0x6F && buf[27] === 0x6D)) { + return { + ext: "mp4", + mime: "video/mp4" + }; + } + + if ((buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x56)) { + return { + ext: "m4v", + mime: "video/x-m4v" + }; + } + + if (buf[0] === 0x4D && buf[1] === 0x54 && buf[2] === 0x68 && buf[3] === 0x64) { + return { + ext: "mid", + mime: "audio/midi" + }; + } + + // needs to be before the `webm` check + if (buf[31] === 0x6D && buf[32] === 0x61 && buf[33] === 0x74 && buf[34] === 0x72 && buf[35] === 0x6f && buf[36] === 0x73 && buf[37] === 0x6B && buf[38] === 0x61) { + return { + ext: "mkv", + mime: "video/x-matroska" + }; + } + + if (buf[0] === 0x1A && buf[1] === 0x45 && buf[2] === 0xDF && buf[3] === 0xA3) { + return { + ext: "webm", + mime: "video/webm" + }; + } + + if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x14 && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) { + return { + ext: "mov", + mime: "video/quicktime" + }; + } + + if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x41 && buf[9] === 0x56 && buf[10] === 0x49) { + return { + ext: "avi", + mime: "video/x-msvideo" + }; + } + + if (buf[0] === 0x30 && buf[1] === 0x26 && buf[2] === 0xB2 && buf[3] === 0x75 && buf[4] === 0x8E && buf[5] === 0x66 && buf[6] === 0xCF && buf[7] === 0x11 && buf[8] === 0xA6 && buf[9] === 0xD9) { + return { + ext: "wmv", + mime: "video/x-ms-wmv" + }; + } + + if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x1 && buf[3].toString(16)[0] === "b") { + return { + ext: "mpg", + mime: "video/mpeg" + }; + } + + if ((buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) || (buf[0] === 0xFF && buf[1] === 0xfb)) { + return { + ext: "mp3", + mime: "audio/mpeg" + }; + } + + if ((buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x41) || (buf[0] === 0x4D && buf[1] === 0x34 && buf[2] === 0x41 && buf[3] === 0x20)) { + return { + ext: "m4a", + mime: "audio/m4a" + }; + } + + if (buf[0] === 0x4F && buf[1] === 0x67 && buf[2] === 0x67 && buf[3] === 0x53) { + return { + ext: "ogg", + mime: "audio/ogg" + }; + } + + if (buf[0] === 0x66 && buf[1] === 0x4C && buf[2] === 0x61 && buf[3] === 0x43) { + return { + ext: "flac", + mime: "audio/x-flac" + }; + } + + if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x57 && buf[9] === 0x41 && buf[10] === 0x56 && buf[11] === 0x45) { + return { + ext: "wav", + mime: "audio/x-wav" + }; + } + + if (buf[0] === 0x23 && buf[1] === 0x21 && buf[2] === 0x41 && buf[3] === 0x4D && buf[4] === 0x52 && buf[5] === 0x0A) { + return { + ext: "amr", + mime: "audio/amr" + }; + } + + if (buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46) { + return { + ext: "pdf", + mime: "application/pdf" + }; + } + + if (buf[0] === 0x4D && buf[1] === 0x5A) { + return { + ext: "exe", + mime: "application/x-msdownload" + }; + } + + if ((buf[0] === 0x43 || buf[0] === 0x46) && buf[1] === 0x57 && buf[2] === 0x53) { + return { + ext: "swf", + mime: "application/x-shockwave-flash" + }; + } + + if (buf[0] === 0x7B && buf[1] === 0x5C && buf[2] === 0x72 && buf[3] === 0x74 && buf[4] === 0x66) { + return { + ext: "rtf", + mime: "application/rtf" + }; + } + + if (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x46 && buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) { + return { + ext: "woff", + mime: "application/font-woff" + }; + } + + if (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x32 && buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) { + return { + ext: "woff2", + mime: "application/font-woff" + }; + } + + if (buf[34] === 0x4C && buf[35] === 0x50 && ((buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x01) || (buf[8] === 0x01 && buf[9] === 0x00 && buf[10] === 0x00) || (buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x02))) { + return { + ext: "eot", + mime: "application/octet-stream" + }; + } + + if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00 && buf[4] === 0x00) { + return { + ext: "ttf", + mime: "application/font-sfnt" + }; + } + + if (buf[0] === 0x4F && buf[1] === 0x54 && buf[2] === 0x54 && buf[3] === 0x4F && buf[4] === 0x00) { + return { + ext: "otf", + mime: "application/font-sfnt" + }; + } + + if (buf[0] === 0x00 && buf[1] === 0x00 && buf[2] === 0x01 && buf[3] === 0x00) { + return { + ext: "ico", + mime: "image/x-icon" + }; + } + + if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x56 && buf[3] === 0x01) { + return { + ext: "flv", + mime: "video/x-flv" + }; + } + + if (buf[0] === 0x25 && buf[1] === 0x21) { + return { + ext: "ps", + mime: "application/postscript" + }; + } + + if (buf[0] === 0xFD && buf[1] === 0x37 && buf[2] === 0x7A && buf[3] === 0x58 && buf[4] === 0x5A && buf[5] === 0x00) { + return { + ext: "xz", + mime: "application/x-xz" + }; + } + + if (buf[0] === 0x53 && buf[1] === 0x51 && buf[2] === 0x4C && buf[3] === 0x69) { + return { + ext: "sqlite", + mime: "application/x-sqlite3" + }; + } + + /** + * + * Added by n1474335 [n1474335@gmail.com] from here on + * + */ + if ((buf[0] === 0x1F && buf[1] === 0x9D) || (buf[0] === 0x1F && buf[1] === 0xA0)) { + return { + ext: "z, tar.z", + mime: "application/x-gtar" + }; + } + + if (buf[0] === 0x7F && buf[1] === 0x45 && buf[2] === 0x4C && buf[3] === 0x46) { + return { + ext: "none, axf, bin, elf, o, prx, puff, so", + mime: "application/x-executable", + desc: "Executable and Linkable Format file. No standard file extension." + }; + } + + if (buf[0] === 0xCA && buf[1] === 0xFE && buf[2] === 0xBA && buf[3] === 0xBE) { + return { + ext: "class", + mime: "application/java-vm" + }; + } + + if (buf[0] === 0xEF && buf[1] === 0xBB && buf[2] === 0xBF) { + return { + ext: "txt", + mime: "text/plain", + desc: "UTF-8 encoded Unicode byte order mark detected, commonly but not exclusively seen in text files." + }; + } + + // Must be before Little-endian UTF-16 BOM + if (buf[0] === 0xFF && buf[1] === 0xFE && buf[2] === 0x00 && buf[3] === 0x00) { + return { + ext: "UTF32LE", + mime: "charset/utf32le", + desc: "Little-endian UTF-32 encoded Unicode byte order mark detected." + }; + } + + if (buf[0] === 0xFF && buf[1] === 0xFE) { + return { + ext: "UTF16LE", + mime: "charset/utf16le", + desc: "Little-endian UTF-16 encoded Unicode byte order mark detected." + }; + } + + if ((buf[0x8001] === 0x43 && buf[0x8002] === 0x44 && buf[0x8003] === 0x30 && buf[0x8004] === 0x30 && buf[0x8005] === 0x31) || + (buf[0x8801] === 0x43 && buf[0x8802] === 0x44 && buf[0x8803] === 0x30 && buf[0x8804] === 0x30 && buf[0x8805] === 0x31) || + (buf[0x9001] === 0x43 && buf[0x9002] === 0x44 && buf[0x9003] === 0x30 && buf[0x9004] === 0x30 && buf[0x9005] === 0x31)) { + return { + ext: "iso", + mime: "application/octet-stream", + desc: "ISO 9660 CD/DVD image file" + }; + } + + if (buf[0] === 0xD0 && buf[1] === 0xCF && buf[2] === 0x11 && buf[3] === 0xE0 && buf[4] === 0xA1 && buf[5] === 0xB1 && buf[6] === 0x1A && buf[7] === 0xE1) { + return { + ext: "doc, xls, ppt", + mime: "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint", + desc: "Microsoft Office documents" + }; + } + + if (buf[0] === 0x64 && buf[1] === 0x65 && buf[2] === 0x78 && buf[3] === 0x0A && buf[4] === 0x30 && buf[5] === 0x33 && buf[6] === 0x35 && buf[7] === 0x00) { + return { + ext: "dex", + mime: "application/octet-stream", + desc: "Dalvik Executable (Android)" + }; + } + + if (buf[0] === 0x4B && buf[1] === 0x44 && buf[2] === 0x4D) { + return { + ext: "vmdk", + mime: "application/vmdk, application/x-virtualbox-vmdk" + }; + } + + if (buf[0] === 0x43 && buf[1] === 0x72 && buf[2] === 0x32 && buf[3] === 0x34) { + return { + ext: "crx", + mime: "application/crx", + desc: "Google Chrome extension or packaged app" + }; + } + + if (buf[0] === 0x78 && (buf[1] === 0x01 || buf[1] === 0x9C || buf[1] === 0xDA || buf[1] === 0x5e)) { + return { + ext: "zlib", + mime: "application/x-deflate" + }; + } + + return null; + } + +} + +/** + * Byte frequencies of various languages generated from Wikipedia dumps taken in late 2017 and early 2018. + * The Chi-Squared test cannot accept expected values of 0, so 0.0001 has been used to account for bytes + * that do not normally appear in the language. + * + * The common languages are chosen based on https://w3techs.com/technologies/overview/content_language/all + * as of early 2018. + */ +const COMMON_LANG_FREQS = { + "en": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.755, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.843, 0.004, 0.375, 0.002, 0.008, 0.019, 0.008, 0.134, 0.137, 0.137, 0.001, 0.001, 0.972, 0.19, 0.857, 0.017, 0.334, 0.421, 0.246, 0.108, 0.104, 0.112, 0.103, 0.1, 0.127, 0.237, 0.04, 0.027, 0.004, 0.003, 0.004, 0.002, 0.0001, 0.338, 0.218, 0.326, 0.163, 0.121, 0.149, 0.133, 0.192, 0.232, 0.107, 0.082, 0.148, 0.248, 0.134, 0.103, 0.195, 0.012, 0.162, 0.368, 0.366, 0.077, 0.061, 0.127, 0.009, 0.03, 0.015, 0.004, 0.0001, 0.004, 0.0001, 0.003, 0.0001, 6.614, 1.039, 2.327, 2.934, 9.162, 1.606, 1.415, 3.503, 5.718, 0.081, 0.461, 3.153, 1.793, 5.723, 5.565, 1.415, 0.066, 5.036, 4.79, 6.284, 1.992, 0.759, 1.176, 0.139, 1.162, 0.102, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.06, 0.004, 0.003, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.031, 0.006, 0.001, 0.001, 0.001, 0.002, 0.014, 0.001, 0.001, 0.005, 0.005, 0.001, 0.002, 0.017, 0.007, 0.002, 0.003, 0.004, 0.002, 0.001, 0.002, 0.002, 0.012, 0.001, 0.002, 0.001, 0.004, 0.001, 0.001, 0.003, 0.003, 0.002, 0.005, 0.001, 0.001, 0.003, 0.001, 0.003, 0.001, 0.002, 0.001, 0.004, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.02, 0.047, 0.009, 0.009, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.061, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ru": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.512, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.274, 0.002, 0.063, 0.0001, 0.001, 0.009, 0.001, 0.001, 0.118, 0.118, 0.0001, 0.001, 0.595, 0.135, 0.534, 0.009, 0.18, 0.281, 0.15, 0.078, 0.076, 0.077, 0.068, 0.066, 0.083, 0.16, 0.036, 0.016, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.013, 0.009, 0.014, 0.009, 0.007, 0.006, 0.007, 0.006, 0.031, 0.002, 0.003, 0.007, 0.012, 0.007, 0.005, 0.01, 0.001, 0.008, 0.017, 0.011, 0.003, 0.009, 0.005, 0.012, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.003, 0.0001, 0.065, 0.009, 0.022, 0.021, 0.074, 0.01, 0.013, 0.019, 0.054, 0.001, 0.008, 0.036, 0.02, 0.047, 0.055, 0.013, 0.001, 0.052, 0.037, 0.041, 0.026, 0.007, 0.006, 0.003, 0.011, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.469, 2.363, 2.342, 0.986, 0.156, 0.422, 0.252, 0.495, 0.217, 0.136, 0.014, 0.778, 0.56, 0.097, 0.251, 0.811, 0.09, 0.184, 0.165, 0.06, 0.179, 0.021, 0.013, 0.029, 0.05, 0.005, 0.116, 0.045, 0.087, 0.073, 0.067, 0.124, 0.211, 0.16, 0.055, 0.033, 0.036, 0.024, 0.013, 0.02, 0.022, 0.002, 0.0001, 0.1, 0.0001, 0.025, 0.009, 0.011, 3.536, 0.619, 1.963, 0.833, 1.275, 3.452, 0.323, 0.635, 3.408, 0.642, 1.486, 1.967, 1.26, 2.857, 4.587, 1.082, 0.0001, 0.0001, 0.339, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.0001, 0.002, 0.001, 31.356, 12.318, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.131, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "de": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.726, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.303, 0.002, 0.278, 0.0001, 0.0001, 0.007, 0.003, 0.005, 0.149, 0.149, 0.015, 0.001, 0.636, 0.237, 0.922, 0.023, 0.305, 0.472, 0.225, 0.115, 0.11, 0.121, 0.108, 0.11, 0.145, 0.271, 0.049, 0.022, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.413, 0.383, 0.144, 0.412, 0.275, 0.258, 0.273, 0.218, 0.18, 0.167, 0.277, 0.201, 0.328, 0.179, 0.111, 0.254, 0.012, 0.219, 0.602, 0.209, 0.1, 0.185, 0.206, 0.005, 0.01, 0.112, 0.002, 0.0001, 0.002, 0.0001, 0.006, 0.0001, 4.417, 1.306, 1.99, 3.615, 12.382, 1.106, 2.0, 2.958, 6.179, 0.082, 0.866, 2.842, 1.869, 7.338, 2.27, 0.606, 0.016, 6.056, 4.424, 4.731, 3.002, 0.609, 0.918, 0.053, 0.169, 0.824, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.147, 0.002, 0.003, 0.001, 0.006, 0.001, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.03, 0.0001, 0.0001, 0.009, 0.001, 0.002, 0.009, 0.002, 0.001, 0.061, 0.0001, 0.048, 0.122, 0.057, 0.009, 0.001, 0.001, 0.4, 0.001, 0.002, 0.003, 0.003, 0.017, 0.001, 0.003, 0.001, 0.005, 0.0001, 0.001, 0.003, 0.002, 0.003, 0.005, 0.001, 0.001, 0.203, 0.0001, 0.002, 0.001, 0.002, 0.002, 0.438, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.056, 1.237, 0.01, 0.013, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.148, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ja": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.834, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.258, 0.007, 0.036, 0.001, 0.0001, 0.005, 0.002, 0.003, 0.033, 0.033, 0.0001, 0.002, 0.019, 0.052, 0.026, 0.009, 0.281, 0.407, 0.259, 0.126, 0.108, 0.109, 0.095, 0.092, 0.104, 0.184, 0.008, 0.001, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.048, 0.026, 0.039, 0.027, 0.028, 0.022, 0.018, 0.016, 0.03, 0.012, 0.014, 0.02, 0.03, 0.025, 0.025, 0.026, 0.002, 0.026, 0.045, 0.031, 0.013, 0.014, 0.014, 0.006, 0.006, 0.003, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.077, 0.012, 0.03, 0.026, 0.088, 0.012, 0.017, 0.025, 0.067, 0.002, 0.016, 0.041, 0.039, 0.059, 0.066, 0.016, 0.001, 0.06, 0.043, 0.051, 0.028, 0.009, 0.007, 0.004, 0.015, 0.004, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 2.555, 10.322, 5.875, 4.462, 0.784, 0.468, 0.442, 0.409, 1.173, 0.96, 0.657, 1.448, 1.442, 0.636, 0.341, 0.685, 0.495, 0.342, 0.651, 0.536, 0.435, 0.657, 0.51, 0.978, 0.31, 0.563, 0.439, 0.514, 0.668, 0.438, 0.29, 1.039, 0.423, 0.532, 0.407, 0.691, 0.677, 0.555, 0.911, 0.887, 1.086, 0.531, 0.836, 1.345, 0.438, 0.666, 1.528, 0.959, 0.535, 0.379, 0.302, 0.822, 0.614, 0.308, 0.253, 0.467, 0.807, 0.807, 0.777, 0.809, 1.292, 0.546, 0.524, 0.425, 0.0001, 0.0001, 0.002, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.015, 19.387, 1.167, 4.022, 2.518, 1.734, 1.339, 1.229, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.409, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "es": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.757, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.771, 0.003, 0.315, 0.001, 0.004, 0.019, 0.003, 0.014, 0.132, 0.133, 0.001, 0.001, 0.976, 0.078, 0.703, 0.014, 0.268, 0.331, 0.197, 0.095, 0.086, 0.095, 0.085, 0.084, 0.105, 0.183, 0.053, 0.027, 0.001, 0.002, 0.002, 0.002, 0.0001, 0.242, 0.129, 0.28, 0.129, 0.322, 0.105, 0.099, 0.077, 0.116, 0.074, 0.034, 0.209, 0.196, 0.086, 0.059, 0.187, 0.009, 0.118, 0.247, 0.128, 0.061, 0.072, 0.033, 0.023, 0.018, 0.013, 0.005, 0.0001, 0.005, 0.0001, 0.003, 0.0001, 8.9, 0.939, 3.234, 4.015, 9.642, 0.603, 0.891, 0.531, 5.007, 0.262, 0.107, 4.355, 1.915, 5.487, 6.224, 1.805, 0.423, 4.992, 5.086, 3.402, 2.878, 0.667, 0.044, 0.125, 0.673, 0.299, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.033, 0.009, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.003, 0.0001, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.006, 0.006, 0.001, 0.0001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.008, 0.008, 0.001, 0.001, 0.025, 0.274, 0.002, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.221, 0.003, 0.019, 0.001, 0.373, 0.001, 0.001, 0.005, 0.144, 0.01, 0.631, 0.002, 0.001, 0.002, 0.001, 0.002, 0.001, 0.102, 0.018, 0.006, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.079, 1.766, 0.003, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.008, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.032, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.894, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.162, 0.003, 0.276, 0.0001, 0.0001, 0.012, 0.002, 0.638, 0.153, 0.153, 0.001, 0.002, 0.96, 0.247, 0.715, 0.011, 0.225, 0.339, 0.18, 0.084, 0.081, 0.086, 0.081, 0.084, 0.106, 0.194, 0.063, 0.018, 0.003, 0.002, 0.003, 0.002, 0.0001, 0.208, 0.141, 0.255, 0.128, 0.144, 0.1, 0.095, 0.071, 0.154, 0.072, 0.042, 0.331, 0.173, 0.077, 0.056, 0.167, 0.013, 0.108, 0.214, 0.102, 0.049, 0.062, 0.035, 0.009, 0.014, 0.011, 0.003, 0.0001, 0.003, 0.0001, 0.004, 0.0001, 5.761, 0.627, 2.287, 3.136, 10.738, 0.723, 0.838, 0.669, 5.295, 0.172, 0.12, 4.204, 1.941, 5.522, 4.015, 2.005, 0.584, 5.043, 5.545, 5.13, 4.06, 0.906, 0.051, 0.295, 0.278, 0.085, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.136, 0.003, 0.004, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.034, 0.0001, 0.0001, 0.001, 0.004, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.019, 0.003, 0.0001, 0.0001, 0.001, 0.001, 0.112, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.367, 0.007, 0.034, 0.001, 0.003, 0.001, 0.003, 0.046, 0.303, 1.817, 0.082, 0.045, 0.001, 0.004, 0.029, 0.017, 0.004, 0.002, 0.002, 0.005, 0.038, 0.001, 0.003, 0.0001, 0.002, 0.02, 0.002, 0.054, 0.004, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.113, 2.813, 0.007, 0.026, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.003, 0.001, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.122, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pt": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.934, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.319, 0.004, 0.372, 0.001, 0.002, 0.012, 0.004, 0.016, 0.15, 0.15, 0.001, 0.002, 1.16, 0.21, 0.746, 0.022, 0.296, 0.361, 0.226, 0.106, 0.098, 0.105, 0.096, 0.094, 0.114, 0.207, 0.054, 0.022, 0.006, 0.004, 0.006, 0.002, 0.0001, 0.345, 0.166, 0.295, 0.143, 0.233, 0.136, 0.112, 0.077, 0.129, 0.093, 0.039, 0.119, 0.217, 0.135, 0.164, 0.222, 0.016, 0.14, 0.259, 0.142, 0.064, 0.078, 0.041, 0.021, 0.013, 0.012, 0.007, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 9.026, 0.717, 2.572, 4.173, 8.551, 0.751, 0.906, 0.629, 5.107, 0.172, 0.12, 2.357, 3.189, 4.024, 7.683, 1.87, 0.445, 5.017, 5.188, 3.559, 2.852, 0.875, 0.055, 0.186, 0.122, 0.257, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.034, 0.01, 0.003, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.014, 0.001, 0.001, 0.001, 0.005, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.009, 0.006, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.007, 0.007, 0.0001, 0.001, 0.079, 0.267, 0.045, 0.508, 0.002, 0.001, 0.001, 0.424, 0.003, 0.417, 0.113, 0.003, 0.001, 0.255, 0.001, 0.001, 0.005, 0.003, 0.015, 0.161, 0.032, 0.087, 0.003, 0.001, 0.002, 0.001, 0.095, 0.002, 0.005, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.067, 2.471, 0.004, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.033, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "it": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.828, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.918, 0.002, 0.385, 0.0001, 0.001, 0.007, 0.003, 0.383, 0.13, 0.131, 0.0001, 0.001, 0.948, 0.103, 0.657, 0.014, 0.252, 0.332, 0.195, 0.093, 0.089, 0.095, 0.088, 0.084, 0.098, 0.183, 0.061, 0.035, 0.006, 0.002, 0.006, 0.001, 0.0001, 0.215, 0.131, 0.235, 0.125, 0.08, 0.104, 0.125, 0.057, 0.24, 0.04, 0.038, 0.208, 0.179, 0.133, 0.054, 0.164, 0.025, 0.114, 0.256, 0.12, 0.052, 0.079, 0.038, 0.021, 0.012, 0.012, 0.002, 0.0001, 0.002, 0.0001, 0.005, 0.0001, 8.583, 0.65, 3.106, 3.081, 8.81, 0.801, 1.321, 0.694, 8.492, 0.02, 0.115, 5.238, 1.88, 5.659, 6.812, 1.981, 0.236, 4.962, 3.674, 5.112, 2.35, 1.107, 0.055, 0.027, 0.118, 0.709, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.022, 0.004, 0.002, 0.002, 0.001, 0.001, 0.001, 0.002, 0.013, 0.001, 0.0001, 0.0001, 0.001, 0.004, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.006, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.005, 0.0001, 0.001, 0.005, 0.005, 0.0001, 0.001, 0.153, 0.007, 0.001, 0.001, 0.003, 0.001, 0.001, 0.002, 0.174, 0.033, 0.004, 0.009, 0.036, 0.004, 0.001, 0.001, 0.006, 0.003, 0.097, 0.004, 0.001, 0.001, 0.003, 0.001, 0.002, 0.056, 0.009, 0.007, 0.004, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.043, 0.574, 0.01, 0.009, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.007, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.021, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "zh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.074, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.273, 0.003, 0.045, 0.0001, 0.001, 0.012, 0.001, 0.004, 0.032, 0.032, 0.001, 0.003, 0.032, 0.068, 0.063, 0.017, 0.386, 0.478, 0.308, 0.149, 0.134, 0.146, 0.127, 0.121, 0.136, 0.231, 0.018, 0.009, 0.007, 0.006, 0.007, 0.0001, 0.0001, 0.045, 0.029, 0.041, 0.028, 0.022, 0.017, 0.02, 0.019, 0.025, 0.01, 0.013, 0.02, 0.033, 0.021, 0.018, 0.028, 0.002, 0.022, 0.045, 0.031, 0.01, 0.013, 0.012, 0.007, 0.005, 0.003, 0.004, 0.0001, 0.004, 0.0001, 0.009, 0.0001, 0.159, 0.026, 0.051, 0.047, 0.17, 0.025, 0.032, 0.057, 0.124, 0.003, 0.021, 0.089, 0.049, 0.12, 0.129, 0.028, 0.002, 0.124, 0.083, 0.1, 0.058, 0.016, 0.016, 0.008, 0.03, 0.012, 0.006, 0.004, 0.006, 0.001, 0.0001, 2.707, 1.09, 1.398, 0.705, 1.23, 1.04, 0.715, 0.952, 1.455, 1.297, 0.845, 1.19, 2.403, 1.193, 0.813, 1.077, 0.889, 0.565, 0.387, 0.47, 0.931, 0.663, 1.035, 0.837, 0.77, 0.772, 1.434, 1.023, 1.668, 0.609, 0.437, 0.793, 0.535, 0.706, 0.48, 0.538, 0.785, 0.909, 0.7, 0.697, 1.017, 0.519, 0.441, 0.567, 0.626, 1.082, 0.814, 1.054, 1.074, 0.811, 0.556, 0.684, 0.903, 0.43, 0.642, 0.78, 2.083, 1.147, 2.006, 1.331, 2.547, 1.015, 0.911, 0.807, 0.0001, 0.0001, 0.069, 0.007, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.126, 1.369, 3.539, 8.968, 5.44, 4.358, 3.141, 2.48, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 1.821, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.841, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.03, 0.001, 0.048, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.117, 0.117, 0.001, 0.001, 0.009, 0.038, 0.486, 0.012, 0.007, 0.009, 0.007, 0.005, 0.003, 0.004, 0.003, 0.003, 0.003, 0.004, 0.048, 0.001, 0.001, 0.003, 0.001, 0.001, 0.0001, 0.011, 0.006, 0.011, 0.006, 0.005, 0.005, 0.004, 0.005, 0.007, 0.002, 0.002, 0.005, 0.008, 0.005, 0.005, 0.008, 0.001, 0.005, 0.011, 0.008, 0.002, 0.003, 0.004, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.007, 0.0001, 0.058, 0.008, 0.02, 0.02, 0.06, 0.011, 0.012, 0.017, 0.051, 0.001, 0.009, 0.031, 0.018, 0.042, 0.047, 0.015, 0.001, 0.043, 0.03, 0.037, 0.022, 0.005, 0.008, 0.003, 0.009, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.678, 0.557, 0.438, 0.001, 1.227, 2.118, 3.004, 2.445, 2.539, 0.0001, 0.003, 0.021, 5.067, 0.002, 0.007, 0.006, 0.015, 0.005, 0.002, 0.008, 0.07, 0.0001, 0.0001, 0.0001, 0.053, 0.001, 0.0001, 0.018, 0.0001, 0.001, 0.0001, 0.002, 0.002, 0.006, 0.337, 0.015, 0.006, 0.001, 0.059, 6.029, 1.704, 1.216, 2.096, 0.113, 0.433, 0.309, 0.439, 3.398, 0.192, 3.798, 0.977, 1.716, 1.137, 0.259, 0.129, 0.264, 0.12, 0.588, 0.085, 0.033, 0.001, 0.0001, 0.327, 0.0001, 0.0001, 0.0001, 0.068, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 23.012, 12.666, 1.946, 5.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.676, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.97, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.695, 0.002, 0.242, 0.0001, 0.0001, 0.007, 0.002, 0.011, 0.194, 0.194, 0.0001, 0.001, 0.805, 0.129, 1.016, 0.02, 0.347, 0.542, 0.289, 0.14, 0.138, 0.144, 0.123, 0.13, 0.153, 0.343, 0.068, 0.014, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.17, 0.165, 0.143, 0.124, 0.066, 0.081, 0.113, 0.075, 0.141, 0.107, 0.18, 0.108, 0.192, 0.142, 0.119, 0.322, 0.004, 0.139, 0.268, 0.117, 0.058, 0.041, 0.322, 0.032, 0.008, 0.109, 0.001, 0.0001, 0.001, 0.0001, 0.006, 0.0001, 6.697, 0.859, 2.856, 2.291, 5.604, 0.259, 1.117, 0.918, 6.017, 1.562, 2.537, 1.759, 1.903, 4.231, 5.86, 1.841, 0.006, 3.854, 3.145, 2.863, 1.965, 0.061, 3.408, 0.016, 2.669, 3.631, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.208, 0.018, 1.343, 0.004, 0.168, 0.653, 0.002, 0.145, 0.003, 0.001, 0.001, 0.001, 0.002, 0.004, 0.001, 0.002, 0.002, 0.001, 0.003, 0.126, 0.002, 0.001, 0.002, 0.002, 0.001, 0.65, 0.023, 0.378, 0.002, 0.035, 0.035, 0.002, 0.018, 0.011, 0.001, 0.002, 0.005, 0.001, 0.001, 0.002, 0.003, 0.012, 0.001, 0.002, 0.001, 0.005, 0.001, 0.001, 0.01, 0.004, 0.011, 0.641, 0.003, 0.006, 0.005, 0.001, 0.008, 0.004, 0.056, 0.014, 0.433, 0.007, 0.008, 0.002, 0.0001, 0.0001, 0.025, 0.694, 1.442, 2.413, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.006, 0.003, 0.06, 0.02, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.205, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.91, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.447, 0.013, 0.297, 0.0001, 0.001, 0.013, 0.003, 0.465, 0.123, 0.123, 0.001, 0.002, 0.653, 0.111, 0.957, 0.015, 0.312, 0.387, 0.238, 0.107, 0.101, 0.108, 0.097, 0.095, 0.109, 0.217, 0.04, 0.028, 0.007, 0.019, 0.007, 0.002, 0.0001, 0.336, 0.309, 0.117, 0.167, 0.132, 0.105, 0.13, 0.135, 0.063, 0.042, 0.261, 0.085, 0.236, 0.083, 0.095, 0.131, 0.004, 0.092, 0.247, 0.219, 0.038, 0.052, 0.037, 0.008, 0.095, 0.019, 0.007, 0.0001, 0.007, 0.0001, 0.005, 0.001, 8.533, 1.3, 0.65, 3.067, 6.656, 0.419, 0.804, 0.718, 6.178, 0.059, 2.986, 5.127, 2.286, 5.537, 2.04, 0.623, 0.006, 5.247, 2.411, 2.743, 2.225, 0.903, 0.049, 0.018, 2.076, 0.792, 0.0001, 0.018, 0.0001, 0.0001, 0.0001, 0.096, 0.004, 0.004, 0.004, 0.002, 0.002, 0.002, 0.041, 0.002, 0.001, 0.001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.007, 0.002, 0.001, 0.031, 0.001, 0.003, 0.065, 0.001, 0.001, 0.033, 0.009, 0.047, 1.71, 0.04, 0.005, 0.027, 0.002, 0.003, 0.001, 0.001, 0.647, 0.002, 0.008, 0.002, 0.003, 0.001, 0.004, 0.019, 0.002, 0.132, 3.435, 0.005, 0.004, 0.003, 0.003, 0.525, 0.001, 0.004, 0.002, 0.003, 0.007, 1.206, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.046, 2.539, 4.197, 1.125, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.007, 0.003, 0.023, 0.009, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.01, 0.007, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.094, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.158, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.747, 0.002, 0.267, 0.0001, 0.001, 0.008, 0.01, 0.052, 0.196, 0.196, 0.0001, 0.001, 0.504, 0.205, 0.944, 0.013, 0.311, 0.428, 0.229, 0.104, 0.101, 0.109, 0.102, 0.102, 0.137, 0.252, 0.048, 0.012, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.205, 0.192, 0.181, 0.371, 0.131, 0.088, 0.11, 0.236, 0.167, 0.069, 0.091, 0.119, 0.172, 0.137, 0.117, 0.141, 0.005, 0.112, 0.229, 0.137, 0.034, 0.123, 0.084, 0.006, 0.011, 0.064, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 6.042, 1.063, 1.294, 4.124, 13.689, 0.579, 2.105, 1.822, 5.542, 0.948, 1.42, 3.124, 1.72, 7.129, 4.759, 1.349, 0.015, 5.115, 3.623, 4.903, 1.642, 1.84, 1.06, 0.063, 0.226, 0.656, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.023, 0.003, 0.004, 0.003, 0.002, 0.001, 0.001, 0.002, 0.001, 0.002, 0.0001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.008, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.007, 0.001, 0.001, 0.003, 0.003, 0.001, 0.002, 0.008, 0.009, 0.003, 0.002, 0.005, 0.002, 0.001, 0.003, 0.009, 0.038, 0.001, 0.051, 0.001, 0.005, 0.001, 0.011, 0.004, 0.003, 0.013, 0.008, 0.002, 0.002, 0.008, 0.001, 0.004, 0.001, 0.003, 0.002, 0.01, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.02, 0.166, 0.007, 0.01, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.016, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.022, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ko": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.893, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.919, 0.003, 0.069, 0.0001, 0.0001, 0.007, 0.002, 0.048, 0.269, 0.269, 0.0001, 0.002, 0.501, 0.04, 0.699, 0.01, 0.29, 0.417, 0.259, 0.125, 0.109, 0.112, 0.1, 0.094, 0.109, 0.192, 0.015, 0.002, 0.006, 0.002, 0.006, 0.003, 0.0001, 0.038, 0.026, 0.038, 0.022, 0.02, 0.024, 0.015, 0.013, 0.023, 0.008, 0.015, 0.017, 0.027, 0.016, 0.016, 0.023, 0.002, 0.017, 0.041, 0.027, 0.011, 0.013, 0.01, 0.005, 0.004, 0.002, 0.006, 0.0001, 0.006, 0.0001, 0.012, 0.0001, 0.108, 0.014, 0.037, 0.031, 0.116, 0.024, 0.022, 0.032, 0.084, 0.002, 0.021, 0.064, 0.06, 0.077, 0.092, 0.02, 0.001, 0.086, 0.056, 0.066, 0.046, 0.011, 0.008, 0.004, 0.019, 0.004, 0.0001, 0.002, 0.0001, 0.025, 0.0001, 2.21, 0.565, 0.766, 0.471, 3.043, 0.671, 0.334, 0.049, 1.404, 0.218, 1.17, 1.657, 1.23, 0.278, 0.091, 0.557, 1.645, 0.451, 0.058, 0.386, 1.38, 2.193, 0.506, 1.29, 2.708, 0.68, 0.385, 0.399, 2.758, 3.352, 0.954, 0.141, 1.848, 0.829, 0.071, 0.249, 1.741, 0.637, 0.43, 0.888, 0.537, 0.506, 0.243, 0.027, 1.4, 0.355, 0.026, 0.179, 2.38, 0.404, 0.739, 1.021, 2.205, 0.729, 0.454, 0.308, 1.635, 0.561, 0.035, 0.084, 1.612, 0.309, 0.024, 0.047, 0.0001, 0.0001, 0.034, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.039, 0.089, 0.025, 0.107, 0.071, 0.044, 0.037, 0.043, 3.199, 8.716, 12.558, 3.298, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cs": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.804, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.066, 0.002, 0.232, 0.0001, 0.0001, 0.008, 0.002, 0.009, 0.188, 0.188, 0.007, 0.002, 0.814, 0.094, 1.008, 0.025, 0.299, 0.437, 0.233, 0.115, 0.111, 0.119, 0.106, 0.102, 0.129, 0.233, 0.051, 0.011, 0.002, 0.002, 0.002, 0.002, 0.0001, 0.143, 0.145, 0.103, 0.117, 0.06, 0.072, 0.055, 0.092, 0.08, 0.13, 0.142, 0.093, 0.169, 0.137, 0.088, 0.246, 0.003, 0.104, 0.236, 0.127, 0.039, 0.213, 0.033, 0.007, 0.007, 0.069, 0.002, 0.0001, 0.002, 0.0001, 0.005, 0.0001, 5.018, 1.137, 1.8, 2.299, 5.465, 0.243, 0.288, 1.623, 3.2, 1.177, 2.624, 3.218, 2.048, 4.447, 5.813, 1.952, 0.006, 3.062, 3.218, 3.502, 2.227, 3.008, 0.043, 0.058, 1.313, 1.405, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.104, 0.003, 0.004, 0.003, 0.001, 0.001, 0.001, 0.003, 0.041, 0.001, 0.001, 0.001, 0.049, 0.57, 0.001, 0.012, 0.001, 0.001, 0.002, 0.048, 0.002, 0.001, 0.001, 0.002, 0.011, 0.748, 0.01, 0.981, 0.025, 0.001, 0.025, 0.002, 0.191, 1.9, 0.003, 0.001, 0.005, 0.024, 0.002, 0.002, 0.002, 0.87, 0.001, 0.001, 0.001, 1.984, 0.001, 0.336, 0.006, 0.002, 0.004, 0.031, 0.002, 0.003, 0.006, 0.001, 0.003, 0.001, 0.094, 0.002, 0.007, 0.671, 0.58, 0.001, 0.0001, 0.0001, 0.173, 5.104, 1.615, 2.233, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.021, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.009, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.103, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ar": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.65, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.194, 0.002, 0.102, 0.0001, 0.0001, 0.007, 0.001, 0.002, 0.109, 0.108, 0.002, 0.001, 0.03, 0.046, 0.42, 0.018, 0.182, 0.202, 0.135, 0.063, 0.065, 0.061, 0.055, 0.053, 0.062, 0.113, 0.054, 0.001, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.01, 0.006, 0.009, 0.007, 0.005, 0.004, 0.004, 0.004, 0.005, 0.002, 0.002, 0.005, 0.007, 0.005, 0.004, 0.007, 0.001, 0.005, 0.009, 0.006, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.007, 0.001, 0.007, 0.0001, 0.004, 0.0001, 0.052, 0.008, 0.019, 0.018, 0.055, 0.008, 0.011, 0.016, 0.045, 0.001, 0.006, 0.028, 0.016, 0.037, 0.04, 0.012, 0.001, 0.038, 0.03, 0.035, 0.02, 0.006, 0.006, 0.002, 0.009, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.055, 1.131, 0.874, 0.939, 4.804, 2.787, 2.235, 1.018, 2.407, 0.349, 3.542, 0.092, 0.4, 0.007, 0.051, 0.053, 0.022, 0.061, 0.01, 0.008, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.008, 0.001, 0.001, 0.0001, 0.002, 0.013, 0.133, 0.049, 0.782, 0.037, 0.335, 0.157, 6.208, 1.599, 1.486, 1.889, 0.276, 0.607, 0.762, 0.341, 1.38, 0.239, 2.041, 0.293, 1.149, 0.411, 0.383, 0.246, 0.406, 0.094, 1.401, 0.223, 0.006, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.027, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 23.298, 20.414, 0.003, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.019, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "vi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.205, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.546, 0.002, 0.241, 0.0001, 0.001, 0.015, 0.013, 0.009, 0.13, 0.13, 0.0001, 0.002, 0.714, 0.089, 0.813, 0.02, 0.259, 0.361, 0.203, 0.104, 0.097, 0.104, 0.089, 0.089, 0.116, 0.194, 0.047, 0.017, 0.002, 0.002, 0.002, 0.002, 0.0001, 0.148, 0.175, 0.293, 0.111, 0.056, 0.04, 0.092, 0.206, 0.057, 0.03, 0.119, 0.232, 0.178, 0.247, 0.036, 0.156, 0.056, 0.062, 0.184, 0.397, 0.022, 0.114, 0.033, 0.033, 0.019, 0.009, 0.005, 0.0001, 0.005, 0.0001, 0.003, 0.0001, 2.683, 0.66, 3.149, 0.627, 1.148, 0.076, 2.542, 4.362, 3.528, 0.019, 0.59, 1.486, 1.611, 5.924, 2.001, 0.761, 0.201, 1.559, 1.014, 3.555, 1.77, 0.861, 0.05, 0.173, 0.826, 0.047, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.021, 0.214, 0.011, 0.478, 0.002, 0.039, 0.001, 0.324, 0.002, 0.072, 0.001, 0.198, 0.002, 0.32, 0.002, 0.048, 0.141, 1.485, 0.001, 0.116, 0.015, 0.106, 0.001, 0.025, 0.002, 0.579, 0.004, 0.289, 0.004, 0.257, 0.005, 0.174, 1.516, 1.221, 0.326, 0.818, 0.013, 0.337, 0.005, 0.51, 0.014, 0.324, 0.408, 0.115, 0.147, 0.492, 0.002, 0.218, 0.82, 0.26, 0.102, 0.383, 0.379, 0.016, 0.006, 0.094, 0.005, 0.132, 2.233, 4.628, 0.009, 0.062, 0.003, 0.385, 0.0001, 0.0001, 0.047, 4.542, 1.653, 0.065, 0.997, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.011, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 6.74, 0.019, 0.004, 0.002, 0.009, 0.006, 0.004, 0.003, 0.003, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "el": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.389, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.245, 0.003, 0.167, 0.001, 0.0001, 0.005, 0.002, 0.015, 0.1, 0.101, 0.0001, 0.001, 0.487, 0.058, 0.449, 0.01, 0.151, 0.215, 0.114, 0.058, 0.055, 0.058, 0.052, 0.051, 0.065, 0.119, 0.032, 0.001, 0.003, 0.003, 0.003, 0.0001, 0.0001, 0.021, 0.016, 0.024, 0.014, 0.012, 0.012, 0.011, 0.013, 0.012, 0.005, 0.006, 0.013, 0.018, 0.01, 0.009, 0.015, 0.001, 0.013, 0.025, 0.017, 0.005, 0.006, 0.008, 0.002, 0.002, 0.001, 0.005, 0.0001, 0.005, 0.0001, 0.002, 0.0001, 0.125, 0.018, 0.039, 0.039, 0.142, 0.017, 0.026, 0.036, 0.105, 0.002, 0.017, 0.072, 0.036, 0.093, 0.102, 0.022, 0.002, 0.099, 0.07, 0.077, 0.046, 0.014, 0.01, 0.005, 0.02, 0.005, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 1.502, 1.948, 1.522, 1.805, 3.613, 1.458, 0.354, 0.481, 0.073, 0.584, 0.024, 0.002, 0.912, 0.435, 0.305, 0.001, 0.006, 0.156, 0.057, 0.068, 0.049, 0.097, 0.01, 0.064, 0.017, 0.048, 0.112, 0.037, 0.115, 0.048, 0.003, 0.099, 0.122, 0.029, 0.001, 0.129, 0.119, 0.011, 0.03, 0.034, 0.002, 0.008, 0.0001, 0.022, 0.85, 0.749, 0.601, 1.063, 0.004, 3.95, 0.27, 0.716, 0.649, 2.656, 0.14, 1.63, 0.422, 2.831, 1.733, 1.214, 1.337, 2.636, 0.149, 3.615, 0.0001, 0.0001, 0.06, 0.007, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 28.675, 14.922, 0.013, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.282, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.667, 0.001, 0.345, 0.0001, 0.0001, 0.007, 0.002, 0.013, 0.083, 0.083, 0.0001, 0.0001, 0.902, 0.146, 1.182, 0.007, 0.152, 0.25, 0.108, 0.06, 0.06, 0.065, 0.065, 0.066, 0.089, 0.153, 0.044, 0.004, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.178, 0.164, 0.421, 0.354, 0.095, 0.078, 0.149, 0.127, 0.181, 0.06, 0.161, 0.209, 0.174, 0.099, 0.072, 0.149, 0.019, 0.12, 0.249, 0.206, 0.034, 0.058, 0.04, 0.006, 0.012, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 6.63, 0.945, 0.963, 3.448, 8.696, 0.922, 2.03, 1.373, 4.448, 0.429, 1.949, 3.417, 3.024, 6.448, 3.193, 1.076, 0.019, 6.923, 3.891, 5.562, 1.877, 1.653, 0.074, 0.114, 0.424, 0.075, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.022, 0.039, 0.002, 0.003, 0.007, 0.074, 0.004, 0.007, 0.005, 0.002, 0.002, 0.0001, 0.003, 0.008, 0.002, 0.004, 0.001, 0.002, 0.0001, 0.011, 0.001, 0.001, 0.012, 0.001, 0.005, 0.002, 0.001, 0.001, 0.001, 0.004, 0.001, 0.003, 0.21, 0.017, 0.005, 0.004, 1.574, 0.853, 0.002, 0.007, 0.008, 0.038, 0.004, 0.047, 0.001, 0.014, 0.002, 0.009, 0.187, 0.01, 0.004, 0.012, 0.004, 0.002, 0.808, 0.001, 0.008, 0.002, 0.004, 0.002, 0.006, 0.002, 0.003, 0.001, 0.0001, 0.0001, 0.393, 3.436, 0.069, 0.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.014, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.021, 0.021, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.019, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.827, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.714, 0.004, 0.265, 0.0001, 0.0001, 0.007, 0.001, 0.007, 0.159, 0.159, 0.001, 0.002, 1.016, 0.461, 0.937, 0.013, 0.261, 0.429, 0.206, 0.109, 0.106, 0.113, 0.103, 0.105, 0.137, 0.238, 0.073, 0.019, 0.004, 0.004, 0.004, 0.002, 0.0001, 0.469, 0.135, 0.097, 0.073, 0.142, 0.093, 0.075, 0.087, 0.095, 0.062, 0.133, 0.086, 0.175, 0.085, 0.042, 0.096, 0.003, 0.071, 0.186, 0.107, 0.027, 0.069, 0.028, 0.009, 0.008, 0.025, 0.002, 0.0001, 0.002, 0.0001, 0.004, 0.0001, 6.316, 1.591, 0.619, 1.364, 7.125, 0.648, 2.159, 0.946, 3.15, 0.796, 3.265, 4.526, 2.054, 3.978, 3.047, 0.846, 0.006, 3.327, 4.35, 5.787, 0.902, 1.395, 0.037, 0.035, 1.463, 2.94, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.129, 0.02, 0.003, 0.003, 0.001, 0.001, 0.001, 0.003, 0.002, 0.014, 0.001, 0.001, 0.001, 0.006, 0.0001, 0.001, 0.004, 0.667, 0.001, 0.068, 0.001, 0.0001, 0.005, 0.001, 0.001, 0.009, 0.007, 0.002, 0.003, 0.026, 0.026, 0.002, 0.024, 2.603, 0.002, 0.001, 0.003, 0.001, 0.002, 0.002, 0.003, 2.374, 0.001, 0.002, 0.001, 0.448, 0.001, 0.001, 0.005, 0.169, 0.003, 0.702, 0.002, 0.002, 0.76, 0.001, 0.004, 0.002, 0.223, 0.002, 0.382, 0.004, 0.004, 0.001, 0.0001, 0.0001, 0.028, 7.544, 0.01, 0.845, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.021, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.128, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ro": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.178, 0.003, 0.287, 0.001, 0.001, 0.038, 0.002, 0.011, 0.2, 0.201, 0.001, 0.002, 1.114, 0.333, 0.783, 0.015, 0.314, 0.397, 0.224, 0.108, 0.105, 0.107, 0.098, 0.099, 0.123, 0.221, 0.062, 0.021, 0.007, 0.006, 0.007, 0.002, 0.0001, 0.27, 0.164, 0.289, 0.16, 0.109, 0.099, 0.098, 0.077, 0.163, 0.044, 0.047, 0.132, 0.205, 0.095, 0.07, 0.207, 0.004, 0.158, 0.242, 0.12, 0.072, 0.085, 0.033, 0.021, 0.01, 0.019, 0.006, 0.0001, 0.006, 0.0001, 0.007, 0.0001, 7.568, 0.638, 3.253, 2.492, 8.352, 0.862, 0.693, 0.377, 7.77, 0.16, 0.142, 3.906, 1.919, 5.009, 3.799, 1.948, 0.008, 5.326, 2.857, 4.711, 4.259, 0.743, 0.045, 0.139, 0.103, 0.506, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.128, 0.004, 0.004, 1.675, 0.002, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.003, 0.104, 0.001, 0.001, 0.002, 0.001, 0.018, 0.003, 0.001, 0.001, 0.001, 0.016, 0.733, 0.007, 0.695, 0.006, 0.05, 0.046, 0.002, 0.038, 0.012, 0.339, 0.002, 0.003, 0.001, 0.001, 0.002, 0.004, 0.016, 0.001, 0.003, 0.001, 0.004, 0.716, 0.001, 0.007, 0.003, 0.004, 0.005, 0.003, 0.002, 0.005, 0.001, 0.003, 0.001, 0.002, 0.003, 0.007, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.048, 1.213, 1.681, 0.01, 0.0001, 0.003, 1.446, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.003, 0.016, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.127, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "id": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.029, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.265, 0.003, 0.293, 0.001, 0.002, 0.008, 0.004, 0.02, 0.156, 0.156, 0.001, 0.002, 0.897, 0.232, 0.837, 0.025, 0.281, 0.301, 0.205, 0.089, 0.081, 0.088, 0.077, 0.074, 0.084, 0.156, 0.047, 0.017, 0.004, 0.004, 0.004, 0.002, 0.0001, 0.336, 0.259, 0.156, 0.221, 0.076, 0.084, 0.101, 0.111, 0.249, 0.128, 0.292, 0.143, 0.276, 0.131, 0.06, 0.365, 0.008, 0.137, 0.448, 0.233, 0.076, 0.043, 0.063, 0.011, 0.049, 0.014, 0.01, 0.0001, 0.01, 0.0001, 0.002, 0.0001, 14.771, 1.913, 0.506, 3.424, 6.588, 0.273, 2.854, 1.797, 6.389, 0.58, 3.078, 2.893, 3.104, 7.626, 2.047, 2.047, 0.011, 4.279, 3.371, 3.841, 3.795, 0.171, 0.34, 0.026, 1.249, 0.063, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.031, 0.005, 0.004, 0.003, 0.003, 0.002, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.004, 0.002, 0.001, 0.001, 0.001, 0.001, 0.012, 0.003, 0.001, 0.001, 0.001, 0.002, 0.005, 0.001, 0.001, 0.006, 0.006, 0.001, 0.002, 0.051, 0.005, 0.002, 0.002, 0.003, 0.001, 0.002, 0.003, 0.002, 0.009, 0.001, 0.002, 0.001, 0.003, 0.001, 0.001, 0.004, 0.003, 0.004, 0.003, 0.002, 0.002, 0.002, 0.001, 0.003, 0.002, 0.002, 0.002, 0.004, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.055, 0.03, 0.005, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.003, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.006, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.03, 0.003, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.159, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.105, 0.002, 0.192, 0.0001, 0.0001, 0.007, 0.002, 0.005, 0.209, 0.21, 0.013, 0.002, 0.819, 0.162, 1.046, 0.023, 0.302, 0.407, 0.233, 0.125, 0.121, 0.119, 0.111, 0.11, 0.127, 0.222, 0.055, 0.011, 0.002, 0.003, 0.002, 0.001, 0.0001, 0.172, 0.157, 0.128, 0.107, 0.068, 0.073, 0.08, 0.101, 0.088, 0.103, 0.136, 0.098, 0.191, 0.186, 0.106, 0.263, 0.004, 0.11, 0.26, 0.138, 0.041, 0.2, 0.032, 0.006, 0.008, 0.071, 0.001, 0.0001, 0.001, 0.0001, 0.004, 0.0001, 6.363, 1.243, 1.749, 2.177, 5.774, 0.29, 0.367, 1.611, 4.04, 1.457, 2.743, 2.816, 2.062, 4.279, 6.818, 1.868, 0.006, 3.912, 3.184, 3.285, 2.066, 3.292, 0.044, 0.067, 1.073, 1.331, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.113, 0.006, 0.004, 0.002, 0.002, 0.001, 0.001, 0.002, 0.077, 0.003, 0.0001, 0.001, 0.033, 0.618, 0.006, 0.066, 0.001, 0.001, 0.001, 0.046, 0.001, 0.006, 0.001, 0.001, 0.001, 0.013, 0.009, 0.007, 0.027, 0.001, 0.026, 0.001, 0.106, 1.828, 0.001, 0.001, 0.067, 0.259, 0.001, 0.002, 0.006, 0.586, 0.001, 0.001, 0.001, 0.717, 0.001, 0.002, 0.005, 0.002, 0.004, 0.16, 0.12, 0.002, 0.005, 0.038, 0.002, 0.001, 0.54, 0.002, 0.006, 0.806, 0.828, 0.001, 0.0001, 0.0001, 0.114, 4.297, 1.036, 1.463, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.003, 0.014, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.112, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "da": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.925, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.716, 0.002, 0.323, 0.001, 0.001, 0.007, 0.004, 0.044, 0.149, 0.15, 0.001, 0.001, 0.888, 0.199, 1.047, 0.017, 0.356, 0.494, 0.245, 0.119, 0.115, 0.124, 0.118, 0.127, 0.168, 0.257, 0.046, 0.018, 0.001, 0.002, 0.001, 0.002, 0.0001, 0.185, 0.17, 0.132, 0.265, 0.124, 0.155, 0.096, 0.211, 0.151, 0.076, 0.153, 0.12, 0.178, 0.102, 0.069, 0.125, 0.005, 0.111, 0.307, 0.131, 0.057, 0.087, 0.054, 0.005, 0.012, 0.01, 0.002, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 4.818, 1.29, 0.375, 4.241, 11.595, 1.856, 2.915, 1.153, 4.647, 0.373, 2.179, 3.858, 2.304, 5.903, 3.8, 1.073, 0.008, 6.456, 4.455, 5.128, 1.418, 1.705, 0.066, 0.033, 0.579, 0.056, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.052, 0.003, 0.002, 0.001, 0.001, 0.008, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.033, 0.003, 0.0001, 0.001, 0.001, 0.013, 0.005, 0.0001, 0.001, 0.002, 0.008, 0.001, 0.002, 0.01, 0.006, 0.001, 0.001, 0.01, 0.595, 0.559, 0.002, 0.002, 0.02, 0.001, 0.004, 0.001, 0.004, 0.001, 0.001, 0.005, 0.002, 0.003, 0.005, 0.001, 0.001, 0.011, 0.001, 0.585, 0.001, 0.002, 0.003, 0.011, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.02, 1.836, 0.004, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.052, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.851, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.647, 0.002, 0.239, 0.0001, 0.0001, 0.006, 0.003, 0.009, 0.115, 0.115, 0.0001, 0.004, 0.594, 0.296, 1.014, 0.011, 0.404, 0.475, 0.268, 0.112, 0.107, 0.117, 0.106, 0.107, 0.133, 0.295, 0.069, 0.007, 0.003, 0.004, 0.003, 0.001, 0.0001, 0.183, 0.111, 0.1, 0.068, 0.113, 0.064, 0.065, 0.195, 0.087, 0.098, 0.225, 0.146, 0.211, 0.097, 0.06, 0.172, 0.005, 0.116, 0.314, 0.181, 0.037, 0.143, 0.044, 0.006, 0.048, 0.009, 0.001, 0.0001, 0.001, 0.0001, 0.004, 0.0001, 9.681, 0.162, 0.176, 0.832, 6.272, 0.12, 0.289, 1.322, 8.475, 1.576, 3.754, 4.597, 2.281, 6.958, 4.47, 1.345, 0.007, 2.326, 6.029, 6.589, 4.108, 1.653, 0.05, 0.021, 1.301, 0.041, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.101, 0.002, 0.002, 0.001, 0.004, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.061, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.008, 0.0001, 0.001, 0.001, 0.032, 0.0001, 0.001, 0.032, 0.02, 0.001, 0.001, 2.624, 0.003, 0.001, 0.001, 0.002, 0.014, 0.0001, 0.002, 0.001, 0.01, 0.001, 0.001, 0.003, 0.002, 0.002, 0.005, 0.001, 0.001, 0.349, 0.001, 0.002, 0.001, 0.002, 0.001, 0.005, 0.002, 0.004, 0.001, 0.0001, 0.0001, 0.039, 3.028, 0.006, 0.023, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.101, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "th": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.353, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.736, 0.001, 0.084, 0.0001, 0.0001, 0.003, 0.001, 0.003, 0.081, 0.081, 0.0001, 0.001, 0.043, 0.029, 0.16, 0.005, 0.088, 0.106, 0.121, 0.047, 0.051, 0.082, 0.032, 0.03, 0.033, 0.045, 0.008, 0.004, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.013, 0.009, 0.013, 0.008, 0.008, 0.006, 0.006, 0.006, 0.008, 0.003, 0.003, 0.006, 0.01, 0.006, 0.005, 0.009, 0.001, 0.007, 0.015, 0.012, 0.003, 0.003, 0.006, 0.001, 0.002, 0.001, 0.003, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 0.08, 0.011, 0.029, 0.025, 0.092, 0.012, 0.017, 0.027, 0.069, 0.001, 0.009, 0.042, 0.023, 0.063, 0.066, 0.017, 0.001, 0.062, 0.045, 0.056, 0.028, 0.008, 0.007, 0.003, 0.015, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 1.311, 1.859, 0.629, 0.364, 0.845, 0.001, 0.034, 1.547, 1.721, 0.971, 0.381, 0.156, 0.367, 0.089, 0.014, 0.016, 0.045, 0.009, 0.014, 0.115, 0.776, 0.653, 0.138, 0.742, 0.12, 1.918, 0.573, 0.602, 0.112, 0.028, 0.443, 0.069, 0.115, 1.089, 0.883, 1.745, 0.026, 0.859, 0.001, 0.829, 0.228, 0.108, 0.682, 0.53, 0.008, 1.369, 0.031, 0.006, 0.627, 1.083, 2.149, 0.218, 0.714, 0.916, 0.178, 0.322, 26.536, 5.927, 0.003, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.884, 0.001, 0.018, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.55, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.448, 0.001, 0.106, 0.0001, 0.0001, 0.005, 0.001, 0.003, 0.12, 0.12, 0.002, 0.001, 0.557, 0.131, 0.613, 0.011, 0.182, 0.272, 0.137, 0.074, 0.072, 0.075, 0.066, 0.065, 0.083, 0.144, 0.028, 0.009, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.013, 0.009, 0.015, 0.008, 0.007, 0.006, 0.006, 0.006, 0.041, 0.002, 0.003, 0.007, 0.011, 0.006, 0.005, 0.01, 0.001, 0.006, 0.015, 0.011, 0.003, 0.01, 0.005, 0.007, 0.001, 0.001, 0.003, 0.0001, 0.003, 0.0001, 0.002, 0.0001, 0.088, 0.012, 0.031, 0.028, 0.092, 0.009, 0.016, 0.024, 0.077, 0.002, 0.014, 0.045, 0.037, 0.056, 0.066, 0.019, 0.001, 0.063, 0.052, 0.05, 0.037, 0.008, 0.006, 0.003, 0.013, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.651, 2.091, 3.127, 0.625, 0.166, 0.165, 0.297, 0.452, 0.133, 0.189, 0.677, 0.001, 0.018, 0.001, 0.079, 0.727, 0.091, 0.092, 0.108, 0.095, 0.081, 0.039, 0.009, 0.034, 0.052, 0.011, 0.114, 0.044, 0.167, 0.089, 0.136, 0.155, 0.116, 0.171, 0.083, 0.024, 0.037, 0.04, 0.014, 0.018, 0.016, 0.009, 0.001, 0.0001, 0.001, 0.002, 0.012, 0.008, 5.212, 0.516, 1.875, 0.701, 1.296, 3.589, 0.274, 0.882, 3.979, 0.288, 1.391, 1.465, 0.909, 3.169, 3.698, 1.109, 0.0001, 0.0001, 0.048, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.0001, 0.015, 0.006, 31.942, 11.185, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.201, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "he": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.485, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.289, 0.001, 0.262, 0.0001, 0.0001, 0.005, 0.001, 0.096, 0.104, 0.103, 0.0001, 0.001, 0.64, 0.203, 0.573, 0.005, 0.181, 0.234, 0.129, 0.06, 0.061, 0.062, 0.055, 0.054, 0.065, 0.138, 0.049, 0.013, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.016, 0.011, 0.014, 0.009, 0.007, 0.007, 0.006, 0.007, 0.009, 0.003, 0.003, 0.008, 0.012, 0.007, 0.005, 0.01, 0.001, 0.008, 0.016, 0.012, 0.003, 0.004, 0.005, 0.002, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.007, 0.0001, 0.073, 0.008, 0.021, 0.022, 0.081, 0.015, 0.013, 0.021, 0.056, 0.001, 0.007, 0.043, 0.024, 0.051, 0.061, 0.011, 0.001, 0.058, 0.038, 0.043, 0.032, 0.007, 0.005, 0.003, 0.012, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.003, 0.002, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 2.008, 2.447, 0.696, 1.135, 3.773, 4.868, 0.394, 0.995, 0.678, 4.903, 0.173, 0.854, 2.776, 1.153, 2.22, 0.562, 1.585, 0.919, 1.159, 0.101, 0.969, 0.062, 0.568, 1.054, 2.634, 1.902, 2.428, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.009, 0.002, 0.002, 0.002, 0.006, 0.004, 0.005, 0.005, 0.008, 0.005, 0.001, 0.002, 0.01, 0.002, 0.005, 0.001, 0.0001, 0.0001, 0.008, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.015, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.044, 42.985, 0.006, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.013, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "uk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.595, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.309, 0.001, 0.06, 0.0001, 0.001, 0.01, 0.001, 0.059, 0.134, 0.135, 0.002, 0.002, 0.619, 0.137, 0.568, 0.01, 0.199, 0.281, 0.159, 0.081, 0.077, 0.082, 0.071, 0.067, 0.079, 0.158, 0.041, 0.017, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.014, 0.009, 0.015, 0.009, 0.007, 0.006, 0.007, 0.006, 0.029, 0.002, 0.003, 0.007, 0.011, 0.006, 0.005, 0.01, 0.001, 0.008, 0.016, 0.01, 0.003, 0.01, 0.004, 0.011, 0.001, 0.001, 0.003, 0.0001, 0.003, 0.0001, 0.004, 0.0001, 0.067, 0.008, 0.022, 0.02, 0.069, 0.01, 0.012, 0.018, 0.056, 0.001, 0.008, 0.037, 0.02, 0.046, 0.054, 0.014, 0.001, 0.051, 0.037, 0.039, 0.027, 0.007, 0.006, 0.003, 0.012, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.481, 1.842, 2.043, 1.429, 0.162, 0.46, 0.448, 0.496, 0.265, 0.125, 0.001, 0.003, 0.806, 0.001, 0.316, 0.84, 0.08, 0.077, 0.114, 0.065, 0.394, 0.018, 2.734, 0.422, 0.001, 0.01, 0.11, 0.047, 0.088, 0.083, 0.052, 0.13, 0.228, 0.124, 0.058, 0.089, 0.032, 0.023, 0.02, 0.023, 0.023, 0.004, 0.0001, 0.09, 0.0001, 0.001, 0.008, 0.014, 3.574, 0.601, 2.221, 0.664, 1.335, 1.986, 0.299, 0.851, 2.427, 0.557, 1.658, 1.688, 1.249, 3.061, 4.029, 1.082, 0.0001, 0.0001, 0.335, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.018, 0.0001, 0.002, 0.001, 28.71, 14.784, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.144, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lt": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.086, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.626, 0.002, 0.167, 0.001, 0.0001, 0.009, 0.001, 0.01, 0.234, 0.234, 0.001, 0.002, 1.069, 0.088, 1.436, 0.009, 0.347, 0.549, 0.256, 0.135, 0.132, 0.151, 0.128, 0.13, 0.15, 0.368, 0.06, 0.018, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.213, 0.143, 0.054, 0.128, 0.066, 0.049, 0.096, 0.041, 0.157, 0.121, 0.23, 0.188, 0.16, 0.109, 0.037, 0.238, 0.002, 0.129, 0.21, 0.163, 0.036, 0.209, 0.013, 0.047, 0.01, 0.016, 0.002, 0.0001, 0.002, 0.0001, 0.003, 0.0001, 8.107, 0.954, 0.391, 1.797, 4.13, 0.204, 1.223, 0.172, 9.411, 1.587, 2.883, 2.415, 2.501, 3.736, 4.946, 1.811, 0.003, 4.047, 5.62, 3.782, 3.399, 1.76, 0.016, 0.008, 1.047, 0.248, 0.0001, 0.015, 0.0001, 0.002, 0.0001, 0.475, 0.005, 0.003, 0.002, 0.002, 0.411, 0.001, 0.001, 0.006, 0.001, 0.001, 0.001, 0.019, 0.313, 0.0001, 0.001, 0.001, 0.001, 0.006, 0.247, 0.001, 0.0001, 0.001, 1.225, 0.001, 0.136, 0.001, 0.001, 0.108, 0.003, 0.111, 0.001, 0.364, 0.781, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.003, 0.002, 0.299, 0.001, 0.004, 0.013, 0.355, 0.007, 0.002, 0.007, 0.931, 0.001, 0.004, 0.001, 0.001, 0.004, 0.002, 0.003, 0.003, 0.003, 0.037, 0.575, 0.001, 0.0001, 0.0001, 0.29, 0.016, 2.467, 2.697, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.033, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.477, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.115, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.127, 0.002, 0.244, 0.0001, 0.0001, 0.007, 0.004, 0.029, 0.125, 0.125, 0.001, 0.001, 0.736, 0.236, 1.026, 0.016, 0.357, 0.45, 0.2, 0.113, 0.108, 0.13, 0.122, 0.121, 0.148, 0.271, 0.033, 0.009, 0.004, 0.002, 0.004, 0.001, 0.0001, 0.218, 0.193, 0.121, 0.247, 0.133, 0.148, 0.105, 0.221, 0.171, 0.071, 0.137, 0.127, 0.194, 0.145, 0.08, 0.133, 0.007, 0.124, 0.352, 0.152, 0.062, 0.099, 0.053, 0.006, 0.016, 0.016, 0.005, 0.0001, 0.005, 0.0001, 0.002, 0.001, 6.479, 0.879, 0.246, 3.008, 9.683, 1.285, 2.701, 0.948, 5.112, 0.784, 2.645, 3.726, 2.383, 5.836, 3.991, 1.273, 0.009, 6.373, 4.403, 5.512, 1.465, 1.904, 0.067, 0.025, 0.761, 0.055, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.031, 0.01, 0.005, 0.003, 0.003, 0.012, 0.002, 0.003, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.02, 0.003, 0.002, 0.002, 0.001, 0.013, 0.005, 0.002, 0.001, 0.002, 0.001, 0.001, 0.003, 0.042, 0.013, 0.002, 0.002, 0.016, 0.934, 0.093, 0.004, 0.01, 0.021, 0.004, 0.076, 0.002, 0.01, 0.001, 0.002, 0.012, 0.007, 0.039, 0.01, 0.004, 0.006, 0.015, 0.002, 0.552, 0.004, 0.006, 0.078, 0.011, 0.006, 0.007, 0.003, 0.0001, 0.0001, 0.197, 1.726, 0.009, 0.008, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.017, 0.007, 0.044, 0.016, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.01, 0.009, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.002, 0.027, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.893, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.172, 0.002, 0.34, 0.0001, 0.001, 0.011, 0.002, 0.016, 0.182, 0.182, 0.001, 0.002, 0.943, 0.135, 1.23, 0.019, 0.3, 0.38, 0.204, 0.106, 0.1, 0.109, 0.096, 0.094, 0.112, 0.22, 0.065, 0.02, 0.009, 0.004, 0.009, 0.002, 0.0001, 0.156, 0.17, 0.109, 0.14, 0.063, 0.069, 0.111, 0.12, 0.137, 0.079, 0.163, 0.086, 0.175, 0.178, 0.118, 0.22, 0.004, 0.116, 0.267, 0.137, 0.108, 0.095, 0.03, 0.008, 0.009, 0.078, 0.011, 0.0001, 0.011, 0.0001, 0.002, 0.0001, 8.648, 1.028, 0.78, 2.344, 6.653, 0.218, 1.346, 0.572, 7.393, 3.932, 2.783, 2.724, 2.195, 4.91, 6.755, 1.994, 0.007, 4.039, 3.61, 3.329, 3.254, 2.478, 0.043, 0.016, 0.083, 1.288, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.039, 0.005, 0.004, 0.003, 0.002, 0.001, 0.003, 0.353, 0.002, 0.001, 0.001, 0.001, 0.016, 0.678, 0.001, 0.001, 0.004, 0.158, 0.001, 0.011, 0.002, 0.001, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.009, 0.005, 0.008, 0.001, 0.033, 0.524, 0.003, 0.002, 0.003, 0.001, 0.001, 0.002, 0.002, 0.01, 0.001, 0.005, 0.001, 0.004, 0.001, 0.001, 0.008, 0.004, 0.005, 0.005, 0.002, 0.004, 0.004, 0.001, 0.004, 0.002, 0.004, 0.006, 0.006, 0.016, 0.36, 0.002, 0.0001, 0.0001, 0.021, 0.044, 1.208, 0.914, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.011, 0.005, 0.028, 0.01, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.038, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "no": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.028, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.853, 0.002, 0.247, 0.0001, 0.001, 0.006, 0.004, 0.016, 0.159, 0.158, 0.001, 0.001, 0.698, 0.213, 1.037, 0.017, 0.377, 0.496, 0.255, 0.116, 0.113, 0.123, 0.117, 0.116, 0.152, 0.295, 0.042, 0.013, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.196, 0.176, 0.125, 0.246, 0.126, 0.148, 0.099, 0.211, 0.167, 0.071, 0.132, 0.135, 0.185, 0.133, 0.091, 0.127, 0.006, 0.11, 0.321, 0.146, 0.058, 0.092, 0.051, 0.007, 0.014, 0.011, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 4.956, 1.168, 0.243, 2.996, 11.38, 1.384, 2.632, 1.02, 4.719, 0.546, 2.591, 3.946, 2.341, 6.218, 3.979, 1.354, 0.009, 6.417, 4.712, 5.821, 1.424, 1.732, 0.061, 0.029, 0.639, 0.049, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.041, 0.006, 0.003, 0.002, 0.002, 0.009, 0.002, 0.002, 0.001, 0.002, 0.001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.034, 0.002, 0.001, 0.002, 0.001, 0.014, 0.003, 0.001, 0.001, 0.001, 0.002, 0.001, 0.002, 0.028, 0.009, 0.001, 0.002, 0.012, 0.765, 0.126, 0.003, 0.003, 0.021, 0.001, 0.062, 0.001, 0.006, 0.001, 0.001, 0.007, 0.003, 0.006, 0.006, 0.002, 0.003, 0.012, 0.001, 0.598, 0.002, 0.004, 0.062, 0.009, 0.004, 0.004, 0.002, 0.0001, 0.0001, 0.152, 1.588, 0.007, 0.007, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.004, 0.022, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.039, 0.001, 0.001, 0.004, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.872, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.68, 0.001, 0.1, 0.0001, 0.0001, 0.009, 0.0001, 0.005, 0.176, 0.176, 0.0001, 0.003, 0.5, 0.178, 0.762, 0.011, 0.275, 0.318, 0.214, 0.099, 0.096, 0.093, 0.078, 0.075, 0.084, 0.129, 0.031, 0.008, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.017, 0.01, 0.025, 0.013, 0.007, 0.006, 0.019, 0.007, 0.026, 0.003, 0.008, 0.007, 0.014, 0.016, 0.013, 0.016, 0.001, 0.009, 0.02, 0.011, 0.006, 0.008, 0.003, 0.004, 0.001, 0.003, 0.002, 0.0001, 0.002, 0.0001, 0.018, 0.0001, 0.453, 0.047, 0.05, 0.128, 0.37, 0.027, 0.066, 0.039, 0.393, 0.16, 0.152, 0.148, 0.154, 0.268, 0.352, 0.1, 0.001, 0.219, 0.193, 0.185, 0.165, 0.107, 0.003, 0.002, 0.007, 0.07, 0.053, 0.001, 0.053, 0.0001, 0.0001, 2.152, 2.07, 1.61, 1.756, 0.112, 0.204, 0.344, 0.339, 0.366, 0.003, 0.007, 0.001, 0.001, 0.031, 0.0001, 0.007, 0.082, 0.095, 0.143, 0.054, 0.071, 0.047, 0.006, 0.035, 1.459, 0.284, 0.347, 0.2, 0.143, 0.119, 0.086, 0.186, 0.072, 0.175, 0.071, 0.052, 0.034, 0.041, 0.014, 0.02, 0.016, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 4.933, 0.477, 1.401, 0.663, 1.33, 3.708, 0.225, 0.704, 3.913, 0.001, 1.472, 1.2, 1.198, 2.623, 3.682, 1.022, 0.0001, 0.0001, 0.018, 0.003, 0.054, 0.041, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 30.181, 10.982, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.062, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ca": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.816, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.948, 0.002, 0.294, 0.001, 0.011, 0.035, 0.001, 0.634, 0.154, 0.154, 0.001, 0.002, 1.001, 0.144, 0.747, 0.01, 0.301, 0.411, 0.25, 0.137, 0.131, 0.135, 0.12, 0.123, 0.144, 0.212, 0.051, 0.029, 0.002, 0.003, 0.003, 0.001, 0.0001, 0.252, 0.125, 0.23, 0.119, 0.296, 0.09, 0.091, 0.066, 0.12, 0.061, 0.034, 0.213, 0.174, 0.072, 0.049, 0.171, 0.012, 0.097, 0.192, 0.11, 0.053, 0.092, 0.024, 0.034, 0.01, 0.009, 0.002, 0.0001, 0.002, 0.0001, 0.004, 0.0001, 9.132, 1.004, 2.746, 3.236, 9.343, 0.681, 0.95, 0.465, 5.412, 0.169, 0.095, 4.932, 2.114, 4.848, 3.551, 1.884, 0.571, 5.202, 5.696, 4.416, 2.672, 1.094, 0.036, 0.312, 0.252, 0.123, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.044, 0.004, 0.004, 0.002, 0.002, 0.001, 0.001, 0.001, 0.002, 0.015, 0.001, 0.001, 0.001, 0.005, 0.001, 0.001, 0.001, 0.001, 0.002, 0.006, 0.003, 0.001, 0.001, 0.001, 0.001, 0.021, 0.001, 0.001, 0.003, 0.003, 0.001, 0.001, 0.327, 0.012, 0.002, 0.002, 0.002, 0.001, 0.001, 0.088, 0.218, 0.355, 0.001, 0.01, 0.003, 0.236, 0.001, 0.038, 0.005, 0.007, 0.161, 0.374, 0.002, 0.003, 0.003, 0.047, 0.003, 0.002, 0.063, 0.01, 0.034, 0.003, 0.002, 0.002, 0.0001, 0.0001, 0.099, 1.903, 0.005, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.004, 0.012, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.039, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.06, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.437, 0.024, 0.237, 0.001, 0.001, 0.007, 0.002, 0.011, 0.174, 0.174, 0.021, 0.002, 1.072, 0.17, 1.037, 0.022, 0.277, 0.429, 0.215, 0.122, 0.124, 0.121, 0.109, 0.108, 0.134, 0.239, 0.061, 0.025, 0.005, 0.006, 0.005, 0.002, 0.0001, 0.162, 0.141, 0.1, 0.122, 0.063, 0.075, 0.091, 0.086, 0.111, 0.082, 0.154, 0.138, 0.185, 0.145, 0.099, 0.224, 0.004, 0.106, 0.263, 0.133, 0.042, 0.163, 0.031, 0.007, 0.007, 0.087, 0.013, 0.0001, 0.014, 0.0001, 0.006, 0.0001, 7.7, 1.204, 0.709, 2.364, 7.782, 0.229, 1.139, 0.879, 6.985, 3.327, 2.701, 3.64, 2.037, 5.283, 6.653, 2.232, 0.006, 4.152, 3.513, 3.409, 1.654, 3.049, 0.039, 0.016, 0.079, 1.473, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 0.054, 0.004, 0.003, 0.002, 0.002, 0.001, 0.001, 0.011, 0.002, 0.002, 0.0001, 0.001, 0.021, 0.847, 0.001, 0.0001, 0.001, 0.002, 0.002, 0.027, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.056, 0.644, 0.007, 0.001, 0.003, 0.001, 0.001, 0.002, 0.003, 0.013, 0.001, 0.027, 0.001, 0.005, 0.001, 0.001, 0.007, 0.003, 0.004, 0.005, 0.002, 0.003, 0.006, 0.001, 0.004, 0.002, 0.004, 0.028, 0.008, 0.018, 0.391, 0.002, 0.0001, 0.0001, 0.071, 0.059, 0.881, 1.071, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.01, 0.005, 0.024, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.054, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.879, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.099, 0.004, 0.432, 0.0001, 0.0001, 0.013, 0.002, 0.007, 0.207, 0.208, 0.0001, 0.003, 0.965, 0.082, 1.276, 0.01, 0.332, 0.476, 0.254, 0.122, 0.117, 0.123, 0.105, 0.106, 0.127, 0.271, 0.045, 0.023, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.208, 0.134, 0.062, 0.128, 0.074, 0.067, 0.074, 0.058, 0.112, 0.068, 0.189, 0.194, 0.144, 0.089, 0.055, 0.234, 0.002, 0.136, 0.249, 0.163, 0.042, 0.182, 0.012, 0.007, 0.003, 0.051, 0.001, 0.0001, 0.001, 0.0001, 0.003, 0.0001, 8.58, 1.078, 0.806, 2.221, 4.451, 0.231, 1.228, 0.175, 6.667, 1.704, 2.603, 2.424, 2.389, 3.209, 2.883, 1.908, 0.003, 4.056, 5.825, 4.121, 3.633, 1.801, 0.012, 0.009, 0.029, 1.289, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.124, 2.988, 0.003, 0.002, 0.001, 0.006, 0.331, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.015, 0.083, 0.0001, 0.001, 0.001, 0.001, 0.007, 1.174, 0.07, 0.0001, 0.001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.005, 0.012, 0.009, 0.001, 0.06, 0.627, 0.004, 0.097, 0.002, 0.001, 0.001, 0.001, 0.001, 0.002, 0.006, 1.565, 0.0001, 0.002, 0.0001, 0.0001, 0.01, 0.002, 0.005, 0.002, 0.002, 0.005, 0.01, 0.106, 0.006, 0.002, 0.003, 0.01, 0.298, 0.012, 0.176, 0.002, 0.0001, 0.0001, 0.03, 0.013, 6.068, 1.452, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.051, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.11, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "et": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.183, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.759, 0.003, 0.281, 0.0001, 0.0001, 0.013, 0.001, 0.037, 0.198, 0.199, 0.001, 0.003, 0.786, 0.203, 1.175, 0.017, 0.35, 0.548, 0.272, 0.142, 0.137, 0.143, 0.127, 0.129, 0.154, 0.323, 0.059, 0.022, 0.017, 0.003, 0.017, 0.003, 0.0001, 0.235, 0.096, 0.074, 0.061, 0.173, 0.056, 0.064, 0.105, 0.122, 0.088, 0.255, 0.166, 0.186, 0.114, 0.065, 0.208, 0.003, 0.138, 0.296, 0.251, 0.046, 0.167, 0.033, 0.011, 0.008, 0.01, 0.008, 0.0001, 0.008, 0.0001, 0.004, 0.0001, 9.665, 0.664, 0.152, 2.822, 7.678, 0.189, 1.393, 1.095, 7.816, 1.25, 3.234, 4.738, 2.585, 4.03, 3.549, 1.167, 0.005, 3.003, 6.68, 5.333, 4.153, 1.613, 0.043, 0.017, 0.074, 0.045, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.13, 0.015, 0.01, 0.006, 0.004, 0.003, 0.003, 0.004, 0.002, 0.002, 0.001, 0.002, 0.003, 0.005, 0.001, 0.003, 0.002, 0.002, 0.003, 0.102, 0.002, 0.008, 0.003, 0.003, 0.002, 0.004, 0.002, 0.001, 0.044, 0.005, 0.006, 0.003, 0.016, 0.035, 0.003, 0.002, 0.833, 0.002, 0.001, 0.002, 0.002, 0.01, 0.001, 0.006, 0.001, 0.005, 0.001, 0.001, 0.017, 0.004, 0.012, 0.007, 0.005, 0.763, 0.179, 0.003, 0.015, 0.005, 0.008, 0.007, 0.518, 0.012, 0.028, 0.003, 0.0001, 0.0001, 0.02, 2.358, 0.019, 0.061, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.004, 0.104, 0.037, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.123, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.374, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.123, 0.002, 0.071, 0.0001, 0.001, 0.004, 0.0001, 0.023, 0.08, 0.08, 0.0001, 0.001, 0.255, 0.072, 0.052, 0.006, 0.068, 0.07, 0.044, 0.02, 0.019, 0.023, 0.019, 0.019, 0.021, 0.04, 0.021, 0.006, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.008, 0.004, 0.007, 0.004, 0.005, 0.003, 0.004, 0.003, 0.006, 0.001, 0.002, 0.003, 0.005, 0.004, 0.003, 0.005, 0.0001, 0.003, 0.008, 0.005, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.007, 0.0001, 0.008, 0.0001, 0.001, 0.0001, 0.049, 0.007, 0.017, 0.016, 0.052, 0.008, 0.01, 0.017, 0.038, 0.001, 0.004, 0.024, 0.015, 0.034, 0.035, 0.012, 0.001, 0.033, 0.03, 0.034, 0.015, 0.005, 0.005, 0.002, 0.008, 0.001, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 1.039, 0.443, 1.278, 0.061, 0.0001, 0.273, 0.146, 1.879, 0.535, 0.214, 0.013, 0.729, 0.054, 1.826, 0.0001, 0.253, 0.014, 0.012, 0.0001, 0.042, 0.14, 2.07, 0.133, 0.43, 0.035, 0.004, 0.215, 0.046, 0.503, 0.014, 0.016, 0.269, 0.037, 0.213, 0.023, 0.155, 24.777, 7.162, 0.554, 0.224, 1.23, 0.009, 0.8, 0.117, 0.393, 0.245, 0.995, 0.828, 2.018, 0.001, 0.771, 0.001, 0.001, 0.707, 0.299, 0.18, 1.226, 0.94, 0.0001, 0.0001, 0.133, 0.001, 2.558, 1.303, 0.0001, 0.0001, 0.008, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.261, 0.0001, 0.024, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], +}; +const EXTENSIVE_LANG_FREQS = Object.assign({}, COMMON_LANG_FREQS, { + "aa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.161, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.548, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.29, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.29, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.452, 0.645, 0.645, 2.581, 9.032, 0.0001, 5.161, 3.871, 5.806, 0.0001, 1.935, 2.581, 1.29, 5.161, 2.581, 1.29, 0.0001, 4.516, 0.645, 3.226, 0.645, 0.0001, 1.29, 0.0001, 0.645, 1.29, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.581, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.29, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 1.29, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.871, 0.645, 2.581, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ab": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.925, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.477, 0.003, 0.06, 0.0001, 0.0001, 0.005, 0.0001, 0.013, 0.269, 0.273, 0.001, 0.001, 0.518, 0.306, 0.76, 0.006, 0.291, 0.709, 0.42, 0.294, 0.242, 0.237, 0.242, 0.222, 0.25, 0.32, 0.04, 0.028, 0.008, 0.0001, 0.008, 0.002, 0.0001, 0.004, 0.004, 0.004, 0.006, 0.001, 0.002, 0.001, 0.001, 0.033, 0.012, 0.001, 0.001, 0.002, 0.001, 0.011, 0.003, 0.0001, 0.002, 0.009, 0.002, 0.002, 0.007, 0.006, 0.01, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.679, 0.013, 0.02, 0.028, 0.073, 0.002, 0.006, 0.01, 0.057, 0.001, 0.005, 0.035, 0.039, 0.025, 0.031, 0.027, 0.011, 0.045, 0.036, 0.027, 0.037, 0.009, 0.002, 0.01, 0.027, 0.004, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 3.029, 1.109, 1.569, 1.131, 0.085, 0.805, 0.262, 0.083, 0.992, 0.002, 0.003, 2.495, 0.791, 0.003, 0.006, 0.03, 0.654, 0.059, 0.04, 0.137, 0.332, 0.075, 0.041, 0.012, 0.142, 2.586, 0.087, 1.002, 0.086, 0.047, 0.045, 0.323, 0.073, 0.328, 0.016, 0.067, 0.011, 0.052, 0.054, 0.455, 0.024, 0.199, 0.0001, 0.026, 0.015, 0.539, 0.001, 0.001, 7.771, 0.517, 0.209, 1.034, 0.683, 1.368, 0.238, 0.686, 3.093, 0.042, 0.729, 1.305, 0.754, 1.868, 1.136, 0.676, 0.0001, 0.0001, 0.065, 0.019, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.001, 0.155, 0.0001, 0.005, 0.002, 22.83, 11.878, 3.39, 2.86, 0.019, 0.007, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.386, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ace": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.36, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.198, 0.0001, 0.137, 0.0001, 0.001, 0.007, 0.0001, 0.256, 0.125, 0.125, 0.0001, 0.0001, 1.042, 0.179, 1.302, 0.01, 0.401, 0.568, 0.284, 0.118, 0.113, 0.112, 0.099, 0.093, 0.097, 0.13, 0.041, 0.007, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.777, 0.587, 0.153, 0.133, 0.028, 0.036, 0.256, 0.095, 0.205, 0.159, 0.483, 0.331, 0.444, 0.183, 0.028, 0.481, 0.019, 0.179, 0.473, 0.324, 0.101, 0.026, 0.042, 0.006, 0.021, 0.009, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 11.224, 1.773, 0.851, 1.583, 5.304, 0.086, 3.693, 3.458, 3.728, 0.528, 2.425, 2.037, 2.4, 8.165, 2.618, 1.607, 0.015, 2.485, 1.74, 2.806, 6.018, 0.112, 0.344, 0.01, 1.486, 0.04, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.039, 0.008, 0.005, 0.009, 0.016, 0.007, 0.006, 0.006, 0.01, 0.004, 0.008, 0.003, 0.002, 0.004, 0.012, 0.004, 0.007, 0.003, 0.004, 0.014, 0.002, 0.001, 0.001, 0.002, 0.004, 0.016, 0.001, 0.001, 0.002, 0.002, 0.001, 0.007, 0.007, 0.006, 0.003, 0.008, 0.005, 0.002, 0.001, 0.019, 1.193, 0.401, 0.007, 0.574, 0.003, 0.006, 0.002, 0.006, 0.025, 0.011, 0.006, 0.008, 0.873, 0.004, 0.151, 0.002, 0.005, 0.005, 0.008, 0.007, 0.004, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.025, 3.205, 0.014, 0.012, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.004, 0.001, 0.012, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.061, 0.078, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.011, 0.039, 0.001, 0.001, 0.005, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ady": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.142, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.359, 0.001, 0.089, 0.0001, 0.0001, 0.003, 0.0001, 0.006, 0.111, 0.11, 0.001, 0.001, 0.645, 0.309, 0.862, 0.007, 0.118, 0.279, 0.082, 0.059, 0.052, 0.055, 0.051, 0.045, 0.057, 0.071, 0.053, 0.011, 0.003, 0.003, 0.003, 0.001, 0.0001, 0.008, 0.007, 0.003, 0.003, 0.002, 0.003, 0.0001, 0.002, 1.228, 0.004, 0.001, 0.003, 0.004, 0.002, 0.004, 0.005, 0.0001, 0.001, 0.006, 0.003, 0.002, 0.004, 0.002, 0.008, 0.0001, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.001, 0.0001, 0.05, 0.009, 0.016, 0.02, 0.067, 0.009, 0.011, 0.022, 0.046, 0.001, 0.006, 0.031, 0.02, 0.036, 0.037, 0.013, 0.0001, 0.038, 0.031, 0.043, 0.016, 0.004, 0.008, 0.003, 0.011, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.778, 0.778, 1.192, 2.098, 0.406, 1.886, 0.203, 0.188, 0.585, 0.672, 2.887, 2.927, 0.717, 6.004, 0.019, 0.21, 0.317, 0.122, 0.019, 0.226, 0.145, 0.045, 0.02, 0.041, 0.09, 0.005, 0.262, 0.059, 0.092, 0.079, 0.053, 0.07, 0.076, 0.092, 0.086, 0.055, 0.029, 0.124, 0.039, 0.031, 0.045, 0.011, 0.0001, 0.031, 0.0001, 0.018, 0.005, 0.018, 2.762, 0.645, 0.171, 1.681, 0.855, 1.134, 0.39, 0.89, 1.618, 0.147, 1.755, 1.169, 1.845, 1.192, 0.989, 0.792, 0.0001, 0.0001, 0.094, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.0001, 0.003, 0.004, 0.0001, 0.0001, 20.033, 23.044, 0.001, 0.227, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.229, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "af": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.732, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.494, 0.002, 0.361, 0.0001, 0.001, 0.008, 0.001, 0.297, 0.136, 0.136, 0.002, 0.001, 0.651, 0.269, 0.893, 0.01, 0.25, 0.371, 0.17, 0.095, 0.09, 0.104, 0.09, 0.086, 0.122, 0.213, 0.049, 0.019, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.241, 0.154, 0.103, 0.382, 0.093, 0.072, 0.119, 0.168, 0.14, 0.087, 0.137, 0.088, 0.157, 0.131, 0.103, 0.129, 0.004, 0.104, 0.29, 0.11, 0.03, 0.115, 0.083, 0.006, 0.008, 0.015, 0.002, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 6.202, 1.128, 0.17, 4.12, 13.284, 0.609, 2.484, 1.201, 6.602, 0.17, 2.299, 2.976, 1.671, 6.221, 4.571, 1.147, 0.006, 5.197, 4.908, 4.263, 1.7, 1.691, 1.336, 0.018, 0.832, 0.043, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.182, 0.005, 0.004, 0.003, 0.002, 0.001, 0.001, 0.001, 0.003, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.001, 0.001, 0.024, 0.002, 0.001, 0.001, 0.001, 0.003, 0.118, 0.001, 0.001, 0.017, 0.016, 0.001, 0.001, 0.076, 0.018, 0.001, 0.005, 0.004, 0.002, 0.002, 0.003, 0.003, 0.032, 0.053, 0.119, 0.001, 0.004, 0.001, 0.014, 0.007, 0.003, 0.004, 0.007, 0.002, 0.003, 0.005, 0.001, 0.005, 0.002, 0.003, 0.003, 0.007, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.084, 0.264, 0.004, 0.005, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.003, 0.001, 0.0001, 0.009, 0.004, 0.022, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.181, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ak": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.856, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 17.14, 0.001, 0.181, 0.0001, 0.002, 0.004, 0.001, 0.124, 0.134, 0.137, 0.001, 0.0001, 0.719, 0.119, 1.218, 0.014, 0.179, 0.257, 0.137, 0.052, 0.061, 0.075, 0.065, 0.054, 0.059, 0.197, 0.031, 0.029, 0.002, 0.015, 0.002, 0.018, 0.0001, 0.566, 0.167, 0.173, 0.118, 0.172, 0.085, 0.258, 0.093, 0.098, 0.056, 0.193, 0.111, 0.204, 0.399, 0.102, 0.121, 0.012, 0.083, 0.271, 0.145, 0.084, 0.04, 0.206, 0.011, 0.078, 0.02, 0.025, 0.0001, 0.025, 0.0001, 0.0001, 0.0001, 10.911, 1.752, 0.404, 1.704, 5.791, 1.18, 0.501, 1.542, 4.479, 0.04, 1.975, 0.667, 3.211, 7.434, 5.302, 0.888, 0.03, 2.693, 2.695, 1.838, 2.674, 0.126, 2.695, 0.023, 2.4, 0.077, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.046, 0.01, 0.002, 0.005, 0.002, 0.006, 0.095, 0.003, 0.01, 0.003, 0.006, 0.011, 0.002, 0.017, 0.002, 0.004, 0.052, 0.011, 0.001, 0.002, 1.774, 0.002, 0.002, 0.001, 0.0001, 0.02, 0.0001, 1.749, 0.01, 0.01, 0.0001, 0.0001, 0.151, 0.004, 0.001, 0.002, 0.006, 0.022, 0.001, 0.003, 0.005, 0.01, 0.002, 0.003, 0.002, 0.005, 0.001, 0.003, 0.01, 0.006, 0.005, 0.012, 0.015, 0.552, 0.007, 0.003, 0.008, 0.006, 0.006, 0.392, 0.013, 0.005, 0.007, 0.004, 0.0001, 0.0001, 0.146, 0.054, 0.004, 0.004, 0.139, 0.0001, 0.0001, 3.532, 0.002, 0.008, 0.003, 0.34, 0.547, 0.0001, 0.045, 0.018, 0.0001, 0.0001, 0.018, 0.055, 0.008, 0.002, 0.016, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.048, 0.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "als": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.981, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.805, 0.003, 0.368, 0.0001, 0.0001, 0.09, 0.001, 0.06, 0.177, 0.177, 0.009, 0.001, 0.909, 0.215, 1.001, 0.022, 0.318, 0.46, 0.232, 0.128, 0.122, 0.132, 0.116, 0.119, 0.142, 0.206, 0.063, 0.024, 0.004, 0.003, 0.004, 0.001, 0.0001, 0.315, 0.452, 0.163, 0.512, 0.205, 0.236, 0.319, 0.219, 0.188, 0.156, 0.222, 0.212, 0.32, 0.172, 0.112, 0.199, 0.01, 0.225, 0.653, 0.132, 0.131, 0.173, 0.23, 0.004, 0.019, 0.129, 0.009, 0.0001, 0.009, 0.0001, 0.003, 0.001, 3.964, 1.276, 2.626, 3.453, 8.363, 1.057, 2.308, 3.744, 6.377, 0.069, 0.66, 2.78, 2.213, 4.452, 3.12, 0.516, 0.012, 5.572, 4.629, 4.341, 2.669, 0.935, 0.979, 0.046, 0.315, 0.925, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.124, 0.003, 0.002, 0.002, 0.034, 0.001, 0.001, 0.001, 0.005, 0.003, 0.0001, 0.0001, 0.004, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.023, 0.002, 0.001, 0.01, 0.001, 0.003, 0.02, 0.003, 0.002, 0.048, 0.001, 0.034, 0.042, 0.156, 0.005, 0.005, 0.003, 1.018, 0.003, 0.001, 0.003, 0.354, 0.039, 0.002, 0.022, 0.079, 0.004, 0.001, 0.002, 0.004, 0.003, 0.015, 0.003, 0.029, 0.017, 0.333, 0.001, 0.002, 0.045, 0.004, 0.015, 0.5, 0.004, 0.001, 0.002, 0.0001, 0.0001, 0.108, 2.635, 0.006, 0.005, 0.0001, 0.005, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.011, 0.005, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.12, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "am": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.067, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.441, 0.005, 0.08, 0.001, 0.0001, 0.003, 0.0001, 0.013, 0.12, 0.121, 0.002, 0.001, 0.021, 0.111, 0.25, 0.041, 0.102, 0.167, 0.089, 0.049, 0.044, 0.048, 0.044, 0.043, 0.057, 0.081, 0.018, 0.001, 0.048, 0.019, 0.048, 0.008, 0.0001, 0.009, 0.005, 0.007, 0.005, 0.005, 0.004, 0.003, 0.003, 0.004, 0.004, 0.002, 0.003, 0.006, 0.003, 0.002, 0.004, 0.001, 0.003, 0.007, 0.005, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.017, 0.0001, 0.02, 0.0001, 0.007, 0.0001, 0.059, 0.06, 0.021, 0.018, 0.066, 0.009, 0.014, 0.02, 0.05, 0.001, 0.005, 0.029, 0.021, 0.042, 0.045, 0.014, 0.001, 0.09, 0.032, 0.04, 0.026, 0.005, 0.007, 0.003, 0.012, 0.002, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.402, 0.178, 0.052, 0.194, 0.053, 0.478, 0.259, 0.003, 10.51, 5.557, 5.996, 6.414, 2.305, 3.741, 0.258, 0.015, 0.706, 0.091, 0.071, 0.613, 0.064, 1.598, 0.107, 0.008, 0.907, 0.126, 0.312, 0.688, 0.12, 0.989, 0.129, 0.009, 2.006, 0.213, 0.679, 0.599, 0.206, 1.204, 0.134, 0.012, 1.72, 0.213, 0.231, 1.059, 0.087, 1.793, 0.284, 0.013, 1.151, 0.255, 0.312, 0.726, 0.115, 2.127, 0.177, 0.025, 0.19, 0.059, 0.032, 0.208, 0.015, 0.466, 0.016, 0.003, 0.0001, 0.0001, 0.096, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.005, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.017, 0.046, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 29.467, 0.047, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.001, 0.0001, 0.017, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "an": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.253, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.49, 0.005, 0.725, 0.0001, 0.0001, 0.005, 0.001, 0.998, 0.246, 0.246, 0.002, 0.002, 1.083, 0.164, 0.685, 0.057, 0.291, 0.382, 0.213, 0.125, 0.12, 0.124, 0.115, 0.119, 0.131, 0.221, 0.057, 0.029, 0.007, 0.01, 0.006, 0.001, 0.0001, 0.411, 0.169, 0.298, 0.091, 0.216, 0.095, 0.1, 0.059, 0.154, 0.037, 0.024, 0.177, 0.199, 0.072, 0.146, 0.19, 0.011, 0.122, 0.227, 0.128, 0.065, 0.101, 0.021, 0.037, 0.032, 0.028, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 9.483, 1.074, 3.3, 3.436, 7.765, 0.618, 0.822, 0.72, 5.365, 0.027, 0.17, 3.124, 1.916, 5.869, 6.23, 1.654, 0.435, 4.741, 4.813, 3.981, 2.96, 0.573, 0.028, 0.256, 1.248, 0.309, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.014, 0.007, 0.003, 0.003, 0.002, 0.001, 0.001, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.007, 0.002, 0.001, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.002, 0.028, 0.174, 0.002, 0.002, 0.003, 0.001, 0.001, 0.008, 0.012, 0.227, 0.002, 0.014, 0.002, 0.209, 0.001, 0.002, 0.004, 0.013, 0.086, 0.54, 0.002, 0.002, 0.003, 0.002, 0.004, 0.002, 0.027, 0.014, 0.019, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.127, 1.249, 0.007, 0.007, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.009, 0.005, 0.014, 0.005, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.002, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.013, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ang": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.542, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.629, 0.001, 0.406, 0.001, 0.001, 0.005, 0.001, 0.041, 0.166, 0.166, 0.001, 0.001, 0.772, 0.085, 0.973, 0.007, 0.229, 0.292, 0.152, 0.081, 0.082, 0.095, 0.083, 0.089, 0.101, 0.139, 0.058, 0.032, 0.011, 0.001, 0.011, 0.001, 0.0001, 0.204, 0.193, 0.317, 0.089, 0.179, 0.148, 0.229, 0.279, 0.189, 0.034, 0.031, 0.128, 0.195, 0.168, 0.087, 0.103, 0.007, 0.125, 0.419, 0.122, 0.043, 0.034, 0.145, 0.006, 0.012, 0.007, 0.02, 0.0001, 0.02, 0.0001, 0.0001, 0.0001, 5.666, 0.997, 2.318, 3.22, 8.139, 1.491, 2.061, 1.574, 3.89, 0.022, 0.109, 2.731, 2.332, 6.4, 3.389, 0.62, 0.014, 4.435, 4.532, 3.015, 1.701, 0.127, 1.341, 0.09, 0.658, 0.04, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.032, 0.62, 0.006, 0.006, 0.004, 0.003, 0.052, 0.002, 0.001, 0.001, 0.002, 0.033, 0.008, 0.478, 0.002, 0.002, 0.01, 0.003, 0.05, 1.069, 0.004, 0.001, 0.004, 0.002, 0.003, 0.003, 0.011, 0.012, 0.009, 0.068, 0.141, 0.003, 0.009, 0.037, 0.013, 0.751, 0.006, 0.002, 1.085, 0.003, 0.002, 0.01, 0.039, 0.996, 0.002, 0.008, 0.002, 0.002, 0.371, 0.007, 0.005, 0.069, 0.002, 0.003, 0.002, 0.008, 0.006, 0.003, 0.005, 0.004, 0.005, 0.004, 2.003, 0.078, 0.0001, 0.0001, 0.009, 3.7, 2.566, 0.742, 0.075, 0.766, 0.127, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.012, 0.006, 0.017, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.006, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.024, 0.022, 0.003, 0.001, 0.003, 0.002, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "arc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.038, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.39, 0.001, 0.055, 0.0001, 0.0001, 0.007, 0.0001, 0.005, 0.294, 0.294, 0.0001, 0.0001, 0.039, 0.041, 0.295, 0.017, 0.207, 0.161, 0.078, 0.046, 0.044, 0.053, 0.042, 0.044, 0.043, 0.091, 0.189, 0.006, 0.003, 0.004, 0.003, 0.0001, 0.0001, 0.01, 0.01, 0.013, 0.007, 0.004, 0.004, 0.006, 0.005, 0.007, 0.003, 0.005, 0.008, 0.011, 0.008, 0.004, 0.008, 0.001, 0.007, 0.013, 0.004, 0.003, 0.005, 0.004, 0.001, 0.001, 0.002, 0.005, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.107, 0.013, 0.023, 0.039, 0.088, 0.011, 0.022, 0.025, 0.081, 0.003, 0.021, 0.05, 0.023, 0.07, 0.066, 0.018, 0.002, 0.062, 0.042, 0.051, 0.032, 0.013, 0.011, 0.006, 0.012, 0.006, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.359, 0.027, 0.139, 0.022, 0.095, 0.021, 0.095, 0.051, 0.776, 0.005, 0.029, 0.002, 0.032, 0.003, 0.011, 0.005, 6.959, 0.008, 1.918, 0.561, 0.013, 2.47, 0.003, 1.261, 3.75, 0.282, 0.787, 0.504, 0.018, 4.683, 0.009, 0.786, 1.796, 2.249, 2.761, 0.874, 0.009, 1.007, 0.747, 0.053, 0.199, 0.858, 2.538, 1.15, 2.879, 0.016, 0.009, 0.021, 0.023, 0.056, 0.023, 0.019, 0.01, 0.046, 0.007, 0.011, 0.024, 0.035, 0.015, 0.012, 0.048, 0.023, 0.008, 0.047, 0.0001, 0.0001, 0.004, 0.019, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.832, 0.001, 0.126, 0.053, 0.042, 0.017, 0.001, 0.0001, 0.0001, 0.009, 0.024, 0.108, 0.212, 0.141, 0.001, 0.004, 41.501, 0.031, 0.0001, 0.0001, 0.002, 0.019, 0.018, 0.0001, 0.001, 0.004, 0.004, 0.0001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "arz": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.02, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.739, 0.003, 0.126, 0.0001, 0.0001, 0.004, 0.001, 0.003, 0.118, 0.124, 0.002, 0.001, 0.064, 0.045, 0.405, 0.01, 0.141, 0.269, 0.129, 0.067, 0.063, 0.072, 0.064, 0.065, 0.08, 0.165, 0.039, 0.002, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.012, 0.009, 0.011, 0.008, 0.005, 0.005, 0.005, 0.006, 0.006, 0.005, 0.004, 0.009, 0.011, 0.005, 0.003, 0.007, 0.0001, 0.006, 0.013, 0.009, 0.001, 0.004, 0.004, 0.001, 0.001, 0.001, 0.006, 0.001, 0.006, 0.0001, 0.002, 0.0001, 0.091, 0.01, 0.025, 0.026, 0.093, 0.01, 0.015, 0.024, 0.072, 0.002, 0.01, 0.045, 0.023, 0.064, 0.06, 0.013, 0.001, 0.06, 0.046, 0.047, 0.027, 0.009, 0.007, 0.004, 0.017, 0.005, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.111, 1.136, 0.763, 1.043, 4.458, 2.752, 2.413, 1.721, 2.708, 1.077, 3.156, 0.021, 0.238, 0.002, 0.017, 0.028, 0.008, 0.018, 0.006, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.003, 0.003, 0.004, 0.0001, 0.003, 0.019, 0.06, 0.018, 0.274, 0.041, 0.116, 0.08, 6.51, 1.771, 0.79, 1.749, 0.151, 0.593, 0.743, 0.294, 1.313, 0.079, 2.202, 0.292, 1.274, 0.493, 0.453, 0.187, 0.361, 0.078, 1.267, 0.19, 0.005, 0.002, 0.002, 0.011, 0.002, 0.0001, 0.0001, 0.025, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.004, 0.01, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.004, 21.565, 21.383, 0.022, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.029, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "as": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.296, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.811, 0.001, 0.086, 0.0001, 0.0001, 0.005, 0.0001, 0.083, 0.075, 0.077, 0.0001, 0.001, 0.203, 0.086, 0.044, 0.006, 0.008, 0.009, 0.006, 0.004, 0.003, 0.003, 0.002, 0.002, 0.003, 0.004, 0.022, 0.007, 0.002, 0.003, 0.002, 0.001, 0.0001, 0.015, 0.009, 0.013, 0.007, 0.006, 0.005, 0.005, 0.006, 0.011, 0.003, 0.003, 0.005, 0.01, 0.007, 0.004, 0.011, 0.001, 0.008, 0.013, 0.013, 0.003, 0.002, 0.004, 0.0001, 0.001, 0.001, 0.01, 0.0001, 0.01, 0.0001, 0.001, 0.0001, 0.213, 0.031, 0.074, 0.083, 0.255, 0.044, 0.045, 0.095, 0.18, 0.004, 0.017, 0.099, 0.058, 0.166, 0.164, 0.046, 0.002, 0.151, 0.14, 0.179, 0.063, 0.023, 0.027, 0.005, 0.036, 0.003, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.537, 0.769, 0.261, 0.102, 0.001, 0.242, 0.382, 1.586, 0.215, 0.133, 0.002, 0.429, 0.033, 1.928, 0.026, 0.213, 0.004, 0.0001, 0.0001, 0.14, 0.003, 1.299, 0.21, 0.401, 0.056, 0.073, 0.394, 0.328, 0.382, 0.006, 0.051, 0.353, 0.081, 0.128, 0.02, 0.231, 1.75, 0.525, 21.552, 9.182, 1.32, 0.031, 0.846, 0.112, 0.982, 0.29, 0.858, 1.027, 2.855, 0.297, 0.931, 0.0001, 0.0001, 0.0001, 0.293, 0.318, 0.674, 0.559, 0.001, 0.0001, 0.584, 0.0001, 2.717, 1.766, 0.0001, 0.0001, 0.009, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.161, 0.0001, 0.072, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ast": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.724, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.007, 0.002, 0.424, 0.002, 0.001, 0.01, 0.003, 0.548, 0.156, 0.156, 0.002, 0.003, 1.046, 0.096, 0.743, 0.015, 0.245, 0.288, 0.158, 0.086, 0.078, 0.093, 0.076, 0.077, 0.093, 0.166, 0.056, 0.032, 0.002, 0.005, 0.002, 0.002, 0.0001, 0.218, 0.121, 0.236, 0.117, 0.257, 0.089, 0.088, 0.078, 0.115, 0.051, 0.038, 0.23, 0.167, 0.117, 0.051, 0.161, 0.007, 0.094, 0.198, 0.134, 0.043, 0.06, 0.041, 0.061, 0.037, 0.011, 0.014, 0.0001, 0.014, 0.0001, 0.001, 0.0001, 8.074, 0.835, 3.151, 3.345, 9.578, 0.701, 0.803, 0.452, 5.046, 0.025, 0.11, 4.637, 2.087, 5.542, 5.253, 1.877, 0.488, 4.828, 5.384, 3.477, 3.909, 0.672, 0.055, 0.4, 0.967, 0.259, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.04, 0.01, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.003, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.01, 0.01, 0.001, 0.0001, 0.001, 0.002, 0.009, 0.001, 0.001, 0.005, 0.006, 0.0001, 0.001, 0.026, 0.531, 0.001, 0.001, 0.002, 0.001, 0.002, 0.002, 0.002, 0.291, 0.001, 0.019, 0.001, 0.46, 0.001, 0.001, 0.005, 0.157, 0.004, 0.608, 0.002, 0.002, 0.003, 0.002, 0.004, 0.002, 0.119, 0.021, 0.027, 0.002, 0.001, 0.003, 0.0001, 0.0001, 0.073, 2.207, 0.003, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.012, 0.005, 0.007, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.039, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "atj": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.34, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.835, 0.0001, 0.034, 0.0001, 0.0001, 0.001, 0.0001, 0.005, 0.045, 0.047, 0.0001, 0.0001, 0.548, 0.045, 1.11, 0.006, 0.039, 0.075, 0.033, 0.013, 0.017, 0.015, 0.02, 0.018, 0.017, 0.061, 0.024, 0.003, 0.015, 0.0001, 0.015, 0.002, 0.0001, 0.175, 0.012, 0.062, 0.025, 0.193, 0.022, 0.01, 0.006, 0.035, 0.021, 0.212, 0.019, 0.332, 0.208, 0.141, 0.099, 0.007, 0.017, 0.034, 0.12, 0.001, 0.003, 0.089, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 11.805, 0.044, 6.264, 0.083, 5.028, 0.008, 0.026, 0.952, 15.443, 0.004, 9.886, 0.134, 2.846, 5.167, 5.337, 2.131, 0.022, 2.079, 2.27, 7.277, 0.131, 0.025, 4.581, 0.005, 0.015, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.009, 0.046, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.015, 0.069, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "av": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.031, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.23, 0.001, 0.083, 0.0001, 0.0001, 0.007, 0.001, 0.001, 0.166, 0.166, 0.001, 0.001, 0.458, 0.25, 0.562, 0.01, 0.133, 0.234, 0.149, 0.084, 0.058, 0.065, 0.053, 0.053, 0.06, 0.094, 0.055, 0.017, 0.001, 0.003, 0.001, 0.003, 0.0001, 0.011, 0.006, 0.01, 0.003, 0.003, 0.003, 0.003, 0.002, 0.777, 0.001, 0.002, 0.002, 0.006, 0.003, 0.003, 0.002, 0.0001, 0.002, 0.007, 0.008, 0.003, 0.006, 0.001, 0.011, 0.001, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 0.009, 0.0001, 0.075, 0.008, 0.02, 0.025, 0.067, 0.007, 0.015, 0.018, 0.067, 0.001, 0.008, 0.038, 0.014, 0.043, 0.038, 0.019, 0.001, 0.041, 0.043, 0.036, 0.031, 0.01, 0.006, 0.003, 0.01, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.671, 1.227, 0.995, 2.675, 0.059, 0.905, 0.851, 0.335, 0.128, 0.084, 1.771, 0.03, 0.884, 0.039, 0.044, 0.818, 0.134, 0.075, 0.027, 0.273, 0.227, 0.015, 0.029, 0.016, 0.039, 0.006, 0.125, 0.043, 0.127, 0.032, 0.014, 0.032, 0.185, 0.089, 0.062, 0.016, 0.021, 0.082, 0.047, 0.033, 0.042, 0.006, 0.002, 0.039, 0.002, 0.019, 0.005, 0.013, 7.089, 1.927, 0.825, 1.964, 1.317, 1.929, 0.263, 0.636, 2.852, 0.187, 1.471, 3.734, 0.878, 1.983, 1.647, 0.208, 0.0001, 0.0001, 0.195, 0.006, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.022, 0.0001, 0.001, 0.0001, 30.778, 12.343, 0.0001, 0.534, 0.0001, 0.002, 0.0001, 0.001, 0.025, 0.022, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.177, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ay": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.588, 0.005, 0.247, 0.0001, 0.0001, 0.0001, 0.027, 1.72, 0.603, 0.602, 0.046, 0.001, 1.21, 0.158, 1.031, 0.021, 0.387, 0.817, 0.515, 0.316, 0.306, 0.36, 0.273, 0.279, 0.341, 0.428, 0.504, 0.129, 0.064, 0.005, 0.064, 0.147, 0.0001, 0.442, 0.126, 0.339, 0.185, 0.072, 0.071, 0.077, 0.1, 0.109, 0.302, 0.254, 0.268, 0.282, 0.145, 0.064, 0.43, 0.127, 0.121, 0.288, 0.2, 0.25, 0.05, 0.191, 0.012, 0.11, 0.013, 0.007, 0.0001, 0.008, 0.0001, 0.002, 0.004, 14.491, 0.243, 1.49, 0.745, 1.57, 0.085, 0.27, 2.104, 6.268, 1.613, 3.058, 2.342, 2.397, 3.14, 1.316, 1.65, 1.821, 3.874, 4.07, 2.906, 5.224, 0.153, 1.248, 0.859, 2.145, 0.119, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.211, 0.009, 0.003, 0.004, 0.002, 0.001, 0.002, 0.002, 0.003, 0.002, 0.001, 0.002, 0.002, 0.003, 0.002, 0.002, 0.004, 0.008, 0.001, 0.016, 0.006, 0.002, 0.001, 0.001, 0.005, 0.126, 0.002, 0.002, 0.008, 0.019, 0.001, 0.001, 0.061, 0.068, 0.001, 0.003, 0.22, 0.002, 0.002, 0.004, 0.004, 0.062, 0.002, 0.003, 0.001, 0.11, 0.003, 0.049, 0.044, 0.259, 0.029, 0.076, 0.026, 0.004, 0.004, 0.007, 0.009, 0.003, 0.038, 0.01, 0.012, 0.003, 0.005, 0.006, 0.0001, 0.0001, 0.133, 0.88, 0.003, 0.004, 0.0001, 0.001, 0.0001, 0.002, 0.001, 0.003, 0.002, 0.0001, 0.006, 0.002, 0.031, 0.01, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.004, 0.004, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.01, 0.003, 0.207, 0.001, 0.004, 0.008, 0.005, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "az": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.803, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.785, 0.003, 0.222, 0.0001, 0.001, 0.009, 0.001, 0.007, 0.139, 0.141, 0.001, 0.002, 0.64, 0.404, 0.91, 0.014, 0.244, 0.339, 0.188, 0.096, 0.09, 0.102, 0.087, 0.087, 0.102, 0.202, 0.038, 0.019, 0.004, 0.002, 0.004, 0.004, 0.0001, 0.276, 0.242, 0.068, 0.094, 0.057, 0.061, 0.057, 0.095, 0.062, 0.008, 0.127, 0.055, 0.202, 0.081, 0.086, 0.077, 0.107, 0.098, 0.172, 0.115, 0.037, 0.055, 0.005, 0.062, 0.066, 0.023, 0.006, 0.0001, 0.006, 0.0001, 0.004, 0.001, 7.007, 1.378, 0.673, 3.497, 1.722, 0.535, 0.389, 0.748, 6.853, 0.041, 1.544, 4.525, 2.336, 5.203, 1.602, 0.396, 1.07, 4.974, 2.444, 2.338, 1.812, 1.06, 0.008, 0.478, 1.947, 0.87, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.147, 0.01, 0.009, 0.005, 0.005, 0.009, 0.003, 0.033, 0.002, 0.001, 0.001, 0.003, 0.002, 0.001, 0.002, 0.082, 0.004, 0.001, 0.002, 0.028, 0.04, 0.001, 0.012, 0.001, 0.002, 6.259, 0.001, 0.001, 0.046, 0.034, 0.075, 1.454, 0.026, 0.003, 0.003, 0.001, 0.001, 0.001, 0.001, 0.485, 0.001, 0.001, 0.001, 0.011, 0.002, 0.016, 0.001, 0.001, 0.187, 2.533, 0.009, 0.004, 0.005, 0.028, 0.457, 0.003, 0.014, 0.003, 0.01, 0.017, 1.158, 0.011, 0.03, 0.004, 0.0001, 0.0001, 0.067, 2.145, 2.985, 1.196, 0.079, 0.0001, 0.0001, 6.24, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.207, 0.052, 0.0001, 0.018, 0.0001, 0.0001, 0.0001, 0.001, 0.008, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.14, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "azb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.225, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.112, 0.002, 0.032, 0.0001, 0.0001, 0.003, 0.0001, 0.002, 0.275, 0.275, 0.002, 0.001, 0.028, 0.165, 0.744, 0.053, 0.037, 0.078, 0.041, 0.038, 0.027, 0.033, 0.024, 0.023, 0.03, 0.03, 0.059, 0.003, 0.004, 0.001, 0.003, 0.0001, 0.0001, 0.005, 0.004, 0.007, 0.004, 0.002, 0.002, 0.002, 0.003, 0.008, 0.002, 0.002, 0.004, 0.004, 0.003, 0.001, 0.007, 0.001, 0.004, 0.011, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.022, 0.0001, 0.096, 0.009, 0.017, 0.038, 0.09, 0.012, 0.02, 0.043, 0.1, 0.0001, 0.026, 0.053, 0.017, 0.052, 0.064, 0.04, 0.001, 0.055, 0.055, 0.106, 0.015, 0.003, 0.052, 0.004, 0.018, 0.009, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.77, 0.455, 0.528, 0.028, 2.648, 1.417, 3.922, 1.536, 3.205, 0.004, 0.23, 0.004, 7.975, 0.001, 0.011, 0.01, 0.002, 0.06, 0.27, 0.013, 0.004, 0.001, 0.0001, 0.0001, 0.033, 0.002, 0.0001, 0.023, 0.001, 0.001, 0.0001, 0.002, 0.02, 0.007, 0.378, 0.004, 0.281, 0.002, 0.413, 5.027, 1.244, 0.85, 1.199, 0.132, 0.444, 0.158, 0.386, 2.668, 0.253, 3.47, 0.613, 1.73, 0.767, 0.17, 0.092, 0.269, 0.09, 0.326, 0.153, 0.08, 0.001, 0.001, 0.271, 0.002, 0.0001, 0.0001, 0.181, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 18.661, 14.13, 1.511, 8.604, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.0001, 0.763, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ba": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.692, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.933, 0.002, 0.044, 0.0001, 0.0001, 0.005, 0.0001, 0.001, 0.147, 0.147, 0.0001, 0.004, 0.482, 0.143, 0.604, 0.015, 0.158, 0.244, 0.135, 0.077, 0.08, 0.076, 0.061, 0.06, 0.081, 0.125, 0.052, 0.011, 0.008, 0.003, 0.008, 0.001, 0.0001, 0.003, 0.003, 0.006, 0.002, 0.002, 0.001, 0.002, 0.002, 0.025, 0.001, 0.002, 0.002, 0.003, 0.002, 0.001, 0.002, 0.0001, 0.001, 0.004, 0.005, 0.004, 0.007, 0.001, 0.012, 0.0001, 0.001, 0.006, 0.0001, 0.006, 0.0001, 0.002, 0.0001, 0.021, 0.003, 0.012, 0.011, 0.026, 0.004, 0.004, 0.006, 0.021, 0.001, 0.003, 0.02, 0.007, 0.023, 0.02, 0.005, 0.0001, 0.016, 0.01, 0.014, 0.014, 0.002, 0.003, 0.001, 0.009, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.739, 1.424, 2.096, 1.348, 0.183, 0.244, 0.115, 0.088, 0.621, 0.006, 0.016, 3.259, 0.202, 0.093, 0.068, 0.404, 0.112, 0.175, 0.076, 1.0, 0.273, 0.018, 0.005, 0.012, 0.081, 3.093, 0.13, 0.026, 0.084, 0.041, 0.082, 0.063, 0.299, 0.879, 0.098, 0.434, 0.038, 0.036, 0.005, 0.017, 0.043, 0.504, 0.0001, 0.196, 0.001, 0.016, 0.036, 0.445, 4.844, 0.952, 0.303, 0.533, 0.952, 2.488, 0.102, 0.15, 1.49, 1.18, 1.231, 3.558, 1.237, 2.847, 1.277, 0.365, 0.0001, 0.0001, 0.244, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.004, 0.0001, 0.002, 0.001, 24.156, 12.667, 4.154, 3.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.235, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bar": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.604, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.871, 0.004, 0.418, 0.0001, 0.0001, 0.008, 0.002, 0.216, 0.21, 0.21, 0.009, 0.001, 0.803, 0.202, 1.146, 0.023, 0.266, 0.394, 0.199, 0.121, 0.109, 0.119, 0.109, 0.117, 0.138, 0.187, 0.117, 0.02, 0.004, 0.005, 0.004, 0.003, 0.0001, 0.352, 0.447, 0.201, 0.532, 0.247, 0.245, 0.332, 0.228, 0.204, 0.156, 0.293, 0.235, 0.338, 0.204, 0.224, 0.214, 0.034, 0.205, 0.697, 0.181, 0.119, 0.18, 0.276, 0.005, 0.01, 0.114, 0.021, 0.0001, 0.021, 0.0001, 0.003, 0.003, 8.177, 1.169, 1.993, 4.065, 6.625, 1.095, 2.102, 3.003, 6.12, 0.162, 0.941, 2.0, 2.327, 6.606, 4.578, 0.55, 0.014, 3.249, 4.677, 4.042, 3.018, 0.854, 1.171, 0.071, 0.239, 0.864, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.102, 0.003, 0.003, 0.002, 0.004, 0.004, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.014, 0.001, 0.001, 0.016, 0.001, 0.002, 0.009, 0.001, 0.001, 0.039, 0.001, 0.036, 0.116, 0.061, 0.007, 0.003, 0.001, 0.274, 0.073, 0.002, 0.002, 0.004, 0.027, 0.002, 0.002, 0.002, 0.004, 0.001, 0.001, 0.004, 0.002, 0.01, 0.016, 0.006, 0.001, 0.154, 0.002, 0.005, 0.001, 0.002, 0.002, 0.176, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.07, 0.891, 0.007, 0.006, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.007, 0.004, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.103, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bcl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.379, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.071, 0.002, 0.217, 0.001, 0.003, 0.005, 0.002, 0.116, 0.161, 0.16, 0.0001, 0.001, 0.914, 0.25, 0.911, 0.022, 0.337, 0.439, 0.274, 0.132, 0.116, 0.128, 0.121, 0.133, 0.144, 0.229, 0.055, 0.02, 0.017, 0.001, 0.017, 0.022, 0.0001, 0.585, 0.233, 0.246, 0.128, 0.11, 0.148, 0.111, 0.118, 0.238, 0.077, 0.175, 0.149, 0.27, 0.198, 0.07, 0.296, 0.013, 0.12, 0.508, 0.14, 0.057, 0.048, 0.04, 0.004, 0.02, 0.015, 0.025, 0.0001, 0.025, 0.0001, 0.0001, 0.0001, 15.454, 1.486, 0.494, 1.897, 2.968, 0.126, 4.169, 0.861, 6.432, 0.033, 2.688, 2.392, 2.068, 10.392, 5.039, 1.872, 0.022, 3.21, 4.66, 2.796, 1.875, 0.174, 0.643, 0.021, 1.752, 0.121, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.039, 0.006, 0.003, 0.003, 0.005, 0.004, 0.002, 0.003, 0.009, 0.002, 0.004, 0.002, 0.003, 0.004, 0.003, 0.002, 0.007, 0.003, 0.002, 0.009, 0.004, 0.002, 0.001, 0.002, 0.002, 0.008, 0.004, 0.003, 0.013, 0.011, 0.003, 0.001, 0.027, 0.035, 0.013, 0.004, 0.005, 0.003, 0.003, 0.006, 0.004, 0.006, 0.004, 0.003, 0.007, 0.019, 0.005, 0.003, 0.005, 0.018, 0.01, 0.022, 0.014, 0.003, 0.004, 0.003, 0.01, 0.004, 0.006, 0.004, 0.005, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.019, 0.136, 0.005, 0.006, 0.0001, 0.0001, 0.0001, 0.011, 0.004, 0.01, 0.002, 0.0001, 0.006, 0.003, 0.016, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.017, 0.012, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.007, 0.034, 0.001, 0.008, 0.01, 0.006, 0.004, 0.002, 0.003, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "be": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.607, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.35, 0.001, 0.055, 0.0001, 0.0001, 0.006, 0.0001, 0.05, 0.155, 0.156, 0.001, 0.002, 0.628, 0.121, 0.612, 0.009, 0.188, 0.295, 0.148, 0.088, 0.085, 0.087, 0.076, 0.074, 0.089, 0.156, 0.032, 0.017, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.009, 0.006, 0.026, 0.004, 0.005, 0.003, 0.019, 0.003, 0.047, 0.001, 0.002, 0.004, 0.009, 0.01, 0.004, 0.01, 0.0001, 0.005, 0.013, 0.005, 0.003, 0.013, 0.004, 0.018, 0.001, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.003, 0.0001, 0.046, 0.006, 0.014, 0.013, 0.042, 0.007, 0.007, 0.01, 0.04, 0.001, 0.006, 0.023, 0.014, 0.029, 0.035, 0.009, 0.001, 0.032, 0.024, 0.024, 0.019, 0.004, 0.003, 0.002, 0.006, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.314, 1.922, 1.481, 1.13, 0.14, 0.481, 1.007, 0.569, 0.351, 0.001, 0.001, 1.93, 0.479, 0.541, 0.221, 1.357, 0.128, 0.261, 0.085, 0.08, 0.203, 0.012, 2.438, 0.059, 0.001, 0.01, 0.103, 0.048, 0.097, 0.076, 0.995, 0.141, 0.181, 0.137, 0.046, 0.12, 0.029, 0.02, 0.016, 0.019, 0.023, 0.001, 0.0001, 0.081, 0.0001, 0.017, 0.007, 0.023, 7.12, 0.583, 1.325, 0.884, 1.382, 1.613, 0.241, 1.022, 0.011, 0.528, 1.726, 1.757, 1.251, 2.924, 1.397, 1.062, 0.0001, 0.0001, 0.283, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.021, 0.0001, 0.002, 0.001, 26.294, 17.28, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.156, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.941, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.272, 0.0001, 0.067, 0.0001, 0.001, 0.014, 0.0001, 0.006, 0.074, 0.074, 0.0001, 0.001, 0.205, 0.047, 0.036, 0.005, 0.139, 0.215, 0.134, 0.072, 0.07, 0.074, 0.065, 0.069, 0.075, 0.087, 0.017, 0.007, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.006, 0.004, 0.005, 0.002, 0.003, 0.002, 0.004, 0.002, 0.007, 0.001, 0.002, 0.003, 0.003, 0.003, 0.002, 0.004, 0.0001, 0.002, 0.006, 0.006, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.009, 0.0001, 0.1, 0.014, 0.029, 0.038, 0.115, 0.019, 0.024, 0.049, 0.081, 0.001, 0.007, 0.043, 0.023, 0.079, 0.071, 0.019, 0.001, 0.072, 0.065, 0.081, 0.029, 0.011, 0.014, 0.002, 0.014, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.902, 0.534, 1.035, 0.031, 0.0001, 0.22, 0.29, 2.243, 0.258, 0.137, 0.021, 0.553, 0.066, 1.318, 0.0001, 0.336, 0.009, 0.009, 0.0001, 0.03, 0.023, 1.891, 0.248, 0.639, 0.037, 0.011, 0.202, 0.05, 0.683, 0.024, 0.014, 0.375, 0.074, 0.252, 0.031, 0.13, 24.792, 6.19, 0.487, 0.175, 1.097, 0.001, 0.677, 0.098, 0.808, 0.311, 0.975, 0.521, 2.028, 0.0001, 1.424, 0.0001, 0.0001, 0.605, 0.237, 0.107, 1.177, 0.742, 0.0001, 0.0001, 0.117, 0.003, 3.031, 1.138, 0.0001, 0.0001, 0.016, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 29.692, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.859, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.276, 0.003, 0.256, 0.0001, 0.0001, 0.003, 0.003, 0.016, 0.486, 0.484, 0.001, 0.0001, 0.638, 0.156, 1.372, 0.022, 0.455, 0.969, 0.456, 0.237, 0.231, 0.247, 0.248, 0.25, 0.297, 0.612, 0.044, 0.019, 0.005, 0.0001, 0.004, 0.004, 0.0001, 0.449, 0.264, 0.227, 0.165, 0.234, 0.192, 0.164, 0.234, 0.179, 0.456, 0.316, 0.231, 0.458, 0.197, 0.135, 0.315, 0.005, 0.168, 0.606, 0.235, 0.049, 0.123, 0.109, 0.008, 0.231, 0.017, 0.005, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 8.019, 2.445, 0.575, 1.178, 6.318, 0.449, 2.782, 1.275, 5.992, 0.203, 1.688, 4.658, 3.419, 6.494, 6.015, 1.447, 0.023, 2.565, 2.973, 3.583, 1.992, 0.459, 0.92, 0.044, 0.557, 0.136, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.108, 0.019, 0.014, 0.005, 0.005, 0.004, 0.006, 0.01, 0.005, 0.008, 0.002, 0.002, 0.012, 0.031, 0.002, 0.001, 0.002, 0.004, 0.003, 0.089, 0.007, 0.003, 0.003, 0.004, 0.004, 0.002, 0.001, 0.001, 0.007, 0.004, 0.002, 0.004, 0.052, 0.019, 0.003, 0.005, 0.023, 0.009, 0.014, 0.014, 0.008, 0.023, 0.003, 0.01, 0.005, 0.015, 0.003, 0.004, 0.019, 0.013, 0.011, 0.022, 0.006, 0.01, 0.007, 0.004, 0.018, 0.01, 0.009, 0.009, 0.011, 0.009, 0.011, 0.009, 0.0001, 0.0001, 0.048, 0.113, 0.02, 0.046, 0.0001, 0.002, 0.0001, 0.005, 0.001, 0.002, 0.0001, 0.001, 0.032, 0.011, 0.078, 0.027, 0.001, 0.0001, 0.001, 0.018, 0.002, 0.0001, 0.017, 0.009, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.037, 0.005, 0.097, 0.0001, 0.0001, 0.007, 0.003, 0.001, 0.003, 0.001, 0.002, 0.001, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bjn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.274, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.352, 0.002, 0.406, 0.0001, 0.001, 0.013, 0.001, 0.109, 0.199, 0.198, 0.002, 0.001, 0.988, 0.406, 0.819, 0.036, 0.185, 0.196, 0.136, 0.076, 0.062, 0.071, 0.054, 0.058, 0.057, 0.091, 0.102, 0.025, 0.002, 0.003, 0.002, 0.005, 0.0001, 0.244, 0.391, 0.098, 0.173, 0.034, 0.031, 0.106, 0.136, 0.207, 0.121, 0.411, 0.116, 0.312, 0.12, 0.035, 0.341, 0.003, 0.133, 0.409, 0.258, 0.061, 0.026, 0.09, 0.002, 0.038, 0.007, 0.012, 0.0001, 0.012, 0.0001, 0.0001, 0.0001, 19.717, 2.113, 0.418, 2.814, 2.089, 0.126, 3.097, 2.135, 6.446, 0.654, 2.733, 2.879, 2.871, 8.542, 1.048, 1.844, 0.007, 3.384, 2.985, 3.613, 4.514, 0.083, 0.972, 0.009, 1.107, 0.035, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.03, 0.008, 0.005, 0.007, 0.006, 0.006, 0.006, 0.004, 0.006, 0.004, 0.008, 0.003, 0.003, 0.007, 0.001, 0.001, 0.002, 0.002, 0.002, 0.008, 0.003, 0.002, 0.002, 0.004, 0.002, 0.014, 0.001, 0.002, 0.005, 0.005, 0.002, 0.002, 0.012, 0.002, 0.002, 0.004, 0.012, 0.005, 0.004, 0.011, 0.007, 0.182, 0.006, 0.005, 0.004, 0.004, 0.003, 0.005, 0.009, 0.008, 0.005, 0.005, 0.003, 0.002, 0.001, 0.003, 0.006, 0.004, 0.004, 0.003, 0.003, 0.003, 0.002, 0.002, 0.0001, 0.0001, 0.019, 0.193, 0.007, 0.009, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.005, 0.002, 0.005, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.035, 0.03, 0.004, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.019, 0.008, 0.026, 0.006, 0.003, 0.008, 0.005, 0.003, 0.002, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bm": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.129, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.167, 0.007, 0.144, 0.0001, 0.001, 0.013, 0.002, 0.256, 0.237, 0.237, 0.007, 0.003, 0.973, 0.158, 0.97, 0.007, 0.243, 0.224, 0.128, 0.052, 0.064, 0.06, 0.072, 0.055, 0.07, 0.12, 0.287, 0.015, 0.0001, 0.01, 0.0001, 0.005, 0.0001, 0.444, 0.348, 0.111, 0.212, 0.105, 0.277, 0.105, 0.044, 0.094, 0.171, 0.429, 0.132, 0.368, 0.21, 0.091, 0.065, 0.003, 0.072, 0.446, 0.184, 0.079, 0.027, 0.078, 0.004, 0.046, 0.018, 0.018, 0.0001, 0.014, 0.0001, 0.017, 0.0001, 12.037, 2.27, 0.406, 1.816, 3.589, 1.305, 1.615, 0.299, 5.301, 0.672, 3.384, 3.18, 2.268, 7.22, 3.282, 0.194, 0.029, 2.428, 2.045, 1.645, 2.796, 0.059, 0.96, 0.016, 1.69, 0.107, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.237, 0.003, 0.001, 0.017, 0.017, 0.007, 0.015, 0.003, 0.008, 0.011, 0.026, 0.017, 0.001, 0.0001, 0.018, 0.005, 0.013, 0.002, 0.004, 0.018, 1.999, 0.0001, 0.0001, 0.0001, 0.002, 0.172, 0.0001, 1.879, 0.012, 0.017, 0.004, 0.0001, 0.054, 0.002, 0.001, 0.001, 0.002, 0.003, 0.005, 0.027, 0.322, 0.21, 0.005, 0.017, 0.007, 0.002, 0.001, 0.011, 0.002, 0.012, 0.238, 0.014, 0.415, 0.435, 0.001, 0.007, 0.005, 0.009, 0.01, 0.017, 0.003, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.064, 1.039, 0.002, 0.033, 0.027, 0.0001, 0.0001, 4.089, 0.016, 0.002, 0.003, 0.0001, 0.433, 0.0001, 0.024, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.065, 0.05, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.015, 0.0001, 0.003, 0.233, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.319, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.406, 0.001, 0.076, 0.0001, 0.0001, 0.012, 0.0001, 0.015, 0.057, 0.058, 0.0001, 0.001, 0.196, 0.086, 0.029, 0.005, 0.005, 0.006, 0.004, 0.002, 0.002, 0.002, 0.002, 0.001, 0.002, 0.002, 0.016, 0.009, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.005, 0.003, 0.004, 0.002, 0.002, 0.002, 0.002, 0.002, 0.003, 0.002, 0.001, 0.002, 0.003, 0.002, 0.002, 0.003, 0.0001, 0.002, 0.004, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.004, 0.001, 0.001, 0.0001, 0.043, 0.007, 0.016, 0.016, 0.05, 0.009, 0.009, 0.017, 0.038, 0.001, 0.004, 0.022, 0.013, 0.034, 0.034, 0.01, 0.001, 0.031, 0.027, 0.033, 0.016, 0.005, 0.005, 0.002, 0.008, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.359, 0.551, 0.299, 0.082, 0.002, 0.229, 0.186, 2.436, 0.034, 0.152, 0.002, 0.333, 0.036, 2.245, 0.026, 0.384, 0.008, 0.001, 0.001, 0.181, 0.002, 1.31, 0.16, 0.34, 0.043, 0.053, 0.26, 0.209, 0.4, 0.015, 0.042, 0.46, 0.067, 0.212, 0.008, 0.16, 1.542, 0.621, 24.834, 6.808, 1.602, 0.04, 0.792, 0.149, 1.148, 0.261, 0.867, 1.261, 2.631, 0.001, 0.874, 0.001, 0.001, 0.001, 0.381, 0.232, 0.963, 0.451, 0.001, 0.001, 0.701, 0.0001, 2.837, 1.811, 0.0001, 0.0001, 0.013, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.991, 0.0001, 0.03, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.169, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.69, 0.0001, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.01, 0.01, 0.0001, 0.0001, 0.002, 0.003, 0.005, 0.001, 0.003, 0.004, 0.003, 0.002, 0.001, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.012, 0.002, 0.004, 0.004, 0.015, 0.003, 0.003, 0.006, 0.011, 0.0001, 0.001, 0.005, 0.003, 0.01, 0.01, 0.003, 0.0001, 0.008, 0.008, 0.01, 0.004, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.3, 0.21, 1.61, 0.004, 1.096, 0.171, 0.232, 0.056, 0.006, 0.125, 0.009, 7.85, 0.044, 0.821, 0.01, 0.147, 0.305, 1.571, 0.233, 1.086, 0.826, 0.17, 1.379, 0.052, 0.974, 0.101, 0.175, 0.065, 0.005, 0.008, 0.253, 0.318, 0.893, 0.39, 1.207, 0.915, 0.217, 0.014, 2.41, 0.028, 0.071, 0.06, 0.002, 0.023, 0.001, 0.018, 0.001, 0.001, 0.003, 0.913, 2.028, 0.112, 1.086, 0.005, 0.001, 0.055, 0.005, 0.003, 0.951, 0.005, 10.217, 21.49, 2.602, 0.016, 0.0001, 0.0001, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 32.905, 0.0001, 0.024, 0.009, 0.002, 0.006, 0.004, 0.005, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bpy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.902, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.282, 0.0001, 0.009, 0.0001, 0.0001, 0.224, 0.0001, 0.002, 0.281, 0.281, 0.0001, 0.0001, 0.306, 0.253, 0.183, 0.08, 0.005, 0.009, 0.002, 0.004, 0.002, 0.003, 0.003, 0.003, 0.003, 0.003, 0.197, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.016, 0.008, 0.017, 0.005, 0.005, 0.002, 0.004, 0.002, 0.003, 0.003, 0.005, 0.003, 0.007, 0.007, 0.001, 0.007, 0.0001, 0.004, 0.019, 0.004, 0.016, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.014, 0.0001, 0.118, 0.01, 0.016, 0.026, 0.05, 0.006, 0.015, 0.031, 0.057, 0.004, 0.009, 0.031, 0.017, 0.064, 0.06, 0.015, 0.001, 0.059, 0.03, 0.047, 0.04, 0.005, 0.005, 0.001, 0.018, 0.002, 0.0001, 0.016, 0.0001, 0.0001, 0.0001, 0.094, 0.582, 0.295, 0.004, 0.001, 0.199, 0.278, 1.651, 0.006, 0.325, 0.001, 0.49, 0.119, 1.057, 0.003, 0.285, 0.0001, 0.0001, 0.0001, 0.034, 0.032, 0.592, 0.143, 0.798, 0.084, 0.129, 0.075, 0.036, 0.484, 0.004, 0.03, 0.329, 0.051, 0.128, 0.007, 0.019, 1.405, 0.659, 24.309, 6.387, 2.166, 0.231, 0.814, 0.355, 0.961, 0.379, 1.131, 0.99, 2.941, 0.034, 0.919, 0.004, 0.001, 0.001, 0.243, 0.193, 0.791, 1.05, 0.0001, 0.0001, 0.626, 0.0001, 4.392, 1.335, 0.0001, 0.0001, 0.04, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.31, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "br": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.678, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.255, 0.004, 0.515, 0.0001, 0.0001, 0.007, 0.002, 0.663, 0.246, 0.246, 0.001, 0.002, 0.881, 0.746, 0.901, 0.014, 0.258, 0.444, 0.187, 0.109, 0.115, 0.122, 0.109, 0.12, 0.152, 0.228, 0.115, 0.024, 0.015, 0.004, 0.016, 0.003, 0.0001, 0.347, 0.279, 0.201, 0.205, 0.261, 0.098, 0.212, 0.134, 0.164, 0.075, 0.201, 0.168, 0.253, 0.109, 0.059, 0.199, 0.006, 0.146, 0.289, 0.136, 0.097, 0.091, 0.051, 0.019, 0.032, 0.015, 0.024, 0.0001, 0.024, 0.0001, 0.001, 0.0001, 9.146, 1.127, 0.833, 2.777, 10.42, 0.294, 1.799, 2.456, 3.655, 0.167, 1.352, 2.97, 1.505, 5.492, 4.696, 0.867, 0.019, 5.665, 2.33, 3.448, 2.744, 1.784, 0.434, 0.03, 0.247, 2.302, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.1, 0.012, 0.008, 0.007, 0.005, 0.004, 0.003, 0.003, 0.004, 0.005, 0.002, 0.002, 0.004, 0.005, 0.003, 0.002, 0.003, 0.002, 0.002, 0.011, 0.005, 0.002, 0.002, 0.002, 0.002, 0.074, 0.002, 0.003, 0.005, 0.005, 0.001, 0.004, 0.021, 0.015, 0.009, 0.005, 0.007, 0.003, 0.004, 0.009, 0.013, 0.045, 0.076, 0.018, 0.003, 0.013, 0.003, 0.005, 0.011, 0.591, 0.009, 0.012, 0.018, 0.007, 0.006, 0.004, 0.009, 0.467, 0.008, 0.021, 0.017, 0.008, 0.005, 0.006, 0.0001, 0.0001, 0.048, 1.28, 0.01, 0.011, 0.0001, 0.001, 0.0001, 0.004, 0.002, 0.002, 0.002, 0.0001, 0.032, 0.015, 0.039, 0.015, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.006, 0.009, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.009, 0.096, 0.003, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bs": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.108, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.139, 0.002, 0.313, 0.001, 0.001, 0.017, 0.002, 0.011, 0.204, 0.204, 0.001, 0.006, 0.915, 0.157, 1.176, 0.034, 0.332, 0.467, 0.264, 0.159, 0.151, 0.151, 0.132, 0.126, 0.142, 0.226, 0.068, 0.015, 0.006, 0.007, 0.006, 0.001, 0.0001, 0.156, 0.174, 0.174, 0.143, 0.072, 0.074, 0.155, 0.136, 0.152, 0.073, 0.147, 0.082, 0.163, 0.218, 0.118, 0.225, 0.003, 0.11, 0.283, 0.122, 0.105, 0.088, 0.031, 0.007, 0.007, 0.073, 0.025, 0.0001, 0.025, 0.0001, 0.008, 0.0001, 8.723, 0.95, 0.762, 2.331, 6.777, 0.26, 1.369, 0.582, 7.412, 3.867, 2.673, 2.682, 2.205, 4.994, 6.632, 1.941, 0.005, 3.955, 3.612, 3.234, 3.103, 2.415, 0.036, 0.017, 0.061, 1.207, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.038, 0.004, 0.003, 0.002, 0.002, 0.001, 0.003, 0.388, 0.002, 0.001, 0.001, 0.001, 0.016, 0.618, 0.001, 0.0001, 0.003, 0.172, 0.002, 0.018, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.006, 0.003, 0.004, 0.002, 0.035, 0.482, 0.001, 0.001, 0.003, 0.001, 0.001, 0.002, 0.001, 0.008, 0.001, 0.002, 0.001, 0.003, 0.001, 0.001, 0.007, 0.004, 0.003, 0.004, 0.002, 0.003, 0.004, 0.002, 0.004, 0.002, 0.002, 0.003, 0.006, 0.012, 0.366, 0.002, 0.0001, 0.0001, 0.02, 0.032, 1.199, 0.874, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.014, 0.006, 0.021, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bug": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.068, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.164, 0.0001, 0.016, 0.0001, 0.0001, 0.003, 0.001, 0.137, 0.016, 0.016, 0.0001, 0.001, 0.196, 1.935, 1.044, 0.004, 0.035, 0.02, 0.023, 0.01, 0.009, 0.007, 0.007, 0.006, 0.007, 0.013, 0.007, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.516, 0.311, 0.434, 0.185, 0.139, 0.134, 0.304, 0.324, 0.039, 0.055, 0.029, 0.369, 0.412, 0.063, 0.111, 1.316, 0.017, 0.157, 0.558, 0.13, 0.016, 0.233, 0.012, 0.002, 0.073, 0.002, 0.007, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 9.887, 0.241, 1.633, 1.832, 7.179, 0.088, 0.757, 0.513, 7.161, 0.111, 1.126, 1.683, 2.724, 6.291, 2.861, 1.308, 0.04, 7.537, 3.873, 3.7, 4.723, 0.375, 1.036, 0.149, 1.531, 0.172, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.047, 0.009, 0.005, 0.004, 0.009, 0.007, 0.006, 0.004, 0.009, 0.039, 0.01, 0.038, 0.003, 0.005, 0.002, 0.001, 0.004, 0.012, 0.007, 0.011, 0.011, 0.02, 0.001, 0.02, 0.012, 0.019, 0.011, 0.012, 0.002, 0.001, 0.006, 0.003, 0.004, 0.003, 0.047, 0.002, 0.016, 0.005, 0.004, 0.01, 0.405, 2.36, 0.01, 0.013, 0.003, 0.001, 0.008, 0.004, 0.008, 0.004, 0.008, 0.005, 0.176, 0.005, 0.002, 0.003, 0.012, 0.005, 0.008, 0.007, 0.003, 0.003, 0.004, 0.003, 0.0001, 0.0001, 0.007, 2.887, 0.002, 0.04, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.023, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.008, 0.007, 0.001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.048, 0.15, 0.04, 0.0001, 0.0001, 0.002, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "bxr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.49, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.129, 0.001, 0.08, 0.0001, 0.0001, 0.012, 0.0001, 0.001, 0.147, 0.147, 0.0001, 0.002, 0.553, 0.131, 0.523, 0.004, 0.151, 0.243, 0.109, 0.074, 0.068, 0.074, 0.065, 0.062, 0.079, 0.12, 0.022, 0.018, 0.003, 0.001, 0.002, 0.001, 0.0001, 0.004, 0.002, 0.007, 0.001, 0.002, 0.002, 0.002, 0.004, 0.037, 0.001, 0.001, 0.002, 0.003, 0.003, 0.003, 0.003, 0.0001, 0.002, 0.004, 0.003, 0.001, 0.011, 0.001, 0.019, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.037, 0.005, 0.011, 0.009, 0.029, 0.005, 0.007, 0.031, 0.027, 0.001, 0.005, 0.019, 0.012, 0.022, 0.025, 0.008, 0.001, 0.023, 0.018, 0.017, 0.016, 0.003, 0.002, 0.001, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.392, 0.859, 1.489, 1.628, 0.046, 1.574, 0.057, 0.037, 0.549, 0.002, 0.003, 0.546, 0.265, 4.264, 0.148, 0.174, 0.118, 0.207, 0.029, 0.069, 0.123, 0.028, 0.013, 0.033, 0.034, 0.005, 0.055, 0.03, 0.09, 0.073, 0.049, 0.037, 0.094, 0.079, 0.088, 0.076, 0.026, 0.12, 0.011, 0.016, 0.032, 0.306, 0.001, 0.058, 0.001, 0.071, 0.033, 1.461, 5.842, 1.346, 0.152, 2.003, 2.072, 0.704, 0.52, 0.475, 1.576, 1.562, 0.254, 3.078, 0.893, 3.534, 3.045, 0.105, 0.0001, 0.0001, 0.188, 0.005, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.006, 0.002, 27.741, 14.028, 2.178, 0.307, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.075, 0.002, 0.001, 0.004, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cdo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.899, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.597, 0.001, 0.273, 0.0001, 0.0001, 0.004, 0.0001, 0.004, 0.549, 0.551, 0.0001, 0.001, 0.624, 3.929, 0.732, 0.03, 0.251, 0.611, 0.29, 0.189, 0.163, 0.163, 0.16, 0.156, 0.166, 0.215, 0.133, 0.012, 0.001, 0.0001, 0.001, 0.002, 0.0001, 0.053, 0.117, 0.299, 0.251, 0.017, 0.027, 0.504, 0.23, 0.082, 0.03, 0.071, 0.135, 0.356, 0.159, 0.039, 0.068, 0.004, 0.027, 0.229, 0.101, 0.044, 0.025, 0.062, 0.001, 0.013, 0.003, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.822, 0.392, 1.504, 1.05, 0.748, 0.033, 6.691, 1.959, 3.832, 0.006, 1.877, 0.724, 0.396, 5.597, 0.623, 0.123, 0.005, 0.411, 2.143, 0.557, 2.118, 0.037, 0.065, 0.039, 0.184, 0.014, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.562, 0.653, 0.229, 0.604, 0.418, 0.298, 0.318, 0.129, 0.175, 0.171, 0.118, 0.212, 0.31, 0.409, 0.113, 0.98, 0.125, 0.066, 0.036, 0.255, 0.106, 0.397, 0.142, 0.124, 0.138, 0.172, 0.096, 0.139, 0.338, 0.116, 0.144, 0.186, 0.41, 1.078, 0.77, 0.114, 1.515, 0.081, 0.097, 0.077, 0.628, 0.714, 1.044, 0.603, 1.183, 1.024, 0.119, 0.129, 0.135, 0.183, 0.537, 1.615, 1.19, 0.067, 0.211, 0.1, 0.216, 1.217, 0.179, 0.199, 0.306, 0.119, 0.135, 0.091, 0.0001, 0.0001, 0.041, 7.531, 2.472, 1.618, 0.001, 0.001, 0.0001, 0.002, 0.002, 0.001, 2.018, 0.0001, 0.014, 0.006, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.757, 0.108, 0.212, 0.359, 1.361, 0.793, 0.503, 0.549, 0.397, 0.002, 0.003, 0.004, 0.001, 0.0001, 0.218, 0.03, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ce": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.477, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.593, 0.0001, 0.003, 0.0001, 0.0001, 0.014, 0.0001, 0.0001, 0.462, 0.462, 0.0001, 0.166, 0.461, 0.186, 0.813, 0.002, 0.175, 0.094, 0.109, 0.14, 0.045, 0.029, 0.022, 0.02, 0.031, 0.028, 0.033, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.145, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.145, 0.144, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.704, 1.438, 1.762, 1.875, 0.015, 2.329, 0.449, 0.169, 0.835, 0.009, 0.342, 0.05, 1.751, 0.164, 0.611, 0.21, 0.068, 0.113, 0.056, 0.04, 0.434, 0.02, 0.006, 0.019, 0.028, 0.002, 0.404, 0.034, 0.196, 0.056, 0.049, 0.075, 0.184, 0.229, 0.057, 0.026, 0.146, 0.02, 0.017, 0.02, 0.129, 0.002, 0.0001, 0.004, 0.0001, 0.008, 0.009, 0.018, 7.603, 0.877, 1.017, 0.93, 0.629, 1.84, 0.05, 0.386, 1.788, 1.009, 1.778, 2.253, 0.873, 3.199, 2.291, 0.075, 0.0001, 0.0001, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 28.632, 13.675, 0.0001, 0.638, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.405, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ceb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.228, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.341, 0.0001, 0.15, 0.0001, 0.0001, 0.002, 0.0001, 0.016, 0.068, 0.068, 0.0001, 0.0001, 1.15, 0.441, 1.259, 0.001, 0.028, 0.059, 0.035, 0.022, 0.021, 0.022, 0.021, 0.021, 0.026, 0.036, 0.037, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.098, 0.168, 0.578, 0.161, 0.203, 0.063, 0.093, 0.198, 0.052, 0.044, 0.126, 0.151, 0.236, 0.118, 0.082, 0.261, 0.02, 0.131, 0.295, 0.118, 0.081, 0.041, 0.087, 0.005, 0.015, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 15.378, 2.318, 0.367, 1.953, 2.974, 0.093, 5.126, 1.479, 4.851, 0.069, 2.449, 3.4, 2.839, 8.407, 4.701, 1.442, 0.019, 2.43, 4.783, 3.214, 2.941, 0.169, 0.623, 0.03, 1.539, 0.068, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.059, 0.004, 0.005, 0.004, 0.004, 0.003, 0.008, 0.005, 0.003, 0.002, 0.001, 0.004, 0.009, 0.002, 0.004, 0.002, 0.003, 0.0001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.01, 0.005, 0.001, 0.002, 0.001, 0.001, 0.002, 0.006, 0.184, 0.019, 0.007, 0.005, 0.008, 0.019, 0.003, 0.009, 0.007, 0.025, 0.004, 0.049, 0.001, 0.018, 0.002, 0.008, 0.279, 0.015, 0.004, 0.013, 0.004, 0.003, 0.007, 0.001, 0.046, 0.006, 0.007, 0.005, 0.006, 0.004, 0.006, 0.001, 0.0001, 0.0001, 0.452, 0.166, 0.097, 0.047, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.031, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.019, 0.018, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.017, 0.012, 0.008, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ch": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.587, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.467, 0.008, 0.286, 0.0001, 0.0001, 0.018, 0.0001, 1.077, 0.189, 0.189, 0.0001, 0.0001, 1.14, 0.532, 1.257, 0.007, 0.648, 0.639, 0.504, 0.182, 0.3, 0.173, 0.195, 0.169, 0.204, 0.218, 0.042, 0.013, 0.0001, 0.001, 0.0001, 0.005, 0.0001, 0.26, 0.146, 0.257, 0.104, 0.401, 0.111, 0.564, 0.173, 0.223, 0.038, 0.106, 0.097, 0.317, 0.12, 0.025, 0.199, 0.01, 0.074, 0.256, 0.153, 0.279, 0.066, 0.06, 0.002, 0.047, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 10.968, 0.472, 0.524, 1.575, 4.239, 0.44, 3.776, 1.808, 6.943, 0.028, 1.21, 2.019, 1.749, 8.291, 5.798, 1.592, 0.018, 1.795, 5.81, 3.872, 3.565, 0.141, 0.106, 0.012, 0.845, 0.055, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.016, 0.008, 0.003, 0.001, 0.002, 0.01, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.0001, 0.0001, 0.006, 0.001, 0.0001, 0.005, 0.003, 0.0001, 0.0001, 0.001, 0.0001, 0.011, 0.0001, 0.003, 0.001, 0.0001, 0.002, 0.001, 0.0001, 0.02, 0.002, 0.003, 0.001, 0.974, 0.0001, 0.004, 0.003, 0.012, 0.0001, 0.0001, 0.001, 0.009, 0.0001, 0.0001, 0.002, 0.432, 0.0001, 0.044, 0.0001, 0.001, 0.003, 0.001, 0.002, 0.002, 0.006, 0.007, 0.002, 0.002, 0.001, 0.003, 0.0001, 0.0001, 0.001, 1.51, 0.004, 0.013, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.002, 0.0001, 0.0001, 0.005, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.012, 0.0001, 0.0001, 0.003, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cho": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.477, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.446, 0.089, 1.242, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.621, 0.621, 0.0001, 0.0001, 0.799, 0.0001, 0.532, 0.0001, 0.0001, 0.177, 0.089, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.355, 0.266, 0.0001, 0.0001, 0.0001, 0.089, 0.0001, 0.444, 0.0001, 1.154, 0.0001, 0.0001, 0.0001, 0.089, 0.799, 0.177, 0.0001, 0.177, 0.0001, 0.355, 0.177, 0.177, 0.444, 0.0001, 0.0001, 0.355, 0.0001, 0.0001, 0.089, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.955, 1.154, 0.799, 0.0001, 2.839, 0.177, 0.621, 7.365, 8.252, 0.0001, 5.146, 2.662, 3.549, 3.727, 5.413, 1.597, 0.0001, 0.799, 3.638, 5.146, 1.597, 1.065, 0.089, 0.0001, 1.331, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.154, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.266, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.177, 0.0001, 0.0001, 0.0001, 1.154, 0.0001, 0.089, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "chr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.394, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.115, 0.002, 0.174, 0.0001, 0.001, 0.005, 0.001, 0.018, 0.095, 0.095, 0.0001, 0.001, 0.499, 0.081, 0.439, 0.009, 0.086, 0.076, 0.045, 0.025, 0.02, 0.027, 0.02, 0.018, 0.025, 0.029, 0.03, 0.019, 0.002, 0.001, 0.003, 0.002, 0.0001, 0.037, 0.02, 0.038, 0.014, 0.023, 0.017, 0.012, 0.014, 0.019, 0.011, 0.01, 0.013, 0.028, 0.014, 0.01, 0.02, 0.002, 0.016, 0.034, 0.027, 0.013, 0.008, 0.015, 0.002, 0.005, 0.003, 0.065, 0.0001, 0.065, 0.0001, 0.004, 0.0001, 0.692, 0.092, 0.264, 0.31, 0.823, 0.092, 0.184, 0.209, 0.663, 0.01, 0.064, 0.374, 0.188, 0.502, 0.498, 0.163, 0.016, 0.479, 0.482, 0.523, 0.235, 0.107, 0.076, 0.023, 0.123, 0.021, 0.0001, 0.028, 0.0001, 0.0001, 0.0001, 0.027, 0.355, 0.722, 0.213, 0.313, 0.628, 0.115, 0.06, 0.021, 0.056, 0.084, 0.04, 0.154, 1.876, 13.554, 13.952, 0.082, 0.032, 0.441, 0.837, 0.268, 0.161, 0.041, 1.986, 0.138, 0.561, 0.191, 0.664, 0.014, 0.045, 0.005, 0.13, 2.057, 0.126, 1.445, 0.138, 1.031, 0.39, 0.904, 0.381, 0.457, 1.048, 0.569, 0.458, 0.748, 0.433, 0.062, 1.427, 0.213, 0.207, 0.29, 0.574, 0.831, 0.687, 0.218, 0.077, 0.387, 0.051, 0.016, 0.01, 0.004, 0.004, 1.405, 0.134, 0.0001, 0.0001, 0.009, 0.006, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 27.238, 0.017, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "chy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.992, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.662, 0.002, 0.655, 0.0001, 0.0001, 0.0001, 0.0001, 4.281, 0.488, 0.49, 0.012, 0.039, 1.209, 0.935, 1.193, 0.009, 0.099, 0.186, 0.07, 0.039, 0.048, 0.046, 0.051, 0.032, 0.087, 0.113, 0.294, 0.06, 0.044, 0.012, 0.043, 0.009, 0.0001, 0.28, 0.143, 0.271, 0.068, 0.058, 0.046, 0.056, 0.705, 0.041, 0.084, 0.094, 0.075, 0.71, 0.203, 0.133, 0.21, 0.01, 0.123, 0.333, 0.369, 0.109, 0.326, 0.043, 0.02, 0.015, 0.015, 0.017, 0.0001, 0.017, 0.0001, 0.0001, 0.005, 5.694, 0.454, 0.435, 0.594, 8.431, 0.195, 0.654, 4.544, 1.753, 0.053, 1.313, 1.118, 1.931, 4.523, 6.14, 0.553, 0.043, 1.203, 5.097, 4.735, 0.637, 1.842, 0.224, 0.461, 0.27, 0.08, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.024, 0.014, 0.009, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.113, 0.0001, 0.002, 0.007, 0.005, 0.0001, 0.0001, 0.005, 0.002, 0.0001, 0.058, 0.012, 0.0001, 0.003, 0.029, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.002, 0.044, 1.384, 0.696, 0.009, 0.027, 0.002, 0.002, 0.039, 0.005, 3.484, 0.98, 0.162, 0.003, 0.009, 0.002, 0.017, 0.009, 0.003, 0.005, 1.282, 0.993, 0.003, 0.142, 0.0001, 0.017, 0.0001, 0.002, 0.009, 0.007, 0.0001, 0.007, 0.005, 0.0001, 0.0001, 0.014, 8.846, 0.043, 0.545, 0.0001, 0.005, 0.046, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.031, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.019, 0.003, 0.017, 0.0001, 0.0001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ckb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.676, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.035, 0.002, 0.062, 0.0001, 0.0001, 0.003, 0.0001, 0.002, 0.131, 0.13, 0.001, 0.001, 0.011, 0.034, 0.374, 0.013, 0.01, 0.014, 0.008, 0.005, 0.004, 0.004, 0.004, 0.004, 0.005, 0.007, 0.05, 0.0001, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.009, 0.006, 0.007, 0.006, 0.004, 0.004, 0.004, 0.004, 0.005, 0.002, 0.003, 0.004, 0.007, 0.005, 0.003, 0.007, 0.001, 0.005, 0.01, 0.007, 0.002, 0.002, 0.003, 0.001, 0.001, 0.001, 0.004, 0.0001, 0.004, 0.0001, 0.003, 0.0001, 0.058, 0.008, 0.018, 0.017, 0.063, 0.009, 0.012, 0.017, 0.048, 0.001, 0.008, 0.031, 0.019, 0.043, 0.045, 0.012, 0.001, 0.045, 0.029, 0.036, 0.019, 0.006, 0.008, 0.003, 0.011, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.386, 0.193, 0.124, 0.067, 1.187, 1.207, 3.947, 0.41, 3.556, 0.028, 0.015, 0.002, 5.576, 0.003, 1.191, 0.005, 0.006, 0.005, 0.002, 0.004, 0.001, 6.665, 0.001, 0.002, 0.236, 0.001, 0.002, 0.008, 0.002, 0.002, 0.001, 0.006, 0.161, 0.192, 0.114, 0.062, 0.112, 0.064, 0.707, 4.366, 1.564, 2.13, 1.551, 0.015, 0.253, 0.092, 0.303, 2.261, 0.008, 2.411, 0.524, 1.151, 0.651, 0.531, 0.001, 0.004, 0.003, 0.092, 0.048, 0.036, 0.003, 0.003, 0.823, 0.003, 0.0001, 0.0001, 0.028, 0.007, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 15.514, 10.978, 4.45, 13.188, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.375, 0.002, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.063, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "co": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.449, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.862, 0.008, 0.387, 0.0001, 0.0001, 0.006, 0.001, 0.763, 0.212, 0.212, 0.003, 0.001, 0.925, 0.075, 0.859, 0.019, 0.189, 0.28, 0.146, 0.097, 0.087, 0.101, 0.081, 0.085, 0.107, 0.132, 0.097, 0.026, 0.009, 0.003, 0.01, 0.004, 0.0001, 0.325, 0.102, 0.335, 0.094, 0.091, 0.089, 0.126, 0.077, 0.208, 0.025, 0.02, 0.156, 0.189, 0.082, 0.052, 0.201, 0.016, 0.093, 0.268, 0.121, 0.17, 0.078, 0.019, 0.022, 0.005, 0.013, 0.032, 0.0001, 0.032, 0.0001, 0.016, 0.0001, 8.602, 0.557, 3.322, 3.101, 4.329, 0.784, 1.174, 1.381, 10.092, 0.419, 0.069, 2.83, 1.864, 5.457, 2.618, 1.888, 0.179, 4.342, 3.458, 4.676, 6.626, 0.877, 0.033, 0.017, 0.063, 0.595, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.058, 0.006, 0.004, 0.002, 0.003, 0.001, 0.001, 0.001, 0.004, 0.001, 0.001, 0.0001, 0.002, 0.002, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.039, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.789, 0.005, 0.002, 0.002, 0.004, 0.001, 0.002, 0.004, 0.94, 0.016, 0.001, 0.007, 0.251, 0.004, 0.001, 0.002, 0.005, 0.006, 0.189, 0.011, 0.005, 0.003, 0.002, 0.024, 0.003, 0.252, 0.004, 0.007, 0.006, 0.005, 0.002, 0.004, 0.0001, 0.0001, 0.05, 2.469, 0.006, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.032, 0.015, 0.008, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.004, 0.04, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.443, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.088, 0.004, 0.073, 0.0001, 0.0001, 0.02, 0.0001, 0.023, 0.121, 0.12, 0.0001, 0.002, 0.629, 0.081, 0.971, 0.012, 0.119, 0.193, 0.101, 0.064, 0.076, 0.066, 0.061, 0.066, 0.062, 0.105, 0.063, 0.027, 0.0001, 0.0001, 0.0001, 0.015, 0.0001, 0.161, 0.04, 0.143, 0.045, 0.195, 0.034, 0.029, 0.053, 0.081, 0.084, 0.151, 0.056, 0.235, 0.167, 0.103, 0.138, 0.009, 0.033, 0.115, 0.119, 0.03, 0.034, 0.067, 0.012, 0.01, 0.004, 0.05, 0.0001, 0.047, 0.0001, 0.014, 0.0001, 9.914, 0.233, 4.69, 1.145, 5.906, 0.235, 0.326, 1.052, 10.924, 0.134, 6.149, 1.256, 2.551, 4.689, 5.033, 1.928, 0.073, 2.706, 3.099, 5.744, 0.924, 0.192, 2.967, 0.038, 0.312, 0.067, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.088, 0.031, 0.077, 0.099, 0.046, 0.115, 0.007, 0.048, 0.054, 0.011, 0.091, 0.103, 0.074, 0.037, 0.073, 0.005, 0.766, 0.405, 0.312, 0.295, 0.175, 0.052, 0.036, 0.009, 0.01, 0.038, 0.001, 0.005, 0.002, 0.0001, 0.001, 0.021, 0.037, 0.111, 0.205, 0.026, 0.084, 0.087, 0.065, 0.093, 0.076, 0.063, 0.057, 0.032, 0.002, 0.144, 0.111, 0.096, 0.017, 0.078, 0.065, 0.232, 0.037, 0.005, 0.0001, 0.0001, 0.021, 0.005, 0.022, 0.02, 0.014, 0.002, 0.005, 0.005, 0.0001, 0.0001, 0.046, 0.821, 0.023, 0.077, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 1.861, 0.08, 0.005, 0.002, 0.009, 0.005, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "crh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.666, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.545, 0.003, 0.2, 0.0001, 0.003, 0.006, 0.0001, 0.011, 0.498, 0.498, 0.001, 0.003, 0.581, 0.375, 1.265, 0.029, 0.54, 0.844, 0.447, 0.25, 0.254, 0.244, 0.225, 0.224, 0.237, 0.353, 0.036, 0.017, 0.017, 0.002, 0.017, 0.003, 0.0001, 0.292, 0.227, 0.115, 0.122, 0.258, 0.045, 0.081, 0.079, 0.299, 0.014, 0.172, 0.079, 0.19, 0.068, 0.102, 0.074, 0.317, 0.092, 0.196, 0.162, 0.157, 0.161, 0.003, 0.13, 0.089, 0.035, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 7.42, 1.383, 0.39, 2.173, 6.493, 0.253, 0.439, 0.324, 6.527, 0.039, 1.974, 3.301, 1.629, 5.164, 1.476, 0.486, 0.955, 4.625, 3.637, 2.416, 1.149, 1.071, 0.013, 0.004, 1.959, 0.598, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.415, 0.022, 0.015, 0.022, 0.008, 0.007, 0.005, 0.065, 0.008, 0.005, 0.004, 0.008, 0.007, 0.007, 0.003, 0.008, 0.005, 0.004, 0.004, 0.069, 0.234, 0.004, 0.026, 0.004, 0.006, 0.008, 0.008, 0.005, 0.067, 0.049, 0.094, 1.497, 0.026, 0.01, 0.278, 0.006, 0.008, 0.006, 0.005, 0.416, 0.004, 0.006, 0.005, 0.014, 0.004, 0.007, 0.006, 0.006, 0.149, 5.025, 0.014, 0.011, 0.012, 0.067, 0.295, 0.006, 0.022, 0.01, 0.019, 0.017, 0.605, 0.022, 0.039, 0.006, 0.0001, 0.0001, 0.035, 2.796, 4.495, 1.1, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.003, 0.002, 0.256, 0.079, 0.004, 0.002, 0.0001, 0.004, 0.008, 0.013, 0.021, 0.017, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.015, 0.009, 0.398, 0.007, 0.004, 0.019, 0.009, 0.005, 0.004, 0.004, 0.003, 0.002, 0.004, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "csb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.825, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.296, 0.002, 0.584, 0.0001, 0.0001, 0.003, 0.001, 0.009, 0.331, 0.334, 0.002, 0.0001, 0.877, 0.236, 1.256, 0.065, 0.271, 0.637, 0.291, 0.193, 0.181, 0.174, 0.153, 0.187, 0.256, 0.339, 0.093, 0.04, 0.024, 0.004, 0.024, 0.003, 0.0001, 0.093, 0.136, 0.203, 0.135, 0.053, 0.045, 0.141, 0.038, 0.163, 0.132, 0.28, 0.122, 0.184, 0.116, 0.024, 0.275, 0.002, 0.1, 0.23, 0.118, 0.014, 0.056, 0.218, 0.119, 0.003, 0.085, 0.006, 0.0001, 0.007, 0.0001, 0.002, 0.0001, 4.612, 0.986, 3.096, 2.007, 3.546, 0.161, 1.136, 0.946, 4.255, 1.343, 2.142, 1.634, 1.571, 3.378, 2.668, 1.384, 0.004, 3.469, 3.152, 2.405, 0.834, 0.037, 2.89, 0.011, 0.614, 4.079, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.169, 0.025, 0.879, 0.003, 0.332, 0.515, 0.031, 0.005, 0.001, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.005, 0.001, 0.013, 0.102, 0.134, 0.005, 0.002, 0.001, 0.001, 0.003, 0.049, 0.005, 0.012, 0.006, 0.026, 0.025, 0.003, 0.016, 0.006, 0.006, 0.677, 0.002, 0.001, 0.001, 0.001, 0.003, 1.17, 0.001, 2.19, 0.001, 0.003, 0.0001, 0.002, 0.009, 0.003, 2.322, 0.76, 1.31, 0.003, 0.004, 0.001, 0.007, 0.615, 0.005, 0.077, 0.465, 0.007, 0.003, 0.002, 0.0001, 0.0001, 0.14, 9.122, 0.543, 1.724, 0.0001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.006, 0.002, 0.024, 0.023, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.197, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.095, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.137, 0.0001, 0.05, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.026, 0.026, 0.001, 0.0001, 0.049, 0.014, 0.024, 0.015, 0.131, 0.259, 0.12, 0.082, 0.083, 0.082, 0.076, 0.078, 0.096, 0.129, 0.009, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.003, 0.001, 0.006, 0.001, 0.001, 0.001, 0.0001, 0.006, 0.004, 0.0001, 0.001, 0.001, 0.002, 0.002, 0.004, 0.001, 0.0001, 0.002, 0.004, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.003, 0.0001, 0.023, 0.002, 0.008, 0.007, 0.018, 0.001, 0.005, 0.004, 0.017, 0.005, 0.009, 0.01, 0.003, 0.016, 0.015, 0.003, 0.001, 0.01, 0.011, 0.009, 0.011, 0.004, 0.0001, 0.002, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.938, 4.019, 2.29, 0.582, 0.265, 0.184, 0.28, 0.33, 0.175, 0.126, 2.698, 0.002, 1.962, 0.002, 0.135, 0.0001, 0.124, 0.906, 0.12, 0.072, 1.561, 0.0001, 0.139, 0.857, 0.034, 2.179, 0.103, 0.119, 0.097, 0.099, 0.095, 0.124, 0.126, 0.438, 0.049, 1.297, 0.06, 0.96, 0.01, 0.295, 0.011, 0.359, 0.005, 0.236, 0.002, 0.101, 0.019, 0.025, 3.114, 0.623, 1.373, 0.62, 1.221, 0.086, 0.518, 0.573, 2.627, 0.002, 1.325, 1.567, 0.924, 2.121, 2.823, 0.585, 0.0001, 0.0001, 0.514, 0.003, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.408, 0.0001, 0.016, 0.012, 21.25, 18.718, 0.249, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.51, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 1.747, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.247, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.093, 0.001, 0.059, 0.0001, 0.0001, 0.007, 0.0001, 0.003, 0.152, 0.151, 0.0001, 0.002, 0.478, 0.273, 0.79, 0.011, 0.204, 0.309, 0.183, 0.104, 0.101, 0.1, 0.081, 0.081, 0.096, 0.17, 0.076, 0.008, 0.002, 0.002, 0.002, 0.003, 0.0001, 0.004, 0.003, 0.005, 0.002, 0.002, 0.002, 0.002, 0.002, 0.019, 0.001, 0.001, 0.002, 0.003, 0.002, 0.002, 0.003, 0.0001, 0.003, 0.005, 0.003, 0.002, 0.006, 0.001, 0.01, 0.001, 0.0001, 0.013, 0.0001, 0.013, 0.0001, 0.001, 0.0001, 0.027, 0.004, 0.007, 0.008, 0.027, 0.004, 0.006, 0.007, 0.02, 0.001, 0.004, 0.016, 0.009, 0.019, 0.018, 0.006, 0.0001, 0.019, 0.014, 0.015, 0.011, 0.003, 0.002, 0.002, 0.004, 0.001, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 3.257, 1.78, 2.381, 2.851, 0.156, 1.36, 0.178, 0.773, 1.001, 0.006, 0.006, 0.869, 0.319, 0.035, 0.373, 0.165, 0.161, 0.088, 0.098, 0.049, 0.312, 2.25, 0.007, 0.017, 0.069, 0.007, 0.174, 0.039, 0.101, 0.06, 0.095, 0.155, 0.212, 0.157, 0.129, 0.054, 0.061, 0.066, 0.005, 1.16, 0.101, 0.002, 0.0001, 0.045, 0.001, 0.021, 0.156, 0.041, 4.16, 0.372, 1.295, 0.368, 0.304, 3.139, 0.041, 0.13, 2.185, 0.64, 1.311, 1.785, 0.994, 3.619, 1.18, 1.135, 0.0001, 0.0001, 0.101, 1.175, 3.79, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.0001, 0.002, 0.001, 24.733, 13.586, 0.004, 0.088, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.282, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "cy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.628, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.48, 0.003, 0.545, 0.0001, 0.001, 0.007, 0.002, 0.872, 0.259, 0.258, 0.001, 0.001, 0.777, 0.194, 0.96, 0.016, 0.363, 0.487, 0.244, 0.138, 0.133, 0.135, 0.125, 0.126, 0.164, 0.239, 0.149, 0.081, 0.022, 0.001, 0.022, 0.003, 0.0001, 0.36, 0.242, 0.56, 0.267, 0.155, 0.163, 0.331, 0.126, 0.112, 0.06, 0.033, 0.279, 0.433, 0.133, 0.073, 0.238, 0.004, 0.18, 0.303, 0.196, 0.061, 0.026, 0.092, 0.003, 0.167, 0.006, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 7.082, 0.905, 1.506, 6.475, 6.263, 2.165, 2.494, 2.4, 4.773, 0.015, 0.114, 3.901, 1.419, 6.217, 4.277, 0.556, 0.008, 5.57, 2.092, 2.13, 1.941, 0.086, 2.82, 0.025, 5.712, 0.034, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.074, 0.005, 0.003, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.021, 0.002, 0.001, 0.0001, 0.001, 0.002, 0.033, 0.001, 0.001, 0.007, 0.009, 0.001, 0.001, 0.033, 0.007, 0.059, 0.003, 0.003, 0.001, 0.001, 0.003, 0.004, 0.015, 0.016, 0.004, 0.001, 0.004, 0.01, 0.012, 0.004, 0.003, 0.003, 0.004, 0.074, 0.043, 0.005, 0.016, 0.003, 0.006, 0.003, 0.002, 0.004, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.036, 0.221, 0.003, 0.06, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.007, 0.004, 0.014, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.072, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "din": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.698, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.927, 0.0001, 0.06, 0.0001, 0.003, 0.013, 0.0001, 0.015, 0.171, 0.17, 0.0001, 0.0001, 0.878, 0.077, 0.901, 0.027, 0.297, 0.229, 0.151, 0.055, 0.064, 0.078, 0.053, 0.048, 0.049, 0.126, 0.018, 0.013, 0.002, 0.0001, 0.002, 0.005, 0.0001, 0.424, 0.153, 0.093, 0.101, 0.075, 0.019, 0.074, 0.021, 0.051, 0.069, 0.324, 0.085, 0.16, 0.163, 0.021, 0.306, 0.002, 0.087, 0.062, 0.288, 0.034, 0.007, 0.069, 0.0001, 0.136, 0.003, 0.027, 0.0001, 0.027, 0.0001, 0.0001, 0.0001, 5.438, 0.999, 2.9, 1.603, 4.394, 0.024, 0.521, 1.912, 3.749, 0.362, 4.818, 2.02, 1.512, 4.26, 1.668, 1.035, 0.003, 2.29, 0.155, 3.595, 3.428, 0.022, 0.527, 0.011, 2.005, 0.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.036, 0.001, 0.001, 0.0001, 0.027, 0.0001, 0.026, 0.0001, 1.487, 0.0001, 0.005, 1.04, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 2.319, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 1.678, 0.006, 0.006, 0.0001, 0.0001, 0.01, 0.0001, 0.0001, 0.222, 1.181, 0.0001, 0.0001, 0.001, 0.004, 0.001, 0.0001, 3.25, 0.0001, 0.001, 0.006, 1.508, 0.003, 0.002, 0.006, 0.002, 0.0001, 0.011, 1.021, 0.001, 0.004, 0.002, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.016, 6.971, 0.0001, 1.041, 0.02, 0.0001, 0.0001, 4.193, 0.0001, 0.0001, 1.487, 0.0001, 0.027, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.062, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "diq": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.719, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.354, 0.008, 0.4, 0.0001, 0.0001, 0.009, 0.0001, 0.031, 0.299, 0.3, 0.001, 0.003, 0.98, 0.165, 1.27, 0.045, 0.227, 0.302, 0.162, 0.087, 0.08, 0.089, 0.076, 0.082, 0.096, 0.17, 0.156, 0.035, 0.026, 0.008, 0.027, 0.01, 0.0001, 0.309, 0.187, 0.135, 0.206, 0.243, 0.108, 0.12, 0.188, 0.05, 0.033, 0.209, 0.106, 0.271, 0.167, 0.06, 0.167, 0.062, 0.13, 0.271, 0.259, 0.059, 0.085, 0.06, 0.052, 0.088, 0.128, 0.014, 0.0001, 0.014, 0.0001, 0.002, 0.001, 7.586, 1.293, 0.911, 2.514, 8.148, 0.439, 0.62, 0.759, 4.61, 0.11, 2.125, 1.599, 2.095, 4.93, 3.468, 0.588, 0.377, 4.808, 2.018, 2.359, 1.695, 0.626, 1.106, 0.479, 3.36, 1.081, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.078, 0.018, 0.011, 0.012, 0.02, 0.015, 0.019, 0.078, 0.016, 0.004, 0.018, 0.002, 0.014, 0.004, 0.014, 0.003, 0.006, 0.005, 0.003, 0.011, 0.005, 0.006, 0.005, 0.002, 0.009, 0.023, 0.002, 0.004, 0.022, 0.016, 0.065, 0.865, 0.032, 0.01, 0.013, 0.005, 0.007, 0.004, 0.006, 0.242, 0.014, 0.032, 2.716, 0.012, 0.007, 0.008, 0.29, 0.015, 0.191, 2.379, 0.013, 0.015, 0.01, 0.006, 0.021, 0.004, 0.009, 0.01, 0.007, 0.128, 0.093, 0.009, 0.008, 0.006, 0.0001, 0.0001, 0.039, 3.563, 2.668, 0.816, 0.0001, 0.001, 0.0001, 0.005, 0.003, 0.002, 0.002, 0.0001, 0.03, 0.013, 0.034, 0.014, 0.001, 0.0001, 0.001, 0.012, 0.005, 0.037, 0.126, 0.091, 0.007, 0.013, 0.003, 0.0001, 0.0001, 0.0001, 0.019, 0.012, 0.072, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "dsb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.783, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.853, 0.003, 0.608, 0.0001, 0.0001, 0.007, 0.002, 0.016, 0.311, 0.311, 0.022, 0.002, 0.839, 0.138, 1.194, 0.023, 0.287, 0.411, 0.214, 0.128, 0.124, 0.131, 0.109, 0.104, 0.125, 0.201, 0.084, 0.035, 0.006, 0.007, 0.007, 0.003, 0.0001, 0.155, 0.168, 0.123, 0.122, 0.077, 0.058, 0.102, 0.068, 0.054, 0.115, 0.164, 0.108, 0.197, 0.144, 0.038, 0.256, 0.004, 0.113, 0.246, 0.119, 0.042, 0.025, 0.244, 0.005, 0.007, 0.075, 0.008, 0.0001, 0.008, 0.0001, 0.002, 0.0001, 6.833, 1.047, 1.719, 1.818, 5.619, 0.234, 0.977, 0.835, 3.647, 3.795, 2.962, 1.965, 2.079, 4.006, 5.923, 1.615, 0.008, 3.224, 3.399, 2.803, 2.458, 0.071, 3.327, 0.021, 1.623, 1.195, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 0.148, 0.049, 0.931, 0.01, 0.22, 0.006, 0.005, 0.266, 0.005, 0.002, 0.002, 0.002, 0.017, 0.029, 0.002, 0.002, 0.007, 0.003, 0.004, 0.026, 0.004, 0.064, 0.004, 0.004, 0.009, 0.024, 0.008, 1.886, 0.043, 0.009, 0.04, 0.009, 0.064, 0.625, 0.008, 0.004, 0.017, 0.003, 0.003, 0.004, 0.006, 0.017, 0.003, 0.004, 0.001, 0.008, 0.001, 0.002, 0.019, 0.008, 0.014, 1.225, 0.005, 0.009, 0.011, 0.005, 0.012, 0.012, 0.395, 0.009, 0.027, 0.02, 0.616, 0.016, 0.0001, 0.0001, 0.039, 1.311, 1.431, 3.692, 0.0001, 0.0001, 0.001, 0.004, 0.001, 0.001, 0.001, 0.0001, 0.017, 0.009, 0.074, 0.029, 0.001, 0.0001, 0.0001, 0.002, 0.007, 0.043, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.012, 0.141, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "dty": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.724, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.716, 0.001, 0.019, 0.0001, 0.0001, 0.003, 0.0001, 0.008, 0.063, 0.066, 0.001, 0.0001, 0.189, 0.033, 0.052, 0.008, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.027, 0.004, 0.012, 0.001, 0.012, 0.001, 0.0001, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.017, 0.012, 0.004, 0.005, 0.014, 0.002, 0.003, 0.006, 0.016, 0.001, 0.004, 0.007, 0.008, 0.013, 0.011, 0.003, 0.0001, 0.019, 0.008, 0.009, 0.004, 0.001, 0.003, 0.0001, 0.003, 0.001, 0.0001, 0.015, 0.0001, 0.0001, 0.0001, 0.87, 0.744, 0.354, 0.069, 0.0001, 0.295, 0.114, 1.106, 0.404, 0.216, 0.006, 1.008, 0.08, 2.434, 0.0001, 0.171, 0.009, 0.001, 0.001, 0.025, 0.014, 1.53, 0.174, 0.539, 0.045, 0.068, 0.25, 0.269, 0.443, 0.023, 0.04, 0.304, 0.083, 0.214, 0.028, 0.182, 24.937, 7.5, 0.641, 0.298, 1.687, 0.033, 0.816, 0.129, 0.459, 0.371, 1.179, 1.062, 2.109, 0.002, 1.084, 0.0001, 0.0001, 0.578, 0.275, 0.191, 1.004, 0.659, 0.001, 0.0001, 0.01, 0.01, 3.197, 1.534, 0.0001, 0.0001, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.897, 0.0001, 0.034, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "dv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.449, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.782, 0.003, 0.057, 0.0001, 0.0001, 0.005, 0.0001, 0.005, 0.068, 0.068, 0.0001, 0.001, 0.01, 0.02, 0.58, 0.003, 0.08, 0.111, 0.068, 0.041, 0.031, 0.037, 0.03, 0.031, 0.035, 0.052, 0.01, 0.001, 0.003, 0.002, 0.003, 0.0001, 0.0001, 0.003, 0.001, 0.005, 0.002, 0.002, 0.002, 0.001, 0.003, 0.003, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.003, 0.0001, 0.002, 0.003, 0.005, 0.001, 0.001, 0.003, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.004, 0.0001, 0.069, 0.013, 0.026, 0.027, 0.096, 0.015, 0.017, 0.033, 0.065, 0.001, 0.006, 0.037, 0.021, 0.063, 0.061, 0.016, 0.001, 0.05, 0.05, 0.064, 0.025, 0.009, 0.011, 0.002, 0.014, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.961, 0.592, 2.65, 1.657, 0.723, 0.269, 1.597, 3.461, 1.72, 1.651, 0.757, 0.977, 1.223, 0.768, 1.538, 0.011, 0.778, 0.359, 0.094, 0.266, 0.255, 0.126, 0.187, 0.051, 0.006, 0.076, 0.047, 0.004, 0.004, 0.086, 0.041, 0.008, 0.02, 0.003, 0.091, 0.008, 0.069, 0.003, 5.331, 1.558, 2.986, 0.988, 3.164, 0.17, 3.662, 0.439, 0.51, 0.17, 3.636, 0.006, 0.014, 0.003, 0.002, 0.002, 0.001, 0.014, 0.001, 0.004, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.201, 0.101, 0.0001, 0.002, 0.0001, 0.0001, 45.417, 0.0001, 0.002, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.02, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "dz": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.39, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.815, 0.0001, 0.004, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.023, 0.023, 0.0001, 0.002, 0.003, 0.013, 0.008, 0.001, 0.017, 0.015, 0.012, 0.006, 0.005, 0.004, 0.005, 0.004, 0.004, 0.004, 0.001, 0.0001, 0.007, 0.0001, 0.007, 0.001, 0.0001, 0.002, 0.004, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.003, 0.001, 0.0001, 0.004, 0.0001, 0.002, 0.003, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.03, 0.011, 0.006, 0.008, 0.024, 0.002, 0.006, 0.009, 0.021, 0.002, 0.004, 0.014, 0.011, 0.019, 0.021, 0.004, 0.0001, 0.02, 0.011, 0.013, 0.01, 0.002, 0.002, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.269, 0.247, 1.794, 0.002, 1.18, 0.189, 0.19, 0.052, 0.002, 0.102, 0.016, 7.859, 0.051, 0.549, 0.008, 0.12, 0.301, 1.592, 0.28, 1.053, 0.694, 0.157, 1.278, 0.061, 0.824, 0.093, 0.2, 0.068, 0.006, 0.019, 0.267, 0.283, 0.898, 0.517, 1.238, 0.954, 0.214, 0.015, 2.251, 0.029, 0.117, 0.081, 0.001, 0.058, 0.0001, 0.012, 0.002, 0.0001, 0.002, 0.89, 2.149, 0.094, 1.08, 0.001, 0.0001, 0.053, 0.001, 0.0001, 0.926, 0.001, 10.076, 21.494, 2.583, 0.002, 0.0001, 0.0001, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 32.733, 0.0001, 0.016, 0.005, 0.001, 0.002, 0.002, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ee": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.047, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.659, 0.001, 0.347, 0.0001, 0.001, 0.004, 0.004, 0.044, 0.199, 0.199, 0.001, 0.0001, 0.713, 0.054, 1.348, 0.005, 0.312, 0.38, 0.219, 0.115, 0.09, 0.132, 0.118, 0.118, 0.109, 0.211, 0.064, 0.006, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.552, 0.172, 0.134, 0.182, 0.397, 0.085, 0.215, 0.112, 0.083, 0.04, 0.209, 0.217, 0.202, 0.168, 0.043, 0.117, 0.006, 0.112, 0.229, 0.176, 0.053, 0.059, 0.177, 0.021, 0.139, 0.02, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 7.214, 1.62, 0.258, 2.122, 10.212, 0.557, 1.427, 0.62, 4.11, 0.028, 2.137, 3.419, 2.267, 3.348, 4.663, 0.886, 0.007, 1.264, 2.303, 2.327, 2.541, 0.557, 2.031, 0.389, 1.697, 0.84, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.058, 0.011, 0.016, 0.109, 0.004, 0.002, 0.009, 0.001, 0.003, 0.01, 0.044, 0.61, 0.005, 0.002, 0.0001, 0.003, 0.018, 0.018, 1.229, 0.009, 2.883, 0.003, 1.23, 0.001, 0.002, 0.008, 0.003, 0.085, 0.02, 0.018, 0.001, 0.001, 0.052, 0.01, 0.004, 0.485, 0.002, 0.0001, 0.002, 0.004, 0.005, 0.042, 0.003, 0.002, 0.003, 0.025, 0.002, 0.002, 0.007, 0.009, 0.047, 0.01, 0.005, 0.003, 0.005, 0.003, 0.006, 0.005, 0.14, 0.007, 0.005, 0.138, 0.008, 0.004, 0.0001, 0.0001, 0.039, 0.487, 0.018, 0.548, 1.276, 0.0001, 0.004, 4.335, 0.128, 0.004, 0.106, 0.013, 0.028, 0.013, 0.041, 0.016, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.138, 0.051, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "eml": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.684, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.039, 0.004, 0.415, 0.0001, 0.0001, 0.004, 0.001, 1.632, 0.216, 0.216, 0.001, 0.001, 0.746, 0.069, 0.997, 0.011, 0.415, 0.659, 0.408, 0.216, 0.231, 0.235, 0.226, 0.213, 0.215, 0.256, 0.061, 0.026, 0.05, 0.006, 0.05, 0.003, 0.0001, 0.44, 0.139, 0.4, 0.112, 0.078, 0.095, 0.114, 0.018, 0.424, 0.019, 0.012, 0.251, 0.226, 0.059, 0.026, 0.233, 0.016, 0.153, 0.231, 0.099, 0.036, 0.164, 0.011, 0.127, 0.003, 0.015, 0.004, 0.0001, 0.004, 0.0001, 0.002, 0.0001, 7.63, 0.549, 2.301, 3.601, 3.529, 0.617, 1.263, 0.808, 5.22, 0.113, 0.052, 4.92, 1.657, 5.406, 1.72, 1.353, 0.118, 3.957, 2.689, 3.146, 2.026, 0.904, 0.024, 0.02, 0.047, 0.34, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.239, 0.003, 0.006, 0.003, 0.004, 0.052, 0.002, 0.003, 0.008, 0.003, 0.006, 0.001, 0.002, 0.193, 0.002, 0.001, 0.002, 0.002, 0.003, 0.098, 0.002, 0.001, 0.001, 0.001, 0.033, 0.188, 0.003, 0.047, 0.006, 0.006, 0.001, 0.078, 0.562, 0.025, 0.617, 0.129, 0.182, 0.072, 0.003, 0.005, 1.444, 0.829, 0.895, 0.057, 0.235, 0.011, 0.346, 0.001, 0.004, 0.003, 0.664, 0.345, 0.314, 0.007, 0.019, 0.001, 0.003, 0.275, 0.004, 0.186, 0.062, 0.002, 0.002, 0.006, 0.0001, 0.0001, 0.011, 6.936, 0.1, 0.325, 0.0001, 0.004, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.003, 0.002, 0.007, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.192, 0.237, 0.003, 0.002, 0.005, 0.003, 0.003, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "eo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.154, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.737, 0.006, 0.429, 0.0001, 0.0001, 0.01, 0.001, 0.015, 0.235, 0.235, 0.001, 0.003, 0.936, 0.306, 0.916, 0.015, 0.284, 0.481, 0.226, 0.14, 0.134, 0.143, 0.121, 0.123, 0.155, 0.273, 0.072, 0.027, 0.012, 0.007, 0.013, 0.002, 0.0001, 0.209, 0.154, 0.114, 0.106, 0.232, 0.094, 0.127, 0.102, 0.106, 0.077, 0.183, 0.354, 0.184, 0.118, 0.083, 0.187, 0.004, 0.116, 0.241, 0.149, 0.061, 0.074, 0.035, 0.004, 0.009, 0.024, 0.021, 0.0001, 0.021, 0.0001, 0.004, 0.0001, 9.544, 0.784, 0.841, 2.534, 6.934, 0.706, 0.989, 0.423, 6.212, 2.407, 2.868, 4.302, 1.963, 5.456, 7.143, 1.699, 0.009, 4.617, 4.113, 4.222, 2.31, 1.083, 0.045, 0.017, 0.108, 0.46, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.058, 0.01, 0.009, 0.008, 0.004, 0.004, 0.002, 0.003, 0.037, 0.239, 0.001, 0.001, 0.004, 0.007, 0.001, 0.002, 0.002, 0.007, 0.002, 0.018, 0.008, 0.001, 0.002, 0.002, 0.002, 0.012, 0.003, 0.005, 0.093, 0.609, 0.008, 0.005, 0.021, 0.066, 0.005, 0.003, 0.01, 0.029, 0.002, 0.005, 0.005, 0.035, 0.002, 0.007, 0.002, 0.34, 0.001, 0.002, 0.012, 0.007, 0.011, 0.025, 0.006, 0.093, 0.016, 0.003, 0.007, 0.003, 0.008, 0.009, 0.016, 0.009, 0.009, 0.003, 0.0001, 0.0001, 0.038, 0.2, 0.946, 0.502, 0.0001, 0.001, 0.005, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.012, 0.006, 0.045, 0.015, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.003, 0.006, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.056, 0.002, 0.001, 0.003, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "eu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.418, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.177, 0.001, 0.297, 0.0001, 0.0001, 0.006, 0.001, 0.01, 0.167, 0.167, 0.0001, 0.001, 1.097, 0.307, 1.039, 0.006, 0.582, 0.665, 0.539, 0.263, 0.232, 0.207, 0.196, 0.233, 0.193, 0.297, 0.077, 0.037, 0.019, 0.004, 0.019, 0.001, 0.0001, 0.228, 0.197, 0.105, 0.074, 0.177, 0.09, 0.111, 0.131, 0.123, 0.048, 0.077, 0.106, 0.134, 0.065, 0.059, 0.121, 0.005, 0.05, 0.134, 0.08, 0.034, 0.046, 0.019, 0.022, 0.008, 0.029, 0.005, 0.0001, 0.005, 0.0001, 0.002, 0.0001, 11.924, 1.97, 0.229, 2.409, 9.817, 0.3, 1.545, 0.915, 6.874, 0.162, 4.015, 2.508, 1.08, 6.457, 4.385, 0.883, 0.011, 6.261, 2.025, 5.706, 3.55, 0.077, 0.032, 0.337, 0.117, 3.463, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.014, 0.003, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.003, 0.003, 0.0001, 0.001, 0.008, 0.009, 0.002, 0.002, 0.004, 0.001, 0.001, 0.003, 0.009, 0.023, 0.001, 0.012, 0.001, 0.01, 0.001, 0.001, 0.003, 0.012, 0.007, 0.008, 0.006, 0.001, 0.003, 0.001, 0.002, 0.001, 0.004, 0.012, 0.004, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.039, 0.094, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.003, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.013, 0.001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ext": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.183, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.144, 0.002, 0.474, 0.0001, 0.0001, 0.008, 0.001, 0.271, 0.191, 0.19, 0.004, 0.002, 1.06, 0.101, 0.854, 0.021, 0.249, 0.293, 0.188, 0.105, 0.088, 0.096, 0.085, 0.084, 0.099, 0.161, 0.072, 0.026, 0.008, 0.003, 0.006, 0.002, 0.0001, 0.241, 0.103, 0.248, 0.095, 0.369, 0.065, 0.091, 0.071, 0.128, 0.047, 0.018, 0.238, 0.161, 0.09, 0.062, 0.171, 0.026, 0.094, 0.188, 0.116, 0.077, 0.083, 0.02, 0.035, 0.009, 0.011, 0.028, 0.0001, 0.029, 0.0001, 0.001, 0.002, 8.822, 0.896, 2.974, 2.338, 7.586, 0.409, 0.951, 0.639, 6.63, 0.18, 0.079, 4.794, 1.966, 5.508, 3.713, 1.742, 0.451, 4.358, 5.625, 3.427, 5.456, 0.664, 0.026, 0.047, 0.265, 0.205, 0.0001, 0.012, 0.0001, 0.001, 0.0001, 0.09, 0.042, 0.016, 0.012, 0.021, 0.01, 0.009, 0.007, 0.019, 0.01, 0.009, 0.002, 0.007, 0.012, 0.003, 0.002, 0.01, 0.006, 0.003, 0.011, 0.012, 0.003, 0.002, 0.002, 0.004, 0.049, 0.003, 0.005, 0.01, 0.009, 0.003, 0.003, 0.02, 0.663, 0.003, 0.009, 0.008, 0.004, 0.004, 0.092, 0.006, 0.332, 0.01, 0.012, 0.009, 0.354, 0.005, 0.01, 0.016, 0.295, 0.019, 0.537, 0.024, 0.015, 0.008, 0.008, 0.011, 0.017, 0.174, 0.02, 0.041, 0.023, 0.01, 0.023, 0.0001, 0.0001, 0.078, 2.453, 0.012, 0.009, 0.0001, 0.0001, 0.0001, 0.019, 0.008, 0.025, 0.005, 0.0001, 0.151, 0.073, 0.021, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.034, 0.026, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.021, 0.082, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ff": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.229, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.756, 0.003, 0.154, 0.0001, 0.0001, 0.002, 0.0001, 0.07, 0.321, 0.324, 0.004, 0.001, 1.19, 0.201, 1.011, 0.039, 0.221, 0.281, 0.197, 0.076, 0.082, 0.099, 0.098, 0.084, 0.101, 0.154, 0.153, 0.028, 0.04, 0.008, 0.04, 0.01, 0.0001, 0.371, 0.159, 0.12, 0.097, 0.095, 0.198, 0.111, 0.12, 0.065, 0.102, 0.267, 0.138, 0.299, 0.201, 0.095, 0.085, 0.014, 0.046, 0.262, 0.159, 0.061, 0.013, 0.059, 0.003, 0.066, 0.008, 0.007, 0.0001, 0.007, 0.0001, 0.006, 0.0001, 10.449, 0.928, 0.343, 3.119, 8.063, 0.727, 1.432, 1.127, 6.432, 0.966, 2.387, 3.274, 2.586, 6.222, 6.89, 0.484, 0.058, 2.623, 1.086, 2.251, 3.239, 0.048, 1.581, 0.013, 1.385, 0.042, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.25, 0.043, 0.0001, 0.008, 0.007, 0.001, 0.007, 0.002, 0.023, 0.003, 0.031, 0.086, 0.001, 0.0001, 0.009, 0.005, 0.007, 0.017, 0.003, 1.378, 0.001, 0.001, 0.0001, 1.485, 0.01, 0.123, 0.001, 0.002, 0.036, 0.035, 0.003, 0.0001, 0.06, 0.009, 0.0001, 0.003, 0.0001, 0.002, 0.02, 0.011, 0.007, 0.04, 0.001, 0.024, 0.001, 0.003, 0.0001, 0.0001, 0.006, 0.154, 0.006, 0.01, 0.135, 0.002, 0.002, 0.009, 0.004, 0.002, 0.004, 0.025, 0.02, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.111, 0.229, 0.005, 0.088, 0.202, 0.0001, 0.0001, 2.86, 0.02, 0.001, 0.001, 0.0001, 0.003, 0.0001, 0.017, 0.011, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.023, 0.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.248, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fj": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.647, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.11, 0.005, 0.222, 0.0001, 0.0001, 0.0001, 0.002, 0.182, 0.39, 0.39, 0.002, 0.003, 0.665, 0.202, 1.418, 0.055, 0.382, 0.504, 0.342, 0.179, 0.168, 0.196, 0.159, 0.133, 0.129, 0.164, 0.07, 0.04, 0.02, 0.002, 0.02, 0.013, 0.002, 0.352, 0.212, 0.246, 0.146, 0.319, 0.066, 0.096, 0.061, 0.166, 0.217, 0.277, 0.179, 0.262, 0.29, 0.095, 0.254, 0.022, 0.118, 0.377, 0.355, 0.066, 0.534, 0.043, 0.003, 0.05, 0.01, 0.0001, 0.0001, 0.005, 0.0001, 0.008, 0.0001, 13.891, 0.708, 1.055, 1.505, 4.909, 0.352, 0.936, 0.685, 8.96, 0.075, 2.998, 2.827, 2.182, 5.506, 3.831, 0.546, 0.257, 2.747, 2.722, 3.592, 4.532, 2.046, 0.526, 0.045, 0.71, 0.111, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.267, 0.01, 0.007, 0.005, 0.007, 0.002, 0.0001, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.008, 0.0001, 0.0001, 0.013, 0.192, 0.0001, 0.003, 0.002, 0.0001, 0.008, 0.002, 0.0001, 0.023, 0.022, 0.002, 0.0001, 0.007, 0.005, 0.0001, 0.01, 0.003, 0.0001, 0.002, 0.005, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.01, 0.0001, 0.0001, 0.008, 0.0001, 0.003, 0.022, 0.003, 0.002, 0.005, 0.0001, 0.008, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.013, 0.065, 0.0001, 0.023, 0.002, 0.0001, 0.0001, 0.013, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.002, 0.01, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.26, 0.0001, 0.003, 0.002, 0.0001, 0.003, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.171, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.257, 0.003, 0.223, 0.0001, 0.0001, 0.01, 0.002, 0.015, 0.14, 0.141, 0.001, 0.001, 0.983, 0.292, 1.473, 0.021, 0.562, 0.624, 0.361, 0.197, 0.187, 0.183, 0.177, 0.172, 0.176, 0.285, 0.092, 0.018, 0.015, 0.005, 0.015, 0.002, 0.0001, 0.162, 0.14, 0.076, 0.088, 0.116, 0.204, 0.083, 0.244, 0.058, 0.087, 0.291, 0.108, 0.161, 0.114, 0.065, 0.092, 0.004, 0.082, 0.312, 0.204, 0.061, 0.078, 0.034, 0.003, 0.012, 0.006, 0.004, 0.0001, 0.004, 0.0001, 0.002, 0.0001, 6.488, 0.752, 0.145, 1.557, 3.939, 1.383, 2.415, 1.123, 6.407, 0.628, 2.151, 3.099, 2.563, 5.616, 2.172, 0.663, 0.005, 6.541, 3.536, 4.094, 3.571, 2.164, 0.044, 0.017, 0.862, 0.025, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.054, 0.049, 0.002, 0.002, 0.002, 0.004, 0.003, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.091, 0.001, 0.001, 0.001, 0.001, 0.001, 0.033, 0.002, 0.001, 0.002, 0.001, 0.017, 0.004, 0.006, 0.001, 0.006, 0.009, 0.001, 0.001, 0.01, 0.939, 0.001, 0.001, 0.016, 0.008, 0.277, 0.003, 0.006, 0.007, 0.001, 0.002, 0.001, 1.13, 0.001, 0.004, 1.899, 0.003, 0.003, 0.718, 0.002, 0.002, 0.014, 0.001, 0.801, 0.002, 0.333, 0.003, 0.004, 0.203, 0.003, 0.002, 0.0001, 0.0001, 0.022, 6.504, 0.004, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.012, 0.005, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.004, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.053, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "frp": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.788, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.014, 0.012, 0.659, 0.001, 0.0001, 0.001, 0.001, 0.361, 0.368, 0.368, 0.001, 0.0001, 0.743, 0.467, 0.873, 0.02, 0.214, 0.426, 0.274, 0.128, 0.113, 0.117, 0.113, 0.107, 0.116, 0.228, 0.11, 0.019, 0.081, 0.005, 0.081, 0.002, 0.0001, 0.35, 0.279, 0.333, 0.142, 0.141, 0.152, 0.135, 0.066, 0.159, 0.087, 0.033, 0.593, 0.22, 0.099, 0.082, 0.206, 0.019, 0.236, 0.314, 0.121, 0.062, 0.179, 0.013, 0.025, 0.027, 0.009, 0.022, 0.0001, 0.022, 0.0001, 0.006, 0.0001, 6.3, 0.639, 2.237, 2.924, 6.953, 0.549, 0.996, 0.581, 3.639, 0.252, 0.124, 3.838, 1.505, 5.552, 4.982, 1.442, 0.366, 4.363, 4.487, 4.4, 2.763, 0.919, 0.029, 0.168, 0.501, 0.132, 0.0001, 0.008, 0.0001, 0.001, 0.0001, 0.591, 0.012, 0.04, 0.026, 0.003, 0.003, 0.002, 0.002, 0.077, 0.083, 0.002, 0.003, 0.004, 0.003, 0.002, 0.005, 0.007, 0.003, 0.002, 0.023, 0.039, 0.002, 0.001, 0.002, 0.013, 0.56, 0.002, 0.002, 0.004, 0.004, 0.002, 0.004, 0.079, 0.014, 0.761, 0.004, 0.005, 0.003, 0.004, 0.044, 1.724, 0.994, 0.451, 0.049, 0.014, 0.007, 0.008, 0.004, 0.024, 0.005, 0.02, 0.03, 0.411, 0.012, 0.002, 0.176, 0.006, 0.01, 0.014, 0.089, 0.007, 0.007, 0.007, 0.005, 0.0001, 0.0001, 0.277, 4.789, 0.008, 0.018, 0.001, 0.0001, 0.0001, 0.008, 0.004, 0.004, 0.003, 0.001, 0.014, 0.004, 0.075, 0.032, 0.0001, 0.0001, 0.001, 0.005, 0.001, 0.004, 0.007, 0.005, 0.0001, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.004, 0.024, 0.586, 0.003, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "frr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.212, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.548, 0.003, 0.682, 0.0001, 0.001, 0.008, 0.0001, 0.237, 0.407, 0.407, 0.015, 0.002, 0.738, 0.264, 1.349, 0.032, 0.426, 0.487, 0.285, 0.155, 0.131, 0.142, 0.153, 0.132, 0.154, 0.213, 0.163, 0.033, 0.094, 0.019, 0.094, 0.014, 0.0001, 0.424, 0.235, 0.114, 0.463, 0.142, 0.219, 0.132, 0.243, 0.123, 0.143, 0.217, 0.156, 0.239, 0.202, 0.1, 0.178, 0.008, 0.163, 0.493, 0.169, 0.107, 0.04, 0.158, 0.005, 0.006, 0.018, 0.02, 0.0001, 0.02, 0.0001, 0.015, 0.0001, 7.38, 1.026, 0.694, 2.643, 7.751, 1.48, 1.329, 1.414, 5.143, 0.835, 1.946, 2.506, 1.658, 6.635, 2.847, 0.757, 0.017, 4.866, 3.953, 4.835, 3.559, 0.125, 1.078, 0.025, 0.13, 0.078, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.121, 0.04, 0.005, 0.007, 0.011, 0.01, 0.004, 0.003, 0.014, 0.003, 0.007, 0.003, 0.003, 0.004, 0.004, 0.002, 0.006, 0.041, 0.003, 0.029, 0.004, 0.002, 0.039, 0.002, 0.005, 0.057, 0.003, 0.003, 0.033, 0.001, 0.015, 0.005, 0.043, 0.01, 0.008, 0.004, 0.702, 0.24, 0.006, 0.008, 0.007, 0.041, 0.006, 0.01, 0.003, 0.013, 0.002, 0.004, 0.015, 0.008, 0.014, 0.009, 0.006, 0.008, 0.971, 0.003, 0.022, 0.007, 0.006, 0.005, 0.964, 0.005, 0.004, 0.003, 0.0001, 0.0001, 0.041, 3.039, 0.101, 0.012, 0.0001, 0.001, 0.0001, 0.016, 0.008, 0.014, 0.003, 0.0001, 0.014, 0.006, 0.019, 0.007, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.018, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.024, 0.122, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fur": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.465, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.803, 0.002, 0.385, 0.0001, 0.0001, 0.006, 0.001, 0.135, 0.204, 0.203, 0.001, 0.001, 0.945, 0.084, 1.045, 0.015, 0.262, 0.474, 0.24, 0.16, 0.15, 0.158, 0.149, 0.15, 0.168, 0.219, 0.076, 0.046, 0.024, 0.003, 0.006, 0.002, 0.0001, 0.268, 0.102, 0.337, 0.116, 0.078, 0.115, 0.121, 0.022, 0.278, 0.048, 0.02, 0.218, 0.154, 0.07, 0.05, 0.172, 0.005, 0.086, 0.217, 0.131, 0.073, 0.108, 0.016, 0.024, 0.002, 0.027, 0.004, 0.001, 0.004, 0.0001, 0.016, 0.0001, 6.873, 0.54, 3.119, 3.521, 7.672, 0.855, 0.912, 0.901, 8.131, 0.838, 0.065, 4.486, 1.745, 5.361, 3.491, 1.873, 0.016, 4.269, 4.833, 4.488, 2.566, 1.056, 0.024, 0.012, 0.029, 0.497, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.039, 0.005, 0.002, 0.002, 0.002, 0.001, 0.001, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.007, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.013, 0.0001, 0.001, 0.008, 0.008, 0.0001, 0.002, 0.187, 0.005, 0.973, 0.001, 0.004, 0.001, 0.001, 0.127, 0.268, 0.009, 0.161, 0.005, 0.069, 0.003, 0.185, 0.001, 0.033, 0.003, 0.05, 0.006, 0.254, 0.001, 0.005, 0.001, 0.001, 0.015, 0.003, 0.208, 0.005, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.042, 2.523, 0.01, 0.009, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.01, 0.005, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.038, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "fy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.82, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.701, 0.001, 0.398, 0.0001, 0.001, 0.014, 0.003, 0.455, 0.166, 0.166, 0.001, 0.0001, 0.747, 0.192, 0.908, 0.008, 0.277, 0.415, 0.181, 0.098, 0.101, 0.113, 0.107, 0.108, 0.145, 0.219, 0.052, 0.025, 0.005, 0.001, 0.005, 0.002, 0.0001, 0.213, 0.183, 0.091, 0.343, 0.093, 0.196, 0.109, 0.18, 0.193, 0.088, 0.132, 0.122, 0.161, 0.156, 0.11, 0.106, 0.003, 0.108, 0.302, 0.13, 0.038, 0.048, 0.113, 0.006, 0.12, 0.009, 0.007, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 6.027, 1.091, 0.691, 3.439, 11.73, 1.889, 1.306, 1.373, 5.412, 1.009, 2.464, 2.808, 1.837, 7.368, 3.471, 1.074, 0.006, 5.381, 4.264, 5.226, 1.268, 0.226, 1.241, 0.017, 1.595, 0.254, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.043, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.007, 0.001, 0.0001, 0.001, 0.001, 0.004, 0.021, 0.0001, 0.001, 0.004, 0.003, 0.001, 0.001, 0.013, 0.004, 0.263, 0.001, 0.008, 0.001, 0.001, 0.002, 0.002, 0.01, 0.258, 0.016, 0.001, 0.003, 0.001, 0.013, 0.005, 0.004, 0.006, 0.003, 0.084, 0.002, 0.006, 0.001, 0.003, 0.002, 0.21, 0.348, 0.006, 0.003, 0.002, 0.001, 0.0001, 0.0001, 0.02, 1.229, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.006, 0.003, 0.015, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.042, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ga": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.234, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.249, 0.002, 0.288, 0.0001, 0.001, 0.013, 0.002, 0.109, 0.15, 0.15, 0.0001, 0.002, 0.872, 0.193, 0.872, 0.017, 0.241, 0.359, 0.187, 0.093, 0.09, 0.096, 0.095, 0.093, 0.117, 0.202, 0.044, 0.013, 0.002, 0.003, 0.002, 0.002, 0.0001, 0.26, 0.338, 0.441, 0.188, 0.097, 0.15, 0.18, 0.066, 0.279, 0.041, 0.036, 0.154, 0.249, 0.121, 0.062, 0.138, 0.005, 0.145, 0.311, 0.272, 0.036, 0.033, 0.04, 0.007, 0.009, 0.007, 0.033, 0.0001, 0.031, 0.0001, 0.002, 0.0001, 11.315, 1.29, 2.859, 2.236, 4.184, 0.692, 2.117, 5.503, 7.212, 0.011, 0.093, 2.991, 1.605, 6.018, 2.868, 0.471, 0.007, 4.409, 3.653, 3.32, 1.715, 0.088, 0.061, 0.021, 0.135, 0.028, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.063, 0.032, 0.004, 0.003, 0.002, 0.001, 0.001, 0.002, 0.002, 0.059, 0.001, 0.002, 0.002, 0.009, 0.001, 0.001, 0.001, 0.001, 0.001, 0.044, 0.003, 0.001, 0.001, 0.001, 0.005, 0.023, 0.008, 0.001, 0.006, 0.006, 0.0001, 0.001, 0.02, 1.278, 0.008, 0.002, 0.005, 0.001, 0.001, 0.002, 0.002, 1.021, 0.001, 0.002, 0.002, 1.343, 0.001, 0.001, 0.006, 0.004, 0.004, 0.674, 0.002, 0.003, 0.005, 0.001, 0.004, 0.002, 0.624, 0.002, 0.005, 0.004, 0.003, 0.002, 0.0001, 0.0001, 0.022, 5.087, 0.004, 0.005, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.011, 0.005, 0.021, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.061, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gag": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.391, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.28, 0.016, 0.1, 0.0001, 0.001, 0.011, 0.0001, 0.023, 0.153, 0.154, 0.0001, 0.0001, 0.918, 0.454, 1.065, 0.029, 0.183, 0.22, 0.131, 0.062, 0.067, 0.072, 0.06, 0.06, 0.062, 0.143, 0.13, 0.023, 0.015, 0.004, 0.015, 0.028, 0.0001, 0.378, 0.403, 0.048, 0.156, 0.135, 0.049, 0.237, 0.117, 0.049, 0.029, 0.415, 0.105, 0.242, 0.108, 0.187, 0.134, 0.003, 0.159, 0.189, 0.383, 0.092, 0.136, 0.005, 0.011, 0.079, 0.04, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 9.932, 1.463, 0.503, 2.949, 4.34, 0.314, 1.11, 0.547, 5.816, 0.052, 2.859, 4.285, 1.983, 5.174, 2.034, 0.659, 0.007, 5.297, 2.304, 2.138, 2.154, 0.741, 0.006, 0.007, 1.825, 1.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.33, 0.02, 0.014, 0.017, 0.012, 0.006, 0.003, 0.09, 0.004, 0.002, 0.005, 0.006, 0.005, 0.012, 0.002, 0.007, 0.002, 0.004, 0.002, 0.034, 0.066, 0.003, 0.036, 0.002, 0.004, 0.038, 0.004, 0.03, 0.138, 0.106, 0.046, 1.073, 0.005, 0.011, 0.07, 0.054, 1.028, 0.001, 0.006, 0.629, 0.003, 0.006, 0.12, 0.006, 0.002, 0.001, 0.004, 0.003, 0.193, 2.957, 0.016, 0.012, 0.008, 0.03, 0.347, 0.009, 0.023, 0.005, 0.018, 0.016, 1.278, 0.014, 0.03, 0.005, 0.0001, 0.0001, 0.012, 3.601, 3.155, 1.149, 0.001, 0.0001, 0.029, 0.03, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.224, 0.106, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.003, 0.019, 0.015, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.005, 0.317, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gan": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.76, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.481, 0.002, 0.018, 0.0001, 0.0001, 0.024, 0.003, 0.008, 0.023, 0.024, 0.002, 0.006, 0.023, 0.038, 0.047, 0.01, 0.315, 0.585, 0.297, 0.204, 0.191, 0.202, 0.185, 0.171, 0.182, 0.259, 0.005, 0.001, 0.007, 0.003, 0.007, 0.002, 0.0001, 0.033, 0.019, 0.032, 0.016, 0.012, 0.012, 0.016, 0.021, 0.015, 0.011, 0.012, 0.015, 0.023, 0.016, 0.01, 0.022, 0.002, 0.018, 0.031, 0.022, 0.006, 0.009, 0.014, 0.002, 0.005, 0.001, 0.008, 0.001, 0.008, 0.0001, 0.002, 0.0001, 0.219, 0.03, 0.061, 0.069, 0.246, 0.023, 0.046, 0.084, 0.187, 0.005, 0.034, 0.116, 0.064, 0.184, 0.17, 0.035, 0.003, 0.158, 0.115, 0.138, 0.085, 0.023, 0.019, 0.007, 0.04, 0.007, 0.001, 0.001, 0.001, 0.0001, 0.0001, 3.244, 1.279, 2.127, 0.643, 0.387, 0.883, 0.435, 0.848, 1.431, 1.201, 0.629, 1.296, 2.258, 1.163, 0.623, 0.808, 0.937, 0.395, 0.26, 0.593, 0.667, 0.608, 1.031, 1.999, 0.578, 0.845, 0.936, 0.665, 1.536, 0.644, 0.439, 0.928, 0.498, 0.603, 0.631, 0.704, 0.585, 0.768, 0.515, 0.538, 0.76, 0.649, 0.365, 0.712, 0.597, 1.095, 0.882, 0.565, 2.328, 1.119, 0.438, 0.543, 1.012, 0.372, 0.441, 0.708, 1.829, 1.205, 1.47, 1.203, 2.219, 1.044, 0.843, 1.251, 0.0001, 0.0001, 0.055, 0.02, 0.005, 0.006, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.0001, 0.018, 0.009, 0.031, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.007, 0.036, 0.032, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.029, 0.011, 0.055, 2.062, 3.549, 9.312, 4.838, 3.056, 2.889, 2.67, 0.003, 0.005, 0.013, 0.003, 0.002, 1.772, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gd": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.483, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.829, 0.001, 0.374, 0.0001, 0.0001, 0.027, 0.001, 0.653, 0.225, 0.224, 0.001, 0.001, 0.74, 0.732, 0.959, 0.016, 0.275, 0.512, 0.251, 0.163, 0.143, 0.16, 0.146, 0.151, 0.187, 0.234, 0.126, 0.023, 0.004, 0.003, 0.004, 0.002, 0.0001, 0.399, 0.354, 0.494, 0.195, 0.121, 0.114, 0.226, 0.061, 0.158, 0.033, 0.034, 0.204, 0.239, 0.107, 0.062, 0.151, 0.004, 0.164, 0.477, 0.402, 0.038, 0.033, 0.037, 0.023, 0.009, 0.008, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.001, 13.191, 1.481, 2.674, 2.933, 4.722, 0.55, 2.044, 6.832, 6.396, 0.019, 0.13, 2.757, 1.684, 7.147, 2.433, 0.32, 0.014, 3.962, 3.004, 2.554, 2.054, 0.073, 0.068, 0.016, 0.125, 0.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.262, 0.013, 0.005, 0.005, 0.004, 0.003, 0.002, 0.002, 0.031, 0.005, 0.004, 0.001, 0.011, 0.003, 0.002, 0.001, 0.006, 0.003, 0.012, 0.014, 0.004, 0.002, 0.002, 0.002, 0.027, 0.178, 0.003, 0.005, 0.012, 0.011, 0.001, 0.003, 0.677, 0.029, 0.002, 0.003, 0.009, 0.003, 0.004, 0.005, 0.218, 0.029, 0.004, 0.003, 0.303, 0.022, 0.002, 0.003, 0.018, 0.008, 0.323, 0.026, 0.004, 0.004, 0.01, 0.002, 0.006, 0.223, 0.01, 0.003, 0.014, 0.004, 0.005, 0.002, 0.0001, 0.0001, 0.041, 1.912, 0.009, 0.011, 0.0001, 0.0001, 0.0001, 0.018, 0.01, 0.015, 0.003, 0.0001, 0.015, 0.007, 0.02, 0.006, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.008, 0.009, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.004, 0.244, 0.002, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.812, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.39, 0.002, 0.342, 0.0001, 0.0001, 0.01, 0.001, 0.013, 0.144, 0.144, 0.001, 0.002, 1.02, 0.075, 0.726, 0.01, 0.251, 0.326, 0.181, 0.093, 0.083, 0.092, 0.082, 0.082, 0.102, 0.185, 0.047, 0.021, 0.003, 0.002, 0.002, 0.001, 0.0001, 0.331, 0.122, 0.257, 0.114, 0.192, 0.107, 0.104, 0.065, 0.139, 0.039, 0.03, 0.104, 0.167, 0.127, 0.177, 0.186, 0.007, 0.111, 0.187, 0.12, 0.054, 0.074, 0.026, 0.055, 0.009, 0.01, 0.005, 0.0001, 0.005, 0.0001, 0.003, 0.0001, 9.121, 0.85, 3.271, 4.11, 8.668, 0.721, 0.784, 0.524, 5.185, 0.017, 0.092, 2.548, 2.069, 5.528, 7.673, 1.889, 0.464, 5.046, 5.357, 3.627, 2.8, 0.704, 0.036, 0.564, 0.085, 0.291, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.015, 0.013, 0.003, 0.002, 0.002, 0.001, 0.002, 0.002, 0.001, 0.012, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.006, 0.003, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.003, 0.003, 0.0001, 0.001, 0.028, 0.396, 0.001, 0.002, 0.002, 0.001, 0.001, 0.003, 0.003, 0.383, 0.003, 0.007, 0.001, 0.442, 0.001, 0.001, 0.005, 0.193, 0.006, 0.599, 0.002, 0.002, 0.003, 0.001, 0.003, 0.002, 0.219, 0.007, 0.008, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.05, 2.267, 0.004, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.011, 0.005, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.014, 0.003, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "glk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.405, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.911, 0.005, 0.048, 0.0001, 0.0001, 0.001, 0.0001, 0.017, 0.104, 0.105, 0.0001, 0.001, 0.019, 0.086, 0.553, 0.019, 0.043, 0.074, 0.037, 0.051, 0.028, 0.037, 0.027, 0.021, 0.025, 0.021, 0.078, 0.0001, 0.005, 0.006, 0.007, 0.001, 0.0001, 0.004, 0.003, 0.008, 0.003, 0.003, 0.002, 0.002, 0.002, 0.003, 0.001, 0.001, 0.002, 0.004, 0.002, 0.001, 0.003, 0.0001, 0.003, 0.005, 0.008, 0.006, 0.001, 0.002, 0.0001, 0.001, 0.001, 0.003, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.177, 0.041, 0.015, 0.061, 0.102, 0.013, 0.028, 0.036, 0.115, 0.015, 0.035, 0.047, 0.057, 0.128, 0.083, 0.024, 0.008, 0.098, 0.063, 0.07, 0.058, 0.027, 0.009, 0.013, 0.021, 0.022, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.159, 0.386, 0.313, 0.148, 1.28, 2.09, 3.65, 3.311, 2.644, 0.084, 1.185, 0.003, 3.768, 0.001, 0.042, 0.015, 0.057, 0.007, 0.001, 0.006, 0.005, 0.0001, 0.0001, 0.0001, 0.027, 0.07, 0.004, 0.009, 0.002, 0.001, 0.0001, 0.024, 0.001, 0.005, 0.174, 0.185, 0.526, 0.0001, 0.349, 5.779, 1.561, 0.992, 2.058, 0.045, 0.725, 0.235, 0.5, 2.399, 0.083, 3.048, 0.622, 2.068, 1.214, 0.15, 0.072, 0.14, 0.046, 0.343, 0.079, 0.014, 0.001, 0.0001, 0.271, 0.0001, 0.0001, 0.0001, 0.044, 0.065, 0.002, 0.021, 0.0001, 0.003, 0.0001, 0.068, 0.0001, 0.285, 0.001, 0.0001, 0.001, 0.0001, 0.005, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 21.901, 14.77, 1.833, 3.683, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.141, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.37, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.685, 0.002, 0.175, 0.0001, 0.0001, 0.007, 0.0001, 0.625, 0.171, 0.173, 0.001, 0.002, 1.108, 0.288, 0.925, 0.011, 0.221, 0.306, 0.165, 0.094, 0.084, 0.088, 0.078, 0.08, 0.105, 0.172, 0.107, 0.053, 0.096, 0.001, 0.096, 0.001, 0.0001, 0.314, 0.094, 0.194, 0.053, 0.124, 0.074, 0.125, 0.128, 0.14, 0.097, 0.171, 0.086, 0.202, 0.077, 0.188, 0.312, 0.005, 0.119, 0.136, 0.188, 0.098, 0.072, 0.01, 0.015, 0.073, 0.005, 0.013, 0.0001, 0.013, 0.0001, 0.0001, 0.003, 10.368, 1.134, 1.037, 1.076, 7.653, 0.097, 1.575, 2.931, 4.208, 1.013, 1.951, 0.867, 2.302, 2.015, 5.216, 3.17, 0.036, 4.342, 1.438, 2.887, 4.01, 2.242, 0.013, 0.023, 2.052, 0.103, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 1.036, 0.019, 0.002, 0.069, 0.003, 0.001, 0.001, 0.001, 0.002, 0.002, 0.001, 0.003, 0.001, 0.004, 0.0001, 0.001, 0.002, 0.06, 0.001, 0.011, 0.003, 0.002, 0.001, 0.001, 0.002, 0.862, 0.001, 0.001, 0.08, 0.08, 0.0001, 0.001, 0.04, 0.787, 0.003, 0.72, 0.019, 0.002, 0.003, 0.003, 0.016, 1.383, 0.003, 0.016, 0.003, 0.256, 0.002, 0.013, 0.007, 0.786, 0.011, 0.399, 0.027, 0.172, 0.004, 0.001, 0.003, 0.065, 0.529, 0.066, 0.013, 0.527, 0.003, 0.003, 0.0001, 0.0001, 0.078, 4.545, 0.392, 0.1, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.002, 0.065, 0.0001, 0.004, 0.002, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.015, 0.405, 1.034, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gom": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.459, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.409, 0.004, 0.032, 0.0001, 0.0001, 0.004, 0.001, 0.065, 0.082, 0.086, 0.0001, 0.001, 0.31, 0.092, 0.614, 0.025, 0.037, 0.076, 0.035, 0.025, 0.021, 0.026, 0.02, 0.018, 0.022, 0.033, 0.044, 0.02, 0.0001, 0.003, 0.0001, 0.007, 0.0001, 0.043, 0.023, 0.024, 0.027, 0.017, 0.011, 0.022, 0.028, 0.023, 0.016, 0.018, 0.014, 0.036, 0.017, 0.018, 0.033, 0.001, 0.019, 0.035, 0.046, 0.011, 0.011, 0.005, 0.004, 0.003, 0.004, 0.001, 0.0001, 0.001, 0.0001, 0.007, 0.001, 1.398, 0.134, 0.264, 0.41, 0.83, 0.062, 0.182, 0.613, 0.742, 0.041, 0.372, 0.505, 0.457, 0.862, 0.987, 0.203, 0.002, 0.568, 0.367, 0.732, 0.344, 0.233, 0.034, 0.102, 0.093, 0.096, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 1.014, 0.337, 1.717, 0.03, 0.0001, 0.2, 0.49, 1.091, 0.031, 0.184, 0.021, 0.587, 0.017, 1.766, 0.002, 0.057, 0.002, 0.019, 0.005, 0.016, 0.001, 1.048, 0.146, 0.534, 0.083, 0.03, 0.659, 0.006, 0.381, 0.026, 0.006, 0.26, 0.031, 0.261, 0.004, 0.294, 21.971, 5.237, 0.529, 0.24, 0.912, 0.021, 0.699, 0.107, 0.285, 0.131, 0.613, 1.017, 1.508, 0.008, 1.629, 0.499, 0.008, 0.864, 0.313, 0.067, 0.93, 0.419, 0.0001, 0.006, 0.002, 0.0001, 3.471, 0.661, 0.0001, 0.0001, 0.008, 0.024, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 26.65, 0.0001, 0.078, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "got": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.339, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.094, 0.003, 1.291, 0.0001, 0.0001, 0.0001, 0.0001, 0.038, 0.115, 0.115, 0.004, 0.002, 1.558, 0.264, 1.449, 0.007, 0.147, 0.29, 0.265, 0.261, 0.158, 0.118, 0.082, 0.102, 0.128, 0.101, 0.042, 0.039, 0.006, 0.003, 0.008, 0.017, 0.0001, 0.013, 0.006, 0.028, 0.006, 0.126, 0.004, 0.142, 0.123, 0.192, 0.004, 0.003, 0.01, 0.007, 0.004, 0.248, 0.007, 0.0001, 0.011, 0.012, 0.024, 0.014, 0.037, 0.008, 0.0001, 0.001, 0.001, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.001, 1.416, 0.252, 0.277, 0.447, 1.622, 0.345, 0.341, 0.482, 1.005, 0.151, 0.167, 0.523, 0.441, 1.296, 0.895, 0.224, 0.019, 0.998, 0.984, 0.975, 0.495, 0.221, 0.388, 0.018, 0.135, 0.029, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.227, 0.027, 0.943, 1.525, 0.623, 0.417, 0.281, 0.024, 0.043, 0.442, 0.017, 0.001, 12.517, 4.391, 0.0001, 0.004, 16.904, 0.001, 0.002, 0.005, 0.001, 0.003, 0.004, 0.004, 0.0001, 0.003, 0.047, 0.043, 0.003, 0.003, 0.004, 0.002, 1.424, 0.066, 0.105, 0.001, 0.004, 0.001, 0.009, 0.002, 0.017, 0.005, 0.002, 0.005, 0.002, 0.035, 0.001, 0.003, 3.235, 0.309, 0.439, 0.698, 0.617, 0.042, 0.143, 0.379, 0.509, 2.203, 0.495, 0.498, 0.573, 1.215, 0.432, 0.907, 0.0001, 0.0001, 1.432, 0.164, 0.007, 0.004, 0.001, 0.002, 0.0001, 0.004, 0.018, 0.002, 0.024, 0.0001, 0.034, 0.019, 0.033, 0.012, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.002, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.003, 0.09, 0.108, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.902, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "gv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.271, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.449, 0.001, 0.421, 0.002, 0.001, 0.012, 0.004, 0.833, 0.218, 0.217, 0.001, 0.004, 1.036, 0.572, 0.962, 0.016, 0.26, 0.327, 0.165, 0.089, 0.084, 0.093, 0.087, 0.088, 0.107, 0.189, 0.087, 0.045, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.277, 0.194, 0.324, 0.123, 0.14, 0.124, 0.191, 0.146, 0.079, 0.067, 0.068, 0.129, 0.207, 0.152, 0.084, 0.138, 0.02, 0.179, 0.402, 0.526, 0.063, 0.198, 0.043, 0.005, 0.079, 0.006, 0.009, 0.0001, 0.009, 0.0001, 0.001, 0.0001, 8.563, 0.792, 1.691, 1.903, 8.594, 0.377, 2.885, 5.368, 3.902, 0.512, 0.598, 3.599, 1.506, 6.663, 4.174, 0.394, 0.032, 4.839, 4.581, 2.625, 1.233, 0.647, 0.279, 0.018, 6.112, 0.053, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.052, 0.016, 0.011, 0.007, 0.006, 0.002, 0.002, 0.033, 0.003, 0.008, 0.001, 0.001, 0.002, 0.004, 0.001, 0.003, 0.004, 0.002, 0.001, 0.008, 0.005, 0.001, 0.002, 0.002, 0.007, 0.032, 0.003, 0.002, 0.002, 0.002, 0.001, 0.001, 0.013, 0.034, 0.001, 0.003, 0.006, 0.002, 0.002, 0.259, 0.003, 0.024, 0.003, 0.005, 0.003, 0.021, 0.001, 0.003, 0.016, 0.006, 0.011, 0.021, 0.003, 0.006, 0.005, 0.006, 0.011, 0.008, 0.015, 0.005, 0.007, 0.005, 0.006, 0.004, 0.0001, 0.0001, 0.024, 0.446, 0.012, 0.021, 0.0001, 0.001, 0.0001, 0.006, 0.003, 0.004, 0.002, 0.0001, 0.012, 0.007, 0.044, 0.019, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.006, 0.05, 0.002, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ha": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.755, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.253, 0.006, 0.093, 0.001, 0.0001, 0.003, 0.001, 0.233, 0.264, 0.267, 0.0001, 0.001, 0.745, 0.202, 0.904, 0.054, 0.25, 0.351, 0.185, 0.101, 0.092, 0.11, 0.102, 0.101, 0.107, 0.226, 0.077, 0.015, 0.009, 0.002, 0.009, 0.006, 0.001, 0.703, 0.295, 0.111, 0.155, 0.055, 0.098, 0.113, 0.13, 0.318, 0.133, 0.225, 0.088, 0.271, 0.163, 0.048, 0.074, 0.005, 0.115, 0.268, 0.173, 0.05, 0.018, 0.079, 0.003, 0.091, 0.042, 0.023, 0.0001, 0.025, 0.0001, 0.021, 0.001, 18.747, 1.651, 0.919, 2.906, 2.679, 0.906, 1.302, 1.831, 6.455, 0.467, 3.514, 2.109, 2.474, 6.749, 1.839, 0.213, 0.023, 4.031, 3.401, 2.21, 3.388, 0.067, 1.617, 0.015, 2.266, 0.447, 0.001, 0.001, 0.003, 0.002, 0.0001, 0.116, 0.007, 0.003, 0.001, 0.009, 0.005, 0.003, 0.003, 0.007, 0.002, 0.01, 0.001, 0.001, 0.0001, 0.003, 0.001, 0.002, 0.002, 0.001, 0.029, 0.002, 0.001, 0.0001, 0.094, 0.018, 0.242, 0.0001, 0.001, 0.01, 0.009, 0.001, 0.004, 0.02, 0.005, 0.002, 0.006, 0.0001, 0.001, 0.003, 0.015, 0.004, 0.013, 0.004, 0.002, 0.002, 0.004, 0.002, 0.003, 0.004, 0.011, 0.001, 0.005, 0.011, 0.003, 0.002, 0.003, 0.002, 0.004, 0.002, 0.001, 0.003, 0.003, 0.0001, 0.002, 0.0001, 0.0001, 0.03, 0.04, 0.008, 0.004, 0.18, 0.0001, 0.0001, 0.118, 0.001, 0.004, 0.0001, 0.0001, 0.001, 0.001, 0.011, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.044, 0.043, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.115, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hak": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.757, 0.001, 0.06, 0.0001, 0.0001, 0.014, 0.0001, 0.007, 0.281, 0.281, 0.0001, 0.001, 0.836, 6.558, 0.681, 0.018, 0.337, 0.407, 0.278, 0.148, 0.134, 0.137, 0.13, 0.123, 0.136, 0.173, 0.065, 0.014, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.079, 0.057, 0.378, 0.035, 0.025, 0.133, 0.042, 0.182, 0.024, 0.017, 0.335, 0.169, 0.185, 0.174, 0.026, 0.169, 0.016, 0.027, 0.334, 0.366, 0.012, 0.069, 0.025, 0.002, 0.166, 0.009, 0.007, 0.0001, 0.007, 0.0001, 0.003, 0.0001, 1.796, 0.086, 1.609, 0.16, 2.657, 0.577, 2.978, 5.312, 4.077, 0.022, 2.986, 0.978, 0.836, 6.046, 1.214, 0.924, 0.006, 0.355, 1.925, 2.85, 1.719, 0.417, 0.063, 0.011, 1.033, 0.05, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.624, 0.347, 0.489, 0.127, 0.115, 0.217, 0.079, 0.128, 0.198, 0.185, 0.153, 0.188, 0.325, 0.981, 0.111, 0.161, 0.125, 0.071, 0.062, 0.072, 0.143, 0.099, 0.164, 0.124, 0.154, 0.164, 0.132, 0.118, 0.284, 0.116, 0.086, 0.138, 0.587, 0.284, 0.798, 0.114, 0.117, 0.11, 0.089, 0.096, 0.66, 0.449, 0.294, 0.11, 0.804, 0.308, 1.169, 0.118, 0.192, 0.187, 0.596, 1.486, 0.608, 0.076, 0.115, 0.115, 0.317, 1.436, 0.679, 1.022, 0.36, 0.128, 0.129, 0.134, 0.0001, 0.0001, 0.018, 7.409, 0.013, 0.036, 0.003, 0.005, 0.0001, 0.003, 0.001, 0.002, 1.194, 0.0001, 0.01, 0.005, 0.045, 0.02, 0.001, 0.001, 0.0001, 0.0001, 0.003, 0.013, 0.006, 0.004, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 1.011, 0.064, 0.254, 0.448, 1.333, 0.785, 0.602, 0.451, 0.439, 0.002, 0.004, 0.008, 0.003, 0.0001, 0.269, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "haw": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.221, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.294, 0.012, 0.203, 0.0001, 0.0001, 0.0001, 0.001, 0.132, 0.34, 0.352, 0.0001, 0.001, 1.505, 0.111, 0.979, 0.007, 0.17, 0.218, 0.129, 0.06, 0.059, 0.065, 0.059, 0.085, 0.093, 0.096, 0.074, 0.017, 0.01, 0.0001, 0.01, 0.007, 0.0001, 0.393, 0.447, 0.582, 0.062, 0.097, 0.065, 0.079, 0.798, 0.153, 0.05, 0.341, 0.594, 0.369, 0.112, 0.254, 0.296, 0.019, 0.112, 0.703, 0.122, 0.065, 0.176, 0.058, 0.005, 0.01, 0.09, 0.005, 0.0001, 0.006, 0.0001, 0.003, 0.006, 12.798, 0.268, 0.355, 0.813, 5.652, 0.089, 0.569, 1.324, 6.125, 0.081, 4.131, 4.145, 2.483, 4.121, 5.223, 1.895, 0.028, 1.627, 1.407, 0.928, 3.376, 0.134, 0.71, 0.014, 0.137, 0.178, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 1.411, 1.393, 0.012, 0.01, 0.008, 0.004, 0.003, 0.003, 0.01, 0.001, 0.006, 0.004, 0.027, 0.239, 0.001, 0.004, 0.011, 0.006, 0.002, 0.111, 0.01, 0.006, 0.002, 0.004, 1.323, 0.019, 0.006, 0.004, 0.007, 0.006, 0.005, 0.004, 0.006, 0.059, 0.005, 0.006, 0.006, 0.004, 0.001, 0.013, 0.01, 0.035, 0.014, 0.268, 0.004, 0.047, 0.003, 0.004, 0.012, 0.061, 0.008, 0.113, 0.006, 0.007, 0.004, 0.005, 0.011, 0.005, 0.014, 1.288, 0.011, 0.01, 0.006, 0.004, 0.0001, 0.0001, 0.011, 0.331, 1.585, 0.461, 0.0001, 0.008, 0.0001, 0.011, 1.285, 0.01, 0.001, 0.0001, 0.031, 0.013, 0.031, 0.011, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.043, 0.02, 0.017, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.013, 1.362, 0.0001, 0.001, 0.006, 0.003, 0.002, 0.001, 0.001, 0.002, 0.007, 0.008, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hif": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.441, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.1, 0.004, 0.114, 0.0001, 0.001, 0.009, 0.004, 0.035, 0.174, 0.173, 0.001, 0.001, 0.931, 0.131, 1.205, 0.021, 0.405, 0.564, 0.33, 0.156, 0.134, 0.134, 0.137, 0.132, 0.161, 0.312, 0.075, 0.009, 0.003, 0.005, 0.003, 0.001, 0.0001, 0.456, 0.322, 0.355, 0.197, 0.18, 0.293, 0.19, 0.17, 0.372, 0.16, 0.181, 0.207, 0.307, 0.247, 0.078, 0.33, 0.012, 0.201, 0.529, 0.239, 0.168, 0.085, 0.095, 0.004, 0.174, 0.017, 0.016, 0.0001, 0.016, 0.0001, 0.019, 0.0001, 12.241, 1.338, 1.486, 1.704, 7.791, 0.593, 1.202, 3.829, 6.515, 0.754, 3.146, 2.684, 2.468, 4.596, 2.829, 0.958, 0.04, 4.362, 3.289, 3.315, 2.328, 0.443, 0.421, 0.04, 0.804, 0.089, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.026, 0.089, 0.009, 0.002, 0.003, 0.005, 0.002, 0.014, 0.008, 0.001, 0.001, 0.004, 0.002, 0.02, 0.003, 0.003, 0.003, 0.002, 0.001, 0.042, 0.003, 0.007, 0.001, 0.003, 0.002, 0.005, 0.002, 0.011, 0.004, 0.001, 0.001, 0.013, 0.018, 0.009, 0.001, 0.005, 0.072, 0.024, 0.007, 0.009, 0.007, 0.012, 0.004, 0.029, 0.003, 0.013, 0.009, 0.007, 0.017, 0.022, 0.012, 0.006, 0.004, 0.005, 0.014, 0.002, 0.01, 0.032, 0.005, 0.004, 0.012, 0.003, 0.011, 0.006, 0.0001, 0.0001, 0.028, 0.074, 0.148, 0.035, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.005, 0.003, 0.0001, 0.004, 0.001, 0.016, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.009, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.105, 0.033, 0.022, 0.002, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ho": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.445, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.244, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.681, 0.84, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.042, 0.0001, 0.0001, 0.0001, 0.84, 1.681, 0.0001, 0.84, 0.0001, 0.0001, 1.681, 1.681, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.966, 0.84, 0.0001, 0.0001, 7.563, 0.0001, 0.84, 0.0001, 5.042, 0.0001, 0.0001, 2.521, 1.681, 5.882, 12.605, 1.681, 0.0001, 3.361, 1.681, 1.681, 0.0001, 1.681, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hsb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.885, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.708, 0.001, 0.633, 0.0001, 0.0001, 0.02, 0.001, 0.006, 0.349, 0.351, 0.019, 0.001, 0.617, 0.09, 1.156, 0.027, 0.335, 0.549, 0.233, 0.161, 0.153, 0.173, 0.141, 0.134, 0.184, 0.278, 0.061, 0.039, 0.002, 0.004, 0.002, 0.001, 0.0001, 0.124, 0.184, 0.091, 0.139, 0.058, 0.04, 0.059, 0.112, 0.043, 0.103, 0.189, 0.142, 0.204, 0.143, 0.038, 0.227, 0.002, 0.151, 0.281, 0.088, 0.037, 0.024, 0.263, 0.004, 0.003, 0.079, 0.006, 0.0001, 0.006, 0.0001, 0.001, 0.0001, 6.697, 1.107, 1.636, 2.081, 6.467, 0.188, 0.301, 1.756, 3.527, 3.654, 2.787, 1.99, 1.872, 3.895, 5.864, 1.456, 0.004, 3.313, 3.645, 2.804, 2.176, 0.063, 3.44, 0.018, 1.507, 1.152, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.124, 0.059, 0.706, 0.009, 0.065, 0.003, 0.009, 0.741, 0.003, 0.001, 0.002, 0.003, 0.046, 0.476, 0.001, 0.004, 0.004, 0.003, 0.003, 0.038, 0.003, 0.003, 0.002, 0.005, 0.005, 0.336, 0.005, 1.33, 0.03, 0.004, 0.03, 0.009, 0.055, 0.752, 0.003, 0.003, 0.008, 0.003, 0.002, 0.003, 0.003, 0.008, 0.001, 0.003, 0.001, 0.011, 0.001, 0.003, 0.025, 0.008, 0.015, 0.5, 0.006, 0.013, 0.014, 0.003, 0.014, 0.005, 0.495, 0.011, 0.018, 0.033, 0.697, 0.004, 0.0001, 0.0001, 0.023, 0.573, 2.597, 3.085, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.0001, 0.001, 0.0001, 0.01, 0.005, 0.144, 0.055, 0.001, 0.001, 0.001, 0.011, 0.004, 0.015, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.004, 0.112, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ht": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.728, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.82, 0.005, 0.108, 0.0001, 0.0001, 0.002, 0.001, 0.044, 0.203, 0.204, 0.004, 0.0001, 1.177, 0.16, 1.277, 0.006, 1.128, 0.316, 0.385, 0.25, 0.229, 0.141, 0.146, 0.14, 0.135, 0.218, 0.285, 0.009, 0.002, 0.002, 0.002, 0.073, 0.0001, 0.308, 0.114, 0.31, 0.14, 0.272, 0.082, 0.233, 0.111, 0.459, 0.083, 0.546, 0.457, 0.33, 0.177, 0.124, 0.284, 0.004, 0.107, 0.215, 0.201, 0.017, 0.07, 0.083, 0.002, 0.054, 0.009, 0.003, 0.0001, 0.009, 0.003, 0.007, 0.0001, 8.338, 0.713, 0.405, 1.058, 6.922, 0.493, 1.121, 0.484, 5.37, 0.359, 1.684, 3.389, 1.726, 9.14, 4.981, 1.524, 0.032, 2.005, 4.201, 3.104, 1.485, 1.12, 1.14, 0.06, 3.565, 0.552, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.036, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.007, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.023, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.04, 0.015, 0.008, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.815, 0.088, 0.005, 0.004, 0.0001, 0.019, 0.002, 0.004, 0.0001, 0.005, 0.398, 0.011, 0.003, 0.0001, 0.001, 0.0001, 0.001, 0.002, 0.004, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.04, 1.397, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.036, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.597, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.8, 0.0001, 0.032, 0.0001, 0.0001, 0.007, 0.0001, 0.004, 0.144, 0.144, 0.0001, 0.001, 0.586, 0.166, 0.08, 0.013, 0.201, 0.284, 0.165, 0.087, 0.08, 0.086, 0.077, 0.075, 0.09, 0.155, 0.113, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.01, 0.007, 0.01, 0.005, 0.005, 0.004, 0.004, 0.004, 0.018, 0.002, 0.002, 0.005, 0.008, 0.005, 0.004, 0.006, 0.001, 0.005, 0.011, 0.008, 0.002, 0.006, 0.004, 0.006, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.003, 0.016, 0.046, 0.006, 0.015, 0.015, 0.053, 0.008, 0.009, 0.013, 0.038, 0.001, 0.005, 0.027, 0.014, 0.034, 0.04, 0.008, 0.001, 0.036, 0.026, 0.029, 0.018, 0.005, 0.004, 0.002, 0.008, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.414, 0.639, 1.93, 0.109, 0.557, 0.081, 0.132, 0.316, 0.027, 0.402, 0.05, 0.015, 0.042, 0.09, 0.048, 0.034, 0.002, 0.004, 0.002, 0.02, 0.024, 0.021, 0.028, 0.001, 0.0001, 0.001, 0.001, 0.003, 0.001, 0.123, 0.001, 0.0001, 0.042, 6.697, 0.434, 0.595, 0.616, 2.608, 0.304, 0.502, 0.621, 0.7, 0.114, 2.81, 0.856, 0.261, 0.333, 1.634, 0.66, 0.29, 0.576, 0.139, 1.799, 1.257, 4.145, 0.346, 3.356, 0.233, 0.437, 0.354, 0.321, 1.025, 1.123, 1.395, 0.0001, 0.0001, 0.223, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.029, 0.01, 0.0001, 0.0001, 0.652, 36.534, 7.186, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.026, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "hz": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 25.0, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.667, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 8.333, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ia": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.646, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.141, 0.002, 0.329, 0.0001, 0.0001, 0.008, 0.001, 0.021, 0.18, 0.18, 0.001, 0.003, 1.016, 0.166, 0.808, 0.013, 0.184, 0.275, 0.136, 0.08, 0.078, 0.085, 0.074, 0.075, 0.088, 0.135, 0.073, 0.032, 0.002, 0.003, 0.002, 0.002, 0.0001, 0.226, 0.141, 0.296, 0.096, 0.165, 0.073, 0.096, 0.067, 0.304, 0.056, 0.03, 0.329, 0.174, 0.087, 0.056, 0.186, 0.016, 0.106, 0.253, 0.115, 0.079, 0.078, 0.031, 0.017, 0.009, 0.016, 0.018, 0.0001, 0.018, 0.0001, 0.006, 0.0001, 7.783, 0.726, 2.95, 2.701, 11.264, 0.558, 0.916, 0.687, 6.773, 0.133, 0.102, 4.659, 2.226, 5.924, 5.837, 2.221, 0.5, 4.607, 4.777, 5.188, 3.143, 1.186, 0.054, 0.19, 0.205, 0.091, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.033, 0.014, 0.005, 0.003, 0.003, 0.002, 0.001, 0.002, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.01, 0.005, 0.001, 0.001, 0.002, 0.003, 0.007, 0.001, 0.002, 0.005, 0.005, 0.001, 0.001, 0.01, 0.02, 0.003, 0.006, 0.005, 0.003, 0.002, 0.005, 0.004, 0.021, 0.003, 0.011, 0.003, 0.018, 0.002, 0.002, 0.005, 0.011, 0.005, 0.019, 0.002, 0.002, 0.005, 0.002, 0.004, 0.005, 0.009, 0.012, 0.006, 0.004, 0.003, 0.005, 0.0001, 0.0001, 0.026, 0.115, 0.014, 0.006, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.019, 0.01, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.009, 0.031, 0.001, 0.001, 0.004, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ie": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.521, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.809, 0.001, 0.247, 0.0001, 0.0001, 0.004, 0.006, 0.019, 0.181, 0.18, 0.001, 0.0001, 0.349, 1.199, 1.232, 0.019, 0.563, 0.838, 0.612, 0.225, 0.226, 0.24, 0.207, 0.206, 0.219, 0.382, 0.048, 0.005, 0.006, 0.001, 0.006, 0.0001, 0.0001, 0.309, 0.238, 0.27, 0.166, 0.167, 0.136, 0.184, 0.184, 0.432, 0.068, 0.108, 0.44, 0.245, 0.141, 0.106, 0.224, 0.013, 0.149, 0.37, 0.155, 0.122, 0.083, 0.052, 0.007, 0.021, 0.046, 0.016, 0.0001, 0.017, 0.0001, 0.0001, 0.0001, 6.871, 0.75, 2.348, 2.768, 8.937, 0.584, 0.855, 0.832, 7.829, 0.174, 0.338, 4.504, 1.934, 5.948, 3.473, 1.445, 0.281, 4.186, 4.435, 5.077, 2.881, 0.926, 0.103, 0.2, 0.235, 0.149, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.011, 0.008, 0.006, 0.012, 0.004, 0.002, 0.001, 0.038, 0.001, 0.002, 0.0001, 0.001, 0.004, 0.016, 0.001, 0.001, 0.004, 0.003, 0.001, 0.004, 0.002, 0.001, 0.002, 0.003, 0.002, 0.005, 0.002, 0.003, 0.002, 0.002, 0.002, 0.01, 0.018, 0.107, 0.002, 0.003, 0.013, 0.003, 0.002, 0.004, 0.007, 0.34, 0.002, 0.007, 0.001, 0.079, 0.001, 0.001, 0.011, 0.009, 0.004, 0.067, 0.003, 0.005, 0.02, 0.001, 0.012, 0.001, 0.025, 0.006, 0.034, 0.009, 0.011, 0.002, 0.0001, 0.0001, 0.012, 0.714, 0.064, 0.047, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.007, 0.004, 0.047, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.01, 0.006, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ig": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.656, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.908, 0.0001, 0.773, 0.0001, 0.001, 0.002, 0.004, 0.323, 0.322, 0.321, 0.001, 0.0001, 0.801, 0.348, 0.989, 0.009, 0.349, 0.514, 0.434, 0.211, 0.141, 0.149, 0.14, 0.138, 0.136, 0.236, 0.05, 0.04, 0.002, 0.002, 0.002, 0.002, 0.001, 0.437, 0.139, 0.167, 0.124, 0.161, 0.093, 0.162, 0.08, 0.189, 0.162, 0.069, 0.102, 0.246, 0.453, 0.257, 0.111, 0.006, 0.081, 0.231, 0.102, 0.09, 0.023, 0.104, 0.006, 0.033, 0.007, 0.018, 0.0001, 0.018, 0.0001, 0.003, 0.003, 8.644, 2.249, 1.219, 1.734, 6.313, 0.761, 1.664, 1.979, 4.558, 0.257, 2.436, 1.453, 1.97, 6.1, 4.008, 0.966, 0.02, 3.332, 1.739, 2.408, 2.889, 0.225, 1.517, 0.034, 1.16, 0.258, 0.0001, 0.007, 0.001, 0.0001, 0.0001, 0.13, 0.024, 0.004, 0.004, 0.007, 0.006, 0.001, 0.002, 0.001, 0.004, 0.004, 0.623, 0.118, 0.962, 0.001, 0.0001, 0.002, 0.001, 0.004, 0.022, 0.005, 0.001, 0.031, 0.002, 0.001, 0.082, 0.001, 0.002, 0.004, 0.003, 0.0001, 0.0001, 0.34, 0.233, 0.001, 0.001, 0.012, 1.142, 0.001, 0.003, 0.105, 0.2, 0.002, 0.014, 0.036, 0.183, 0.028, 0.019, 0.004, 0.004, 0.029, 0.095, 0.002, 0.001, 0.009, 0.001, 0.003, 0.143, 0.201, 2.836, 0.03, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.146, 1.356, 0.009, 0.021, 0.0001, 0.014, 0.039, 0.003, 0.0001, 0.001, 0.029, 0.0001, 0.005, 0.001, 0.008, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 2.927, 0.109, 0.003, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ii": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.208, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.146, 0.0001, 1.029, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.343, 0.343, 0.0001, 0.0001, 0.0001, 0.0001, 0.686, 0.0001, 4.803, 0.172, 2.401, 0.0001, 0.0001, 0.172, 0.343, 0.686, 0.686, 0.343, 0.0001, 0.0001, 0.0001, 0.0001, 0.515, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.172, 0.0001, 0.172, 0.0001, 0.0001, 0.0001, 0.172, 0.858, 0.0001, 0.343, 0.343, 0.0001, 0.0001, 0.0001, 0.172, 0.0001, 0.0001, 0.0001, 0.343, 0.343, 0.343, 0.172, 0.0001, 0.172, 0.343, 0.0001, 0.515, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.172, 0.0001, 0.172, 0.0001, 0.0001, 2.573, 1.887, 1.544, 0.858, 2.058, 0.343, 1.715, 0.343, 0.343, 0.0001, 0.172, 1.201, 1.887, 1.029, 1.372, 0.172, 0.343, 1.029, 0.686, 0.172, 0.172, 0.172, 0.686, 0.858, 0.686, 0.172, 0.343, 0.0001, 0.515, 0.172, 0.343, 0.686, 0.343, 0.172, 0.0001, 0.0001, 0.343, 0.0001, 0.172, 1.544, 0.172, 0.343, 0.686, 0.858, 0.686, 0.858, 0.343, 0.686, 0.172, 0.343, 0.343, 0.515, 2.744, 0.172, 0.0001, 0.343, 0.858, 2.916, 0.343, 0.686, 0.343, 0.0001, 0.343, 0.172, 0.0001, 0.0001, 1.372, 0.0001, 0.172, 0.172, 0.0001, 0.0001, 0.0001, 0.172, 0.172, 0.0001, 0.515, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.515, 1.029, 4.631, 1.029, 0.686, 0.0001, 0.858, 10.635, 0.0001, 0.0001, 0.0001, 0.0001, 0.343, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ik": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.089, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.203, 0.0001, 1.053, 0.0001, 0.0001, 0.002, 0.004, 0.019, 1.043, 1.038, 0.0001, 0.004, 0.489, 0.212, 1.246, 0.04, 0.17, 0.264, 0.162, 0.084, 0.065, 0.055, 0.132, 0.065, 0.076, 0.124, 0.136, 0.025, 0.013, 0.002, 0.002, 0.0001, 0.0001, 0.824, 0.109, 0.155, 0.065, 0.052, 0.025, 0.048, 0.076, 0.634, 0.073, 0.409, 0.111, 0.352, 0.545, 0.069, 0.285, 0.321, 0.155, 0.436, 0.755, 0.409, 0.076, 0.046, 0.008, 0.044, 0.002, 0.01, 0.0001, 0.015, 0.0001, 0.008, 0.0001, 9.867, 0.308, 1.051, 0.799, 2.404, 0.327, 1.605, 1.011, 7.743, 0.063, 2.113, 2.725, 1.552, 3.495, 1.668, 1.101, 3.682, 2.526, 3.015, 4.496, 6.747, 0.801, 0.229, 0.065, 0.707, 0.103, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.097, 0.073, 0.183, 0.023, 0.006, 0.031, 0.013, 0.103, 0.05, 0.008, 0.004, 0.952, 0.019, 0.055, 0.002, 0.023, 0.013, 0.008, 0.0001, 0.002, 0.008, 0.067, 0.013, 0.015, 0.004, 0.002, 0.04, 0.01, 0.017, 0.01, 0.002, 0.019, 0.013, 0.843, 0.013, 0.029, 1.206, 0.281, 0.025, 0.006, 0.067, 0.006, 0.055, 0.004, 0.038, 0.017, 0.078, 0.034, 0.172, 0.862, 0.059, 0.01, 0.01, 0.067, 0.008, 0.187, 0.269, 0.134, 0.055, 0.021, 0.038, 0.019, 0.189, 0.046, 0.0001, 0.0001, 0.008, 0.944, 0.835, 1.051, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.006, 0.008, 0.0001, 0.025, 0.023, 0.42, 0.185, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.408, 0.191, 0.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ilo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.301, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.793, 0.111, 0.271, 0.0001, 0.001, 0.008, 0.001, 0.018, 0.172, 0.172, 0.003, 0.003, 0.83, 0.304, 0.649, 0.008, 0.21, 0.325, 0.155, 0.097, 0.09, 0.094, 0.083, 0.085, 0.1, 0.166, 0.048, 0.03, 0.005, 0.001, 0.005, 0.001, 0.0001, 0.349, 0.225, 0.111, 0.217, 0.099, 0.09, 0.118, 0.1, 0.241, 0.035, 0.175, 0.118, 0.232, 0.163, 0.054, 0.279, 0.009, 0.088, 0.233, 0.461, 0.072, 0.035, 0.029, 0.006, 0.014, 0.012, 0.036, 0.0001, 0.036, 0.0001, 0.001, 0.0001, 16.461, 1.586, 0.189, 2.856, 3.734, 0.046, 3.664, 0.306, 10.008, 0.024, 3.303, 2.245, 1.909, 7.066, 3.393, 2.095, 0.012, 2.409, 3.066, 6.078, 2.307, 0.067, 0.549, 0.014, 1.361, 0.048, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.043, 0.006, 0.003, 0.001, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.004, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.033, 0.004, 0.001, 0.001, 0.001, 0.001, 0.004, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.015, 0.007, 0.001, 0.001, 0.003, 0.002, 0.001, 0.003, 0.002, 0.009, 0.002, 0.004, 0.001, 0.006, 0.002, 0.001, 0.013, 0.007, 0.003, 0.007, 0.004, 0.001, 0.003, 0.001, 0.004, 0.002, 0.004, 0.002, 0.003, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.027, 0.049, 0.008, 0.009, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.007, 0.004, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.004, 0.043, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "io": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.24, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.878, 0.001, 0.226, 0.0001, 0.145, 0.683, 0.001, 0.155, 0.19, 0.19, 0.002, 0.001, 1.502, 0.399, 2.049, 0.127, 1.123, 1.116, 0.845, 0.565, 0.593, 0.586, 0.516, 0.395, 0.578, 0.496, 0.056, 0.039, 0.008, 0.001, 0.008, 0.001, 0.0001, 0.262, 0.119, 0.082, 0.063, 0.203, 0.065, 0.07, 0.089, 0.077, 0.042, 0.131, 0.387, 0.144, 0.086, 0.052, 0.185, 0.006, 0.067, 0.238, 0.064, 0.127, 0.06, 0.027, 0.002, 0.018, 0.007, 0.008, 0.0001, 0.008, 0.0001, 0.001, 0.0001, 8.848, 0.82, 0.665, 2.487, 7.044, 0.592, 0.8, 0.82, 7.741, 0.211, 1.575, 3.65, 2.435, 4.587, 5.58, 1.431, 0.273, 4.484, 4.553, 2.971, 2.4, 1.482, 0.052, 0.098, 0.514, 0.499, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.011, 0.008, 0.004, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.003, 0.002, 0.001, 0.0001, 0.002, 0.001, 0.004, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.096, 0.01, 0.001, 0.003, 0.003, 0.001, 0.001, 0.003, 0.002, 0.015, 0.001, 0.004, 0.001, 0.008, 0.001, 0.001, 0.005, 0.003, 0.253, 0.006, 0.002, 0.002, 0.003, 0.001, 0.003, 0.002, 0.004, 0.005, 0.003, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.356, 0.056, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.005, 0.003, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.01, 0.006, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "is": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.97, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.586, 0.001, 0.206, 0.0001, 0.0001, 0.008, 0.002, 0.007, 0.124, 0.124, 0.0001, 0.001, 0.499, 0.123, 1.026, 0.011, 0.247, 0.371, 0.182, 0.092, 0.087, 0.097, 0.09, 0.091, 0.11, 0.206, 0.046, 0.01, 0.008, 0.003, 0.008, 0.001, 0.0001, 0.15, 0.156, 0.07, 0.071, 0.123, 0.128, 0.099, 0.219, 0.049, 0.069, 0.114, 0.102, 0.145, 0.086, 0.033, 0.076, 0.003, 0.091, 0.275, 0.089, 0.03, 0.081, 0.029, 0.009, 0.012, 0.006, 0.003, 0.0001, 0.003, 0.0001, 0.004, 0.0001, 6.834, 0.671, 0.132, 1.35, 4.383, 2.01, 2.575, 1.208, 5.351, 0.788, 2.14, 3.293, 2.549, 5.87, 1.807, 0.609, 0.005, 6.508, 4.164, 3.597, 3.384, 1.444, 0.036, 0.05, 0.678, 0.023, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.079, 0.071, 0.003, 0.002, 0.002, 0.001, 0.004, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.093, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.031, 0.002, 0.001, 0.01, 0.001, 0.001, 0.001, 0.008, 0.001, 0.029, 0.003, 0.162, 0.001, 0.007, 1.147, 0.001, 0.001, 0.003, 0.001, 0.559, 0.002, 0.002, 0.221, 0.001, 0.001, 0.001, 1.194, 0.001, 0.001, 2.653, 0.002, 0.003, 0.801, 0.002, 0.002, 0.588, 0.001, 0.004, 0.002, 0.419, 0.002, 0.005, 0.183, 0.658, 0.001, 0.0001, 0.0001, 0.014, 8.751, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.004, 0.011, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.079, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "iu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.678, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.59, 0.002, 0.2, 0.001, 0.003, 0.002, 0.003, 0.015, 0.174, 0.173, 0.0001, 0.002, 0.361, 0.227, 0.729, 0.057, 0.148, 0.113, 0.088, 0.041, 0.055, 0.057, 0.038, 0.037, 0.041, 0.075, 0.086, 0.012, 0.034, 0.007, 0.037, 0.002, 0.001, 0.071, 0.015, 0.028, 0.016, 0.027, 0.021, 0.01, 0.09, 0.106, 0.011, 0.032, 0.025, 0.039, 0.045, 0.015, 0.038, 0.016, 0.009, 0.047, 0.052, 0.031, 0.008, 0.018, 0.002, 0.004, 0.0001, 0.042, 0.001, 0.038, 0.0001, 0.005, 0.0001, 3.23, 0.132, 0.269, 0.325, 0.963, 0.137, 0.72, 0.796, 3.179, 0.121, 0.846, 1.083, 0.73, 1.94, 0.65, 0.417, 0.773, 0.909, 0.645, 2.138, 2.24, 0.378, 0.125, 0.018, 0.352, 0.009, 0.063, 0.016, 0.064, 0.0001, 0.0001, 0.195, 0.104, 0.722, 2.277, 0.527, 2.845, 0.283, 0.577, 0.292, 0.16, 1.105, 0.322, 0.08, 0.107, 0.751, 0.183, 5.797, 4.461, 2.284, 5.133, 1.078, 2.99, 2.939, 0.631, 0.063, 0.2, 0.245, 0.066, 0.007, 0.045, 0.004, 0.005, 0.011, 0.073, 0.039, 0.009, 0.018, 0.411, 1.389, 0.092, 0.103, 0.04, 1.113, 0.086, 0.008, 0.439, 0.043, 0.681, 0.098, 0.475, 0.284, 0.202, 0.231, 0.064, 0.012, 0.003, 0.129, 0.126, 0.009, 0.223, 0.007, 0.015, 0.041, 0.125, 0.0001, 0.0001, 0.1, 0.024, 0.004, 0.006, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.004, 0.002, 0.0001, 0.0001, 0.001, 0.131, 0.044, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.009, 0.014, 0.007, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 21.14, 0.181, 0.003, 0.004, 0.004, 0.004, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "jam": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.114, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.204, 0.0001, 0.437, 0.0001, 0.002, 0.015, 0.001, 0.02, 0.246, 0.245, 0.0001, 0.001, 1.286, 0.238, 0.848, 0.011, 0.225, 0.262, 0.144, 0.074, 0.072, 0.083, 0.075, 0.089, 0.083, 0.132, 0.047, 0.038, 0.014, 0.002, 0.014, 0.002, 0.0001, 0.33, 0.18, 0.107, 0.273, 0.095, 0.097, 0.106, 0.027, 0.375, 0.206, 0.243, 0.122, 0.218, 0.135, 0.052, 0.177, 0.004, 0.132, 0.376, 0.091, 0.038, 0.042, 0.116, 0.003, 0.09, 0.009, 0.033, 0.0001, 0.032, 0.0001, 0.0001, 0.0001, 11.751, 1.124, 0.777, 3.113, 4.403, 1.279, 0.882, 3.07, 11.71, 0.554, 2.318, 3.164, 2.271, 5.696, 3.101, 1.655, 0.006, 3.113, 3.636, 3.486, 2.985, 0.575, 1.126, 0.207, 0.616, 0.737, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.054, 0.013, 0.006, 0.006, 0.011, 0.005, 0.006, 0.002, 0.011, 0.004, 0.003, 0.002, 0.005, 0.004, 0.004, 0.001, 0.005, 0.003, 0.003, 0.026, 0.009, 0.002, 0.001, 0.003, 0.001, 0.005, 0.001, 0.003, 0.008, 0.008, 0.001, 0.0001, 0.066, 0.009, 0.001, 0.004, 0.01, 0.005, 0.003, 0.008, 0.009, 0.009, 0.007, 0.005, 0.005, 0.009, 0.003, 0.008, 0.005, 0.014, 0.004, 0.031, 0.002, 0.005, 0.002, 0.003, 0.006, 0.009, 0.008, 0.006, 0.007, 0.007, 0.004, 0.009, 0.0001, 0.0001, 0.069, 0.057, 0.012, 0.006, 0.0001, 0.001, 0.0001, 0.011, 0.004, 0.01, 0.001, 0.0001, 0.049, 0.024, 0.009, 0.004, 0.0001, 0.0001, 0.0001, 0.007, 0.002, 0.004, 0.025, 0.021, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.017, 0.008, 0.051, 0.0001, 0.002, 0.004, 0.003, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "jbo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 18.83, 0.0001, 0.137, 0.0001, 0.0001, 0.001, 0.0001, 3.634, 0.016, 0.016, 0.0001, 0.0001, 0.047, 0.014, 2.419, 0.008, 0.161, 0.318, 0.2, 0.098, 0.09, 0.087, 0.087, 0.089, 0.108, 0.172, 0.004, 0.001, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.035, 0.022, 0.028, 0.013, 0.017, 0.01, 0.012, 0.013, 0.015, 0.011, 0.012, 0.019, 0.022, 0.019, 0.015, 0.017, 0.001, 0.021, 0.029, 0.019, 0.006, 0.006, 0.008, 0.002, 0.002, 0.004, 0.002, 0.0001, 0.003, 0.0001, 0.003, 0.0001, 7.616, 1.669, 2.73, 1.665, 6.288, 0.906, 1.481, 0.055, 8.607, 1.326, 2.153, 5.868, 2.296, 4.062, 6.049, 1.389, 0.004, 2.945, 3.13, 2.492, 4.934, 0.679, 0.018, 0.589, 0.829, 0.701, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.01, 0.006, 0.006, 0.011, 0.005, 0.003, 0.004, 0.008, 0.003, 0.008, 0.003, 0.003, 0.002, 0.002, 0.002, 0.003, 0.002, 0.001, 0.003, 0.004, 0.004, 0.001, 0.002, 0.001, 0.006, 0.001, 0.002, 0.002, 0.002, 0.001, 0.002, 0.003, 0.006, 0.002, 0.003, 0.005, 0.003, 0.006, 0.013, 0.006, 0.012, 0.005, 0.003, 0.005, 0.008, 0.003, 0.005, 0.01, 0.01, 0.007, 0.008, 0.003, 0.008, 0.002, 0.003, 0.01, 0.005, 0.017, 0.007, 0.005, 0.005, 0.004, 0.003, 0.0001, 0.0001, 0.004, 0.032, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.006, 0.004, 0.004, 0.002, 0.0001, 0.016, 0.008, 0.046, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.007, 0.035, 0.026, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.02, 0.006, 0.007, 0.005, 0.001, 0.004, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "jv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.393, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.972, 0.002, 0.376, 0.0001, 0.001, 0.006, 0.002, 0.021, 0.174, 0.174, 0.0001, 0.002, 1.038, 0.248, 0.884, 0.027, 0.242, 0.269, 0.17, 0.077, 0.072, 0.083, 0.071, 0.073, 0.084, 0.157, 0.063, 0.014, 0.005, 0.004, 0.005, 0.001, 0.0001, 0.298, 0.282, 0.139, 0.175, 0.052, 0.071, 0.122, 0.1, 0.279, 0.193, 0.491, 0.137, 0.261, 0.155, 0.054, 0.404, 0.008, 0.134, 0.426, 0.252, 0.063, 0.039, 0.13, 0.007, 0.04, 0.014, 0.024, 0.0001, 0.024, 0.0001, 0.001, 0.0001, 13.56, 1.271, 0.49, 2.178, 3.499, 0.191, 4.675, 1.646, 6.887, 0.617, 3.65, 2.625, 2.089, 9.349, 2.312, 1.888, 0.011, 3.362, 3.296, 3.086, 3.992, 0.185, 1.217, 0.022, 0.792, 0.054, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.032, 0.007, 0.005, 0.003, 0.005, 0.004, 0.003, 0.003, 0.005, 0.012, 0.002, 0.001, 0.001, 0.004, 0.005, 0.002, 0.003, 0.002, 0.003, 0.01, 0.003, 0.002, 0.001, 0.001, 0.003, 0.007, 0.001, 0.003, 0.006, 0.006, 0.001, 0.001, 0.039, 0.004, 0.002, 0.003, 0.006, 0.005, 0.004, 0.006, 0.531, 1.186, 0.005, 0.003, 0.002, 0.005, 0.002, 0.002, 0.007, 0.006, 0.005, 0.006, 0.002, 0.002, 0.002, 0.001, 0.008, 0.005, 0.003, 0.002, 0.004, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.048, 1.757, 0.01, 0.01, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.007, 0.003, 0.009, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.015, 0.024, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.005, 0.031, 0.001, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ka": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.399, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.467, 0.006, 0.05, 0.004, 0.0001, 0.005, 0.0001, 0.002, 0.08, 0.08, 0.0001, 0.001, 0.389, 0.146, 0.411, 0.004, 0.126, 0.165, 0.095, 0.049, 0.046, 0.05, 0.043, 0.044, 0.053, 0.091, 0.022, 0.014, 0.001, 0.004, 0.001, 0.001, 0.0001, 0.009, 0.008, 0.011, 0.006, 0.004, 0.005, 0.005, 0.004, 0.036, 0.001, 0.002, 0.005, 0.008, 0.005, 0.004, 0.007, 0.001, 0.005, 0.01, 0.01, 0.002, 0.01, 0.003, 0.012, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.058, 0.009, 0.021, 0.031, 0.066, 0.012, 0.013, 0.018, 0.047, 0.001, 0.009, 0.032, 0.017, 0.042, 0.05, 0.013, 0.001, 0.044, 0.039, 0.037, 0.025, 0.006, 0.004, 0.003, 0.014, 0.002, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.133, 0.001, 0.001, 30.616, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.203, 1.072, 0.617, 1.27, 2.811, 0.901, 0.251, 0.727, 3.846, 0.492, 1.468, 1.522, 1.35, 1.641, 0.3, 0.022, 1.853, 2.198, 0.578, 0.828, 0.251, 0.28, 0.142, 0.172, 0.523, 0.1, 0.36, 0.118, 0.305, 0.039, 0.412, 0.073, 0.048, 0.001, 0.009, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.023, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.013, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 30.616, 0.133, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kaa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.138, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.976, 0.002, 0.25, 0.0001, 0.0001, 0.021, 0.001, 3.483, 0.188, 0.189, 0.0001, 0.005, 0.857, 0.333, 1.07, 0.015, 0.261, 0.313, 0.191, 0.105, 0.096, 0.102, 0.088, 0.083, 0.102, 0.171, 0.072, 0.024, 0.027, 0.002, 0.027, 0.004, 0.0001, 0.278, 0.237, 0.043, 0.064, 0.083, 0.059, 0.068, 0.047, 0.074, 0.082, 0.125, 0.051, 0.155, 0.064, 0.155, 0.081, 0.145, 0.091, 0.217, 0.129, 0.07, 0.048, 0.02, 0.093, 0.029, 0.015, 0.006, 0.0001, 0.006, 0.0001, 0.001, 0.174, 10.672, 1.536, 0.082, 2.608, 4.846, 0.175, 1.712, 1.492, 6.03, 0.848, 1.882, 4.983, 2.176, 5.612, 2.458, 1.187, 1.824, 4.354, 3.602, 3.336, 1.517, 0.264, 0.926, 0.28, 1.912, 0.845, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.223, 0.008, 0.008, 0.008, 0.005, 0.003, 0.002, 0.003, 0.003, 0.001, 0.002, 0.004, 0.002, 0.002, 0.002, 0.003, 0.008, 0.001, 0.002, 0.024, 0.089, 0.003, 0.024, 0.001, 0.007, 0.086, 0.002, 0.002, 0.011, 0.008, 0.005, 0.018, 0.016, 0.006, 0.003, 0.007, 0.007, 0.002, 0.001, 0.006, 0.003, 0.004, 0.002, 0.012, 0.002, 0.006, 0.001, 0.009, 0.142, 4.113, 0.008, 0.007, 0.005, 0.049, 0.005, 0.002, 0.01, 0.003, 0.009, 0.024, 0.009, 0.012, 0.029, 0.003, 0.0001, 0.0001, 0.053, 0.053, 4.15, 0.014, 0.0001, 0.002, 0.0001, 0.001, 0.004, 0.0001, 0.0001, 0.0001, 0.009, 0.003, 0.235, 0.052, 0.004, 0.001, 0.001, 0.003, 0.0001, 0.002, 0.013, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.006, 0.216, 0.0001, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kab": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.63, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.911, 0.026, 0.321, 0.0001, 0.0001, 0.004, 0.001, 0.063, 0.372, 0.372, 0.003, 0.002, 1.155, 1.35, 0.936, 0.038, 0.266, 0.305, 0.202, 0.119, 0.101, 0.107, 0.102, 0.091, 0.121, 0.181, 0.18, 0.035, 0.01, 0.019, 0.017, 0.012, 0.0001, 0.467, 0.145, 0.091, 0.191, 0.038, 0.078, 0.046, 0.038, 0.257, 0.025, 0.056, 0.211, 0.226, 0.079, 0.026, 0.046, 0.014, 0.063, 0.175, 0.468, 0.109, 0.016, 0.087, 0.018, 0.161, 0.062, 0.014, 0.0001, 0.014, 0.0001, 0.076, 0.0001, 9.2, 0.865, 0.672, 3.845, 7.769, 0.911, 1.711, 0.292, 5.622, 0.162, 1.372, 2.877, 2.842, 6.403, 0.445, 0.148, 0.603, 3.37, 3.532, 4.882, 2.937, 0.09, 1.486, 0.181, 2.148, 0.956, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 0.079, 0.004, 0.004, 0.003, 0.012, 0.007, 0.008, 0.003, 0.006, 0.01, 0.01, 0.0001, 0.003, 0.341, 0.007, 0.006, 0.04, 0.002, 0.003, 0.156, 0.017, 0.001, 0.002, 0.001, 0.004, 0.031, 0.007, 0.42, 0.023, 0.016, 0.002, 0.009, 0.025, 0.004, 0.015, 1.13, 0.027, 0.269, 0.019, 0.099, 0.024, 0.093, 0.007, 0.018, 0.013, 0.276, 0.002, 0.011, 0.014, 0.01, 0.006, 0.129, 0.025, 0.113, 0.001, 0.005, 0.586, 0.529, 0.15, 0.021, 0.004, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.056, 0.149, 0.056, 0.01, 0.05, 0.088, 0.0001, 1.3, 0.001, 0.001, 0.003, 0.0001, 0.203, 0.001, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.008, 0.063, 0.048, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 1.257, 0.143, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kbd": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.877, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.792, 0.0001, 0.075, 0.0001, 0.001, 0.011, 0.0001, 0.003, 0.141, 0.14, 0.0001, 0.003, 0.771, 0.205, 0.683, 0.004, 0.136, 0.165, 0.088, 0.057, 0.049, 0.062, 0.042, 0.043, 0.05, 0.078, 0.043, 0.017, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.304, 0.0001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.003, 0.0001, 0.001, 0.002, 0.001, 0.001, 0.008, 0.001, 0.014, 0.0001, 0.0001, 0.008, 0.0001, 0.008, 0.0001, 0.0001, 0.0001, 0.03, 0.003, 0.008, 0.007, 0.025, 0.002, 0.005, 0.007, 0.023, 0.001, 0.003, 0.195, 0.01, 0.018, 0.016, 0.007, 0.001, 0.016, 0.015, 0.015, 0.012, 0.002, 0.002, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.555, 0.735, 0.993, 2.937, 0.251, 2.403, 0.222, 0.078, 0.401, 1.056, 2.895, 2.991, 0.659, 6.305, 0.005, 0.318, 0.209, 0.078, 0.019, 0.048, 0.196, 0.035, 0.012, 0.035, 0.104, 0.003, 0.214, 0.042, 0.072, 0.044, 0.009, 0.068, 0.044, 0.057, 0.06, 0.06, 0.029, 0.076, 0.012, 0.013, 0.04, 0.033, 0.001, 0.031, 0.001, 0.015, 0.002, 0.026, 2.293, 0.626, 0.124, 1.164, 0.956, 0.819, 0.63, 0.861, 1.412, 0.263, 1.894, 1.024, 2.202, 1.111, 0.541, 0.996, 0.0001, 0.0001, 0.089, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.007, 0.001, 0.005, 0.002, 18.347, 24.31, 0.001, 1.322, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.003, 0.144, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kbp": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.616, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.57, 0.002, 0.071, 0.0001, 0.0001, 0.002, 0.0001, 0.006, 0.116, 0.115, 0.0001, 0.002, 0.667, 0.749, 0.841, 0.003, 0.17, 0.215, 0.112, 0.059, 0.061, 0.065, 0.059, 0.058, 0.083, 0.103, 0.043, 0.02, 0.0001, 0.014, 0.0001, 0.002, 0.0001, 0.165, 0.045, 0.077, 0.029, 0.079, 0.067, 0.032, 0.069, 0.044, 0.029, 0.18, 0.072, 0.11, 0.068, 0.032, 0.297, 0.002, 0.044, 0.127, 0.122, 0.017, 0.016, 0.035, 0.003, 0.036, 0.006, 0.025, 0.0001, 0.025, 0.0001, 0.0001, 0.0001, 8.914, 0.693, 0.409, 0.775, 2.26, 0.236, 0.534, 0.509, 1.986, 0.346, 2.598, 2.297, 1.559, 3.608, 1.061, 1.995, 0.02, 0.616, 1.735, 2.888, 0.861, 0.082, 0.914, 0.015, 2.587, 0.783, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.019, 0.022, 0.002, 0.003, 0.114, 0.001, 0.002, 0.001, 0.002, 0.067, 2.039, 2.33, 0.002, 0.002, 0.001, 0.0001, 0.179, 0.013, 0.001, 0.001, 2.735, 0.001, 1.381, 0.0001, 0.001, 0.007, 0.0001, 5.08, 0.004, 0.003, 0.0001, 0.0001, 0.004, 0.008, 0.005, 1.151, 0.003, 0.001, 0.001, 0.004, 0.013, 4.529, 0.002, 0.019, 0.001, 0.004, 0.003, 0.007, 0.003, 0.207, 0.003, 0.002, 0.003, 0.002, 0.003, 0.001, 0.006, 0.003, 0.002, 0.02, 0.003, 0.002, 0.002, 0.006, 0.0001, 0.0001, 0.035, 0.33, 0.004, 1.069, 0.247, 0.001, 0.0001, 14.815, 3.312, 0.001, 0.128, 0.0001, 0.011, 0.006, 0.009, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.007, 0.013, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.239, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.886, 0.007, 0.336, 0.0001, 0.0001, 0.012, 0.002, 0.078, 0.324, 0.324, 0.001, 0.002, 0.656, 0.558, 1.416, 0.029, 0.129, 0.236, 0.138, 0.114, 0.084, 0.072, 0.081, 0.089, 0.086, 0.136, 0.151, 0.002, 0.018, 0.006, 0.018, 0.004, 0.0001, 0.545, 0.514, 0.255, 0.205, 0.262, 0.18, 0.131, 0.1, 0.152, 0.059, 0.708, 0.293, 0.752, 0.533, 0.094, 0.176, 0.01, 0.241, 0.354, 0.199, 0.108, 0.106, 0.05, 0.006, 0.156, 0.054, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.001, 12.562, 2.277, 0.331, 1.547, 5.722, 0.691, 1.741, 0.399, 6.386, 0.118, 3.863, 3.599, 2.582, 6.478, 2.883, 0.88, 0.049, 1.355, 2.305, 2.139, 4.827, 0.445, 0.58, 0.051, 3.145, 1.337, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.071, 0.012, 0.003, 0.002, 0.01, 0.004, 0.003, 0.001, 0.004, 0.005, 0.003, 0.002, 0.002, 0.003, 0.001, 0.001, 0.006, 0.001, 0.001, 0.062, 0.006, 0.002, 0.0001, 0.001, 0.001, 0.009, 0.002, 0.004, 0.002, 0.001, 0.001, 0.001, 0.037, 0.129, 0.127, 0.006, 0.006, 0.002, 0.017, 0.018, 0.037, 0.077, 0.018, 0.027, 0.002, 0.034, 0.066, 0.007, 0.011, 0.023, 0.005, 0.025, 0.156, 0.002, 0.001, 0.003, 0.003, 0.002, 0.014, 0.066, 0.013, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.038, 0.798, 0.007, 0.01, 0.0001, 0.0001, 0.0001, 0.013, 0.006, 0.004, 0.0001, 0.001, 0.012, 0.004, 0.009, 0.006, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.021, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.016, 0.007, 0.069, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ki": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.157, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.033, 0.001, 0.1, 0.001, 0.0001, 0.002, 0.005, 0.051, 0.116, 0.115, 0.0001, 0.0001, 0.384, 0.122, 1.505, 0.04, 0.182, 0.215, 0.151, 0.09, 0.071, 0.091, 0.067, 0.064, 0.059, 0.089, 0.065, 0.003, 0.006, 0.002, 0.008, 0.01, 0.0001, 0.273, 0.233, 0.763, 0.125, 0.089, 0.072, 0.168, 0.139, 0.145, 0.105, 0.364, 0.123, 0.376, 0.291, 0.066, 0.138, 0.046, 0.111, 0.252, 0.278, 0.132, 0.045, 0.093, 0.048, 0.079, 0.058, 0.02, 0.0001, 0.02, 0.0001, 0.015, 0.0001, 10.33, 0.786, 1.541, 0.901, 3.961, 0.163, 2.604, 2.426, 8.641, 0.326, 1.916, 0.633, 2.867, 6.576, 3.627, 0.309, 0.068, 4.492, 0.79, 3.938, 2.525, 0.104, 1.397, 0.085, 2.472, 0.26, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.05, 0.003, 0.002, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.037, 0.01, 0.0001, 0.001, 0.003, 0.0001, 0.001, 0.001, 0.013, 0.005, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.06, 4.809, 0.0001, 0.069, 0.002, 0.006, 0.001, 0.004, 0.016, 0.25, 0.0001, 0.009, 0.003, 0.002, 0.0001, 0.009, 0.003, 0.001, 0.003, 0.026, 0.003, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.021, 0.032, 2.884, 2.321, 0.0001, 0.002, 0.0001, 0.002, 0.021, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.009, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.048, 0.0001, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kj": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.677, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.71, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.323, 0.323, 0.0001, 0.0001, 0.645, 0.0001, 0.323, 0.0001, 1.613, 0.0001, 0.323, 0.323, 0.0001, 0.0001, 0.645, 0.323, 0.0001, 0.0001, 0.968, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.0001, 0.0001, 0.645, 0.0001, 0.0001, 0.323, 0.0001, 2.903, 0.323, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.097, 3.226, 0.0001, 6.774, 6.774, 1.935, 1.29, 2.903, 10.645, 0.0001, 3.226, 3.226, 6.129, 2.581, 8.065, 0.323, 0.0001, 0.0001, 0.968, 0.323, 1.935, 0.645, 2.581, 0.0001, 0.323, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.706, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.721, 0.001, 0.107, 0.001, 0.0001, 0.006, 0.0001, 0.002, 0.151, 0.153, 0.001, 0.003, 0.51, 0.246, 0.686, 0.019, 0.221, 0.251, 0.17, 0.104, 0.092, 0.099, 0.09, 0.082, 0.09, 0.149, 0.04, 0.015, 0.002, 0.003, 0.002, 0.002, 0.0001, 0.007, 0.006, 0.025, 0.003, 0.016, 0.005, 0.021, 0.002, 0.024, 0.001, 0.002, 0.003, 0.008, 0.018, 0.004, 0.01, 0.0001, 0.004, 0.021, 0.003, 0.003, 0.004, 0.004, 0.005, 0.001, 0.003, 0.003, 0.0001, 0.003, 0.0001, 0.002, 0.0001, 0.029, 0.005, 0.01, 0.008, 0.028, 0.004, 0.005, 0.007, 0.042, 0.0001, 0.004, 0.014, 0.009, 0.02, 0.023, 0.007, 0.0001, 0.021, 0.015, 0.017, 0.01, 0.003, 0.003, 0.001, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.667, 1.698, 2.42, 0.825, 0.088, 0.097, 0.101, 0.026, 0.573, 0.004, 0.008, 3.51, 0.092, 0.043, 0.029, 0.226, 0.151, 0.105, 0.034, 0.789, 0.175, 0.042, 2.128, 0.009, 0.046, 0.288, 0.211, 1.223, 0.099, 0.041, 0.082, 0.052, 0.093, 0.104, 0.084, 0.646, 0.032, 0.032, 0.003, 0.007, 0.066, 0.363, 0.0001, 0.047, 0.001, 0.014, 0.013, 0.268, 5.447, 1.26, 0.188, 0.541, 1.919, 3.092, 0.668, 0.583, 0.903, 0.603, 1.169, 2.242, 1.309, 3.102, 1.26, 0.548, 0.0001, 0.0001, 0.145, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 25.612, 14.266, 3.356, 0.697, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.197, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.635, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.811, 0.001, 0.341, 0.0001, 0.0001, 0.006, 0.002, 0.029, 0.34, 0.34, 0.002, 0.001, 0.7, 0.575, 1.063, 0.02, 0.29, 0.457, 0.333, 0.207, 0.125, 0.141, 0.14, 0.129, 0.134, 0.187, 0.161, 0.026, 0.008, 0.005, 0.008, 0.0001, 0.0001, 0.28, 0.09, 0.107, 0.095, 0.075, 0.086, 0.052, 0.078, 0.183, 0.108, 0.243, 0.074, 0.184, 0.254, 0.06, 0.118, 0.079, 0.062, 0.257, 0.166, 0.177, 0.059, 0.032, 0.002, 0.012, 0.015, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 12.711, 0.276, 0.184, 0.432, 3.419, 0.731, 1.669, 0.268, 10.409, 0.217, 2.335, 4.586, 2.81, 6.778, 2.817, 1.735, 2.883, 5.126, 5.68, 6.217, 6.675, 0.652, 0.054, 0.023, 0.144, 0.055, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.031, 0.035, 0.014, 0.011, 0.03, 0.017, 0.013, 0.007, 0.019, 0.003, 0.015, 0.002, 0.011, 0.008, 0.02, 0.004, 0.014, 0.011, 0.007, 0.013, 0.007, 0.01, 0.01, 0.01, 0.008, 0.016, 0.005, 0.005, 0.009, 0.004, 0.004, 0.006, 0.015, 0.021, 0.01, 0.011, 0.03, 0.03, 0.045, 0.038, 0.021, 0.031, 0.02, 0.014, 0.007, 0.018, 0.005, 0.016, 0.035, 0.027, 0.022, 0.024, 0.011, 0.015, 0.016, 0.009, 0.078, 0.018, 0.016, 0.011, 0.01, 0.011, 0.018, 0.012, 0.0001, 0.0001, 0.012, 0.201, 0.031, 0.017, 0.001, 0.001, 0.0001, 0.004, 0.004, 0.004, 0.004, 0.0001, 0.016, 0.008, 0.085, 0.031, 0.0001, 0.001, 0.0001, 0.0001, 0.024, 0.053, 0.13, 0.094, 0.007, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.065, 0.039, 0.022, 0.0001, 0.001, 0.011, 0.007, 0.001, 0.001, 0.003, 0.001, 0.002, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "km": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.234, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.565, 0.004, 0.038, 0.0001, 0.0001, 0.004, 0.0001, 0.009, 0.049, 0.049, 0.0001, 0.001, 0.07, 0.028, 0.072, 0.003, 0.02, 0.022, 0.013, 0.008, 0.007, 0.007, 0.006, 0.006, 0.007, 0.012, 0.008, 0.003, 0.007, 0.012, 0.008, 0.004, 0.0001, 0.018, 0.012, 0.02, 0.008, 0.012, 0.009, 0.007, 0.009, 0.013, 0.004, 0.006, 0.012, 0.012, 0.009, 0.006, 0.011, 0.001, 0.009, 0.018, 0.02, 0.004, 0.004, 0.006, 0.002, 0.002, 0.001, 0.022, 0.0001, 0.022, 0.0001, 0.004, 0.0001, 0.403, 0.068, 0.154, 0.173, 0.554, 0.096, 0.093, 0.2, 0.358, 0.005, 0.025, 0.201, 0.122, 0.348, 0.339, 0.093, 0.005, 0.306, 0.292, 0.378, 0.132, 0.051, 0.059, 0.012, 0.073, 0.006, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.652, 0.801, 0.696, 0.139, 1.351, 0.735, 0.591, 0.836, 0.083, 0.299, 0.563, 1.859, 0.05, 0.041, 0.223, 1.134, 0.273, 0.671, 2.897, 1.707, 1.359, 0.097, 0.57, 0.24, 1.039, 0.72, 1.493, 0.708, 0.482, 0.006, 22.614, 7.802, 0.292, 0.16, 0.416, 0.027, 0.02, 0.041, 0.016, 0.053, 0.015, 0.021, 0.003, 0.006, 0.019, 0.002, 0.004, 0.041, 0.002, 0.021, 0.047, 0.001, 0.001, 0.001, 2.388, 0.829, 0.388, 0.131, 0.053, 0.602, 0.318, 0.199, 0.385, 0.021, 0.0001, 0.0001, 0.017, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 29.306, 1.288, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.22, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.193, 0.001, 0.077, 0.0001, 0.001, 0.006, 0.001, 0.024, 0.05, 0.05, 0.001, 0.001, 0.263, 0.039, 0.387, 0.008, 0.055, 0.048, 0.031, 0.015, 0.013, 0.017, 0.014, 0.014, 0.016, 0.027, 0.012, 0.01, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.007, 0.004, 0.007, 0.004, 0.004, 0.003, 0.002, 0.002, 0.007, 0.001, 0.001, 0.002, 0.005, 0.003, 0.003, 0.004, 0.0001, 0.003, 0.008, 0.004, 0.004, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.001, 0.001, 0.019, 0.003, 0.007, 0.007, 0.022, 0.004, 0.004, 0.008, 0.016, 0.001, 0.002, 0.009, 0.007, 0.014, 0.015, 0.005, 0.0001, 0.014, 0.012, 0.015, 0.006, 0.002, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.377, 1.744, 1.056, 0.052, 0.0001, 0.294, 1.302, 0.476, 0.14, 0.07, 0.25, 0.184, 0.18, 3.237, 0.115, 0.016, 0.01, 0.0001, 0.076, 0.009, 0.004, 1.075, 0.058, 1.134, 0.019, 0.006, 0.205, 0.005, 0.214, 0.004, 0.012, 0.397, 0.02, 0.439, 0.004, 0.214, 1.341, 0.105, 1.57, 0.184, 1.477, 0.01, 0.553, 0.067, 0.408, 0.14, 0.772, 0.936, 1.909, 0.0001, 24.738, 8.223, 0.0001, 1.147, 0.212, 0.182, 0.975, 0.409, 0.0001, 0.0001, 0.001, 0.0001, 1.605, 2.364, 0.0001, 0.0001, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.178, 0.0001, 0.177, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "koi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.5, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.538, 0.003, 0.105, 0.0001, 0.0001, 0.012, 0.0001, 0.066, 0.298, 0.299, 0.001, 0.003, 0.665, 0.135, 0.828, 0.022, 0.193, 0.238, 0.151, 0.096, 0.069, 0.095, 0.069, 0.062, 0.067, 0.14, 0.09, 0.011, 0.011, 0.003, 0.011, 0.012, 0.0001, 0.012, 0.004, 0.007, 0.003, 0.004, 0.002, 0.002, 0.009, 0.016, 0.003, 0.015, 0.007, 0.012, 0.004, 0.018, 0.015, 0.0001, 0.004, 0.016, 0.008, 0.003, 0.011, 0.001, 0.01, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.204, 0.031, 0.062, 0.036, 0.122, 0.007, 0.019, 0.037, 0.201, 0.009, 0.035, 0.077, 0.03, 0.109, 0.075, 0.025, 0.001, 0.099, 0.08, 0.059, 0.07, 0.013, 0.004, 0.003, 0.013, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.529, 2.707, 1.977, 1.216, 0.076, 0.086, 0.043, 0.37, 0.314, 0.008, 0.015, 2.496, 1.151, 0.356, 0.143, 0.67, 0.146, 0.176, 0.113, 0.201, 0.173, 0.031, 0.44, 0.017, 0.071, 0.03, 0.345, 0.07, 0.14, 0.058, 0.096, 0.178, 0.09, 0.17, 0.07, 0.048, 0.048, 0.034, 0.04, 1.604, 0.03, 0.001, 0.001, 0.041, 0.0001, 0.038, 0.042, 0.02, 3.314, 0.375, 1.556, 0.398, 1.638, 1.43, 1.24, 0.859, 1.906, 0.527, 1.802, 1.787, 1.504, 2.903, 2.273, 0.718, 0.0001, 0.0001, 0.079, 0.905, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.021, 0.0001, 0.001, 0.001, 25.357, 14.367, 0.001, 1.602, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.0001, 0.293, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 25.0, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.667, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 8.333, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 8.333, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "krc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.633, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.611, 0.001, 0.078, 0.0001, 0.002, 0.011, 0.0001, 0.002, 0.139, 0.14, 0.0001, 0.001, 0.591, 0.21, 0.542, 0.004, 0.138, 0.24, 0.114, 0.076, 0.067, 0.073, 0.058, 0.056, 0.073, 0.12, 0.04, 0.013, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.004, 0.004, 0.006, 0.003, 0.003, 0.002, 0.003, 0.002, 0.03, 0.001, 0.002, 0.003, 0.004, 0.002, 0.002, 0.002, 0.001, 0.002, 0.005, 0.004, 0.001, 0.01, 0.002, 0.017, 0.0001, 0.001, 0.014, 0.0001, 0.014, 0.0001, 0.001, 0.0001, 0.038, 0.009, 0.012, 0.014, 0.044, 0.006, 0.01, 0.013, 0.029, 0.002, 0.006, 0.019, 0.015, 0.026, 0.027, 0.008, 0.001, 0.031, 0.024, 0.024, 0.014, 0.007, 0.003, 0.002, 0.005, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.564, 1.141, 1.579, 1.633, 0.148, 0.303, 0.164, 0.503, 0.456, 0.003, 1.306, 2.454, 0.134, 0.294, 0.686, 0.418, 0.168, 0.334, 0.032, 0.057, 0.2, 0.019, 0.006, 0.011, 0.056, 0.006, 0.17, 0.03, 0.076, 0.03, 0.044, 0.051, 0.143, 0.104, 0.049, 0.03, 0.04, 0.03, 0.005, 0.024, 0.052, 0.001, 0.001, 0.061, 0.001, 0.035, 0.01, 0.009, 6.121, 1.252, 0.294, 1.328, 2.359, 2.412, 0.507, 0.442, 2.779, 0.471, 1.691, 3.418, 1.039, 3.402, 1.301, 0.302, 0.0001, 0.0001, 0.209, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.0001, 0.006, 0.002, 30.423, 13.816, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.14, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ks": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.09, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.116, 0.0001, 0.395, 0.007, 0.0001, 0.0001, 0.004, 0.023, 0.126, 0.124, 0.0001, 0.001, 0.08, 0.153, 0.257, 0.005, 0.042, 0.08, 0.041, 0.04, 0.021, 0.031, 0.018, 0.019, 0.02, 0.048, 0.059, 0.003, 0.053, 0.167, 0.053, 0.0001, 0.0001, 0.005, 0.003, 0.008, 0.007, 0.01, 0.007, 0.001, 0.002, 0.016, 0.003, 0.003, 0.003, 0.004, 0.019, 0.008, 0.002, 0.0001, 0.005, 0.01, 0.013, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.198, 0.016, 0.127, 0.13, 0.17, 0.01, 0.074, 0.033, 0.171, 0.002, 0.016, 0.235, 0.092, 0.256, 0.101, 0.014, 0.0001, 0.218, 0.145, 0.254, 0.031, 0.065, 0.054, 0.0001, 0.012, 0.0001, 0.0001, 0.009, 0.0001, 0.0001, 0.0001, 0.451, 1.562, 0.534, 0.248, 1.154, 1.571, 2.211, 0.263, 1.281, 0.132, 0.341, 0.16, 1.683, 0.702, 0.993, 0.637, 0.623, 0.052, 0.37, 0.043, 0.331, 0.813, 0.313, 0.319, 0.042, 0.007, 0.092, 0.282, 0.326, 0.013, 0.006, 0.065, 0.245, 0.114, 0.179, 0.083, 8.684, 2.577, 0.461, 2.698, 1.217, 0.995, 1.306, 0.114, 0.545, 0.242, 0.666, 1.253, 0.811, 1.543, 0.848, 0.915, 0.434, 0.417, 0.188, 0.11, 0.481, 0.73, 0.156, 0.08, 0.312, 0.004, 2.104, 0.512, 0.0001, 0.0001, 0.188, 0.0001, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.031, 0.0001, 0.008, 0.002, 0.028, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.045, 10.482, 2.72, 3.264, 0.0001, 0.0001, 0.0001, 0.0001, 10.717, 0.001, 0.078, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.129, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ksh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.3, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.544, 0.007, 0.195, 0.001, 0.0001, 0.006, 0.002, 0.064, 0.077, 0.076, 0.018, 0.0001, 0.951, 0.126, 1.237, 0.01, 0.258, 0.351, 0.176, 0.091, 0.09, 0.099, 0.083, 0.083, 0.116, 0.206, 0.046, 0.013, 0.003, 0.002, 0.003, 0.004, 0.0001, 0.29, 0.361, 0.086, 0.549, 0.218, 0.205, 0.059, 0.258, 0.102, 0.404, 0.343, 0.228, 0.359, 0.191, 0.138, 0.226, 0.009, 0.194, 0.601, 0.11, 0.081, 0.179, 0.232, 0.004, 0.009, 0.121, 0.015, 0.0001, 0.017, 0.0001, 0.132, 0.0001, 4.203, 0.771, 2.07, 4.046, 9.612, 0.707, 0.863, 3.367, 3.374, 1.363, 1.028, 2.762, 2.009, 5.309, 3.906, 0.798, 0.006, 4.302, 3.629, 3.86, 2.108, 1.453, 1.005, 0.049, 0.079, 0.749, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.123, 0.002, 0.002, 0.001, 0.082, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.005, 0.0001, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.005, 0.011, 0.0001, 0.082, 0.036, 0.001, 0.009, 0.0001, 0.001, 0.047, 0.002, 0.044, 0.413, 0.03, 0.004, 0.001, 0.001, 1.721, 0.001, 0.004, 0.002, 0.003, 0.013, 0.001, 0.084, 0.001, 0.002, 0.0001, 0.008, 0.003, 0.001, 0.005, 0.025, 0.002, 0.001, 1.538, 0.002, 0.001, 0.001, 0.002, 0.003, 0.531, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.029, 4.494, 0.051, 0.013, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.124, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ku": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.393, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.949, 0.005, 0.256, 0.0001, 0.0001, 0.006, 0.001, 0.113, 0.21, 0.21, 0.006, 0.003, 0.803, 0.095, 1.083, 0.023, 0.197, 0.26, 0.139, 0.073, 0.067, 0.078, 0.071, 0.068, 0.08, 0.162, 0.084, 0.022, 0.008, 0.003, 0.008, 0.006, 0.0001, 0.192, 0.235, 0.084, 0.253, 0.208, 0.064, 0.107, 0.175, 0.032, 0.081, 0.247, 0.144, 0.22, 0.115, 0.035, 0.144, 0.05, 0.104, 0.203, 0.123, 0.017, 0.026, 0.063, 0.071, 0.053, 0.061, 0.009, 0.0001, 0.009, 0.0001, 0.003, 0.002, 7.122, 1.894, 0.369, 2.998, 7.334, 0.296, 0.895, 1.263, 5.92, 0.932, 2.612, 1.973, 1.601, 5.257, 1.434, 0.604, 0.177, 4.384, 1.643, 2.193, 1.071, 1.195, 1.296, 0.608, 2.23, 0.722, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.075, 0.006, 0.004, 0.007, 0.009, 0.007, 0.012, 0.062, 0.012, 0.002, 0.018, 0.001, 0.015, 0.003, 0.068, 0.002, 0.001, 0.001, 0.002, 0.006, 0.001, 0.004, 0.003, 0.001, 0.007, 0.019, 0.001, 0.009, 0.013, 0.012, 0.074, 0.658, 0.013, 0.005, 0.004, 0.002, 0.003, 0.002, 0.004, 0.335, 0.008, 0.015, 3.587, 0.004, 0.003, 0.008, 2.776, 0.007, 0.009, 0.038, 0.007, 0.007, 0.016, 0.003, 0.007, 0.002, 0.005, 0.004, 0.005, 1.203, 0.019, 0.003, 0.004, 0.002, 0.0001, 0.0001, 0.03, 8.061, 0.042, 0.73, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.01, 0.005, 0.017, 0.006, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.063, 0.061, 0.005, 0.012, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.006, 0.073, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.403, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.572, 0.002, 0.112, 0.0001, 0.0001, 0.004, 0.0001, 0.006, 0.253, 0.254, 0.001, 0.001, 0.652, 0.237, 0.796, 0.019, 0.199, 0.362, 0.176, 0.114, 0.094, 0.095, 0.085, 0.09, 0.105, 0.228, 0.059, 0.022, 0.003, 0.001, 0.004, 0.001, 0.0001, 0.008, 0.005, 0.011, 0.005, 0.005, 0.004, 0.005, 0.005, 0.02, 0.004, 0.011, 0.006, 0.006, 0.007, 0.004, 0.005, 0.002, 0.005, 0.011, 0.006, 0.004, 0.008, 0.003, 0.013, 0.003, 0.002, 0.039, 0.0001, 0.039, 0.0001, 0.0001, 0.0001, 0.115, 0.019, 0.016, 0.027, 0.069, 0.009, 0.022, 0.03, 0.155, 0.012, 0.027, 0.043, 0.035, 0.068, 0.048, 0.017, 0.005, 0.048, 0.041, 0.048, 0.044, 0.012, 0.013, 0.005, 0.014, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.292, 3.131, 1.711, 1.163, 0.094, 0.093, 0.068, 0.394, 0.316, 0.013, 0.283, 2.417, 0.996, 0.157, 0.138, 0.933, 0.185, 0.144, 0.161, 0.163, 0.266, 0.043, 0.288, 0.024, 0.072, 0.036, 0.257, 0.079, 0.116, 0.07, 0.051, 0.125, 0.115, 0.273, 0.082, 0.056, 0.037, 0.021, 0.028, 2.085, 0.052, 0.007, 0.009, 0.112, 0.005, 0.032, 0.025, 0.019, 3.353, 0.487, 1.618, 0.507, 1.803, 1.293, 0.994, 0.555, 1.916, 0.692, 1.739, 1.936, 1.41, 2.819, 2.119, 0.641, 0.0001, 0.0001, 0.211, 0.665, 0.015, 0.015, 0.006, 0.004, 0.002, 0.021, 0.019, 0.013, 0.017, 0.003, 0.013, 0.006, 25.09, 14.142, 0.006, 2.075, 0.003, 0.001, 0.001, 0.003, 0.01, 0.008, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.016, 0.023, 0.303, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "kw": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.271, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.698, 0.003, 0.428, 0.0001, 0.0001, 0.066, 0.001, 0.379, 0.501, 0.501, 0.001, 0.001, 1.043, 0.466, 1.444, 0.019, 0.602, 0.995, 0.55, 0.31, 0.288, 0.284, 0.283, 0.29, 0.333, 0.472, 0.076, 0.113, 0.013, 0.003, 0.013, 0.002, 0.0001, 0.413, 0.261, 0.217, 0.211, 0.211, 0.117, 0.24, 0.182, 0.089, 0.078, 0.627, 0.279, 0.264, 0.166, 0.089, 0.271, 0.018, 0.16, 0.497, 0.182, 0.13, 0.12, 0.167, 0.003, 0.325, 0.009, 0.005, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 7.247, 1.102, 0.333, 2.599, 6.963, 0.397, 1.527, 3.863, 2.585, 0.151, 1.745, 2.596, 1.638, 6.936, 4.292, 0.693, 0.011, 4.812, 4.449, 2.907, 1.185, 1.044, 2.706, 0.022, 4.495, 0.043, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.063, 0.013, 0.005, 0.007, 0.005, 0.004, 0.003, 0.003, 0.006, 0.002, 0.002, 0.001, 0.003, 0.005, 0.002, 0.002, 0.003, 0.003, 0.001, 0.033, 0.004, 0.002, 0.002, 0.004, 0.004, 0.02, 0.001, 0.001, 0.003, 0.002, 0.001, 0.002, 0.025, 0.014, 0.004, 0.005, 0.015, 0.004, 0.003, 0.007, 0.004, 0.018, 0.007, 0.005, 0.002, 0.009, 0.005, 0.004, 0.012, 0.007, 0.012, 0.009, 0.008, 0.009, 0.007, 0.003, 0.012, 0.008, 0.009, 0.008, 0.006, 0.007, 0.012, 0.004, 0.0001, 0.0001, 0.028, 0.1, 0.011, 0.012, 0.0001, 0.001, 0.0001, 0.007, 0.003, 0.004, 0.004, 0.0001, 0.012, 0.004, 0.062, 0.02, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.004, 0.013, 0.011, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.013, 0.007, 0.058, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ky": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.608, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.786, 0.001, 0.076, 0.0001, 0.0001, 0.007, 0.001, 0.001, 0.181, 0.185, 0.0001, 0.003, 0.592, 0.375, 0.793, 0.011, 0.212, 0.26, 0.154, 0.095, 0.087, 0.095, 0.083, 0.081, 0.088, 0.165, 0.05, 0.023, 0.024, 0.003, 0.024, 0.002, 0.0001, 0.006, 0.009, 0.006, 0.003, 0.002, 0.01, 0.002, 0.004, 0.023, 0.001, 0.001, 0.003, 0.004, 0.009, 0.004, 0.011, 0.0001, 0.003, 0.019, 0.005, 0.001, 0.003, 0.002, 0.004, 0.001, 0.0001, 0.007, 0.0001, 0.008, 0.0001, 0.002, 0.0001, 0.034, 0.028, 0.011, 0.01, 0.036, 0.004, 0.007, 0.01, 0.029, 0.001, 0.005, 0.017, 0.009, 0.023, 0.028, 0.008, 0.001, 0.047, 0.02, 0.022, 0.013, 0.003, 0.003, 0.002, 0.006, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 2.775, 1.184, 2.443, 1.907, 0.113, 0.08, 0.128, 0.561, 0.622, 0.004, 0.005, 2.414, 0.086, 0.264, 0.107, 0.368, 0.184, 0.149, 0.029, 0.1, 0.146, 0.009, 0.06, 0.008, 0.039, 0.003, 0.233, 0.023, 0.133, 0.051, 0.082, 0.045, 0.072, 0.109, 0.101, 0.162, 0.039, 0.017, 0.003, 0.031, 0.045, 0.843, 0.0001, 0.06, 0.001, 0.049, 0.011, 1.059, 5.238, 0.934, 0.249, 1.237, 1.665, 2.222, 0.662, 0.522, 2.314, 0.665, 2.431, 2.219, 1.157, 3.498, 1.756, 0.567, 0.0001, 0.0001, 0.135, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 28.842, 12.881, 1.192, 0.856, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.186, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "la": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.703, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.582, 0.002, 0.557, 0.0001, 0.0001, 0.004, 0.001, 0.038, 0.296, 0.296, 0.016, 0.002, 1.029, 0.127, 0.917, 0.01, 0.288, 0.518, 0.368, 0.158, 0.135, 0.172, 0.155, 0.139, 0.169, 0.292, 0.103, 0.058, 0.002, 0.004, 0.002, 0.002, 0.0001, 0.441, 0.179, 0.385, 0.16, 0.131, 0.176, 0.158, 0.144, 0.363, 0.023, 0.04, 0.184, 0.266, 0.121, 0.103, 0.293, 0.049, 0.202, 0.319, 0.152, 0.063, 0.122, 0.033, 0.022, 0.01, 0.013, 0.004, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 7.718, 1.137, 2.983, 1.877, 7.832, 0.566, 0.934, 0.721, 8.862, 0.018, 0.079, 2.703, 3.638, 5.533, 4.661, 1.753, 0.47, 5.095, 5.379, 5.968, 5.347, 0.814, 0.036, 0.291, 0.205, 0.069, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.045, 0.018, 0.011, 0.014, 0.009, 0.005, 0.004, 0.005, 0.004, 0.018, 0.002, 0.002, 0.005, 0.007, 0.002, 0.002, 0.004, 0.003, 0.002, 0.014, 0.007, 0.002, 0.002, 0.002, 0.003, 0.004, 0.003, 0.002, 0.004, 0.003, 0.003, 0.004, 0.013, 0.011, 0.004, 0.003, 0.009, 0.004, 0.004, 0.006, 0.01, 0.02, 0.004, 0.013, 0.003, 0.007, 0.003, 0.005, 0.044, 0.013, 0.009, 0.008, 0.006, 0.012, 0.008, 0.005, 0.014, 0.01, 0.011, 0.011, 0.013, 0.014, 0.01, 0.01, 0.0001, 0.0001, 0.047, 0.083, 0.019, 0.012, 0.0001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.062, 0.03, 0.07, 0.024, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.005, 0.012, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 0.015, 0.037, 0.003, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lad": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.233, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.114, 0.001, 0.334, 0.0001, 0.0001, 0.009, 0.001, 0.032, 0.169, 0.169, 0.0001, 0.0001, 1.028, 0.087, 0.763, 0.008, 0.237, 0.25, 0.147, 0.074, 0.074, 0.086, 0.072, 0.065, 0.078, 0.138, 0.053, 0.043, 0.005, 0.001, 0.005, 0.001, 0.0001, 0.303, 0.15, 0.122, 0.124, 0.422, 0.07, 0.094, 0.073, 0.145, 0.052, 0.173, 0.269, 0.273, 0.076, 0.097, 0.169, 0.01, 0.114, 0.279, 0.178, 0.068, 0.08, 0.015, 0.026, 0.054, 0.024, 0.01, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 10.092, 0.654, 0.428, 4.329, 9.389, 0.52, 0.701, 0.524, 5.468, 0.466, 2.315, 4.475, 1.912, 5.533, 6.266, 1.56, 0.038, 4.367, 5.784, 3.223, 2.47, 1.069, 0.027, 0.043, 1.039, 0.561, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.02, 0.012, 0.005, 0.005, 0.009, 0.006, 0.004, 0.004, 0.005, 0.003, 0.006, 0.002, 0.002, 0.003, 0.003, 0.001, 0.015, 0.012, 0.004, 0.011, 0.018, 0.019, 0.004, 0.004, 0.007, 0.031, 0.002, 0.006, 0.016, 0.006, 0.01, 0.011, 0.017, 0.14, 0.008, 0.005, 0.006, 0.003, 0.003, 0.02, 0.02, 0.11, 0.013, 0.01, 0.003, 0.09, 0.002, 0.005, 0.012, 0.024, 0.019, 0.137, 0.008, 0.006, 0.005, 0.006, 0.008, 0.006, 0.03, 0.011, 0.011, 0.004, 0.004, 0.004, 0.0001, 0.0001, 0.044, 0.511, 0.018, 0.013, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.017, 0.007, 0.023, 0.009, 0.0001, 0.0001, 0.0001, 0.005, 0.02, 0.199, 0.037, 0.028, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.006, 0.018, 0.0001, 0.001, 0.003, 0.002, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.412, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.95, 0.002, 0.355, 0.0001, 0.0001, 0.008, 0.002, 0.417, 0.145, 0.146, 0.001, 0.003, 0.802, 0.307, 1.03, 0.016, 0.348, 0.52, 0.266, 0.139, 0.134, 0.143, 0.128, 0.134, 0.162, 0.294, 0.059, 0.012, 0.015, 0.003, 0.015, 0.001, 0.0001, 0.428, 0.324, 0.254, 0.594, 0.233, 0.259, 0.289, 0.233, 0.12, 0.196, 0.27, 0.284, 0.379, 0.192, 0.132, 0.314, 0.012, 0.243, 0.585, 0.165, 0.101, 0.142, 0.167, 0.006, 0.01, 0.098, 0.005, 0.0001, 0.005, 0.0001, 0.003, 0.0001, 4.931, 0.886, 1.95, 2.841, 11.151, 0.974, 2.202, 2.438, 4.449, 0.072, 0.85, 2.736, 2.142, 6.511, 2.976, 0.873, 0.044, 5.369, 4.192, 4.448, 3.418, 0.952, 0.815, 0.087, 0.179, 0.783, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.039, 0.004, 0.003, 0.002, 0.022, 0.001, 0.001, 0.002, 0.001, 0.016, 0.001, 0.02, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.012, 0.001, 0.0001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.01, 0.002, 0.008, 0.002, 0.053, 0.005, 0.005, 0.001, 0.485, 0.001, 0.003, 0.007, 0.029, 0.959, 0.004, 0.541, 0.001, 0.003, 0.002, 0.002, 0.009, 0.004, 0.006, 0.005, 0.01, 0.003, 0.01, 0.001, 0.004, 0.002, 0.003, 0.005, 0.046, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.061, 2.169, 0.003, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 0.004, 0.024, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.037, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lbe": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.255, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.9, 0.001, 0.252, 0.0001, 0.0001, 0.001, 0.0001, 0.011, 0.416, 0.416, 0.0001, 0.003, 0.481, 0.136, 0.815, 0.07, 0.265, 0.236, 0.199, 0.107, 0.105, 0.116, 0.098, 0.098, 0.121, 0.12, 0.136, 0.067, 0.071, 0.002, 0.067, 0.006, 0.0001, 0.016, 0.004, 0.021, 0.002, 0.004, 0.005, 0.004, 0.003, 0.485, 0.0001, 0.002, 0.006, 0.012, 0.003, 0.003, 0.014, 0.001, 0.005, 0.011, 0.004, 0.002, 0.006, 0.002, 0.003, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.216, 0.084, 0.071, 0.045, 0.128, 0.01, 0.022, 0.031, 0.155, 0.002, 0.014, 0.09, 0.049, 0.088, 0.086, 0.051, 0.003, 0.174, 0.114, 0.069, 0.102, 0.012, 0.003, 0.009, 0.024, 0.006, 0.001, 0.001, 0.001, 0.001, 0.0001, 3.391, 1.985, 1.311, 3.41, 0.076, 1.237, 0.309, 0.579, 0.377, 0.095, 0.645, 0.087, 1.158, 0.044, 0.125, 0.671, 0.313, 0.089, 0.058, 0.221, 0.212, 0.014, 0.015, 0.044, 0.077, 0.005, 0.185, 0.069, 0.144, 0.054, 0.029, 0.04, 0.037, 0.075, 0.123, 0.038, 0.018, 0.116, 0.052, 0.091, 0.05, 0.027, 0.003, 0.033, 0.004, 0.04, 0.009, 0.029, 7.018, 0.742, 1.169, 0.714, 1.012, 0.485, 0.137, 0.404, 2.976, 0.818, 1.445, 2.805, 1.012, 2.921, 0.476, 0.297, 0.0001, 0.0001, 0.062, 0.008, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 26.245, 14.532, 0.0001, 0.534, 0.0001, 0.001, 0.0001, 0.009, 0.088, 0.067, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.019, 0.318, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lez": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.788, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.917, 0.001, 0.11, 0.0001, 0.0001, 0.014, 0.0001, 0.0001, 0.118, 0.119, 0.0001, 0.001, 0.531, 0.18, 0.599, 0.004, 0.16, 0.227, 0.133, 0.076, 0.063, 0.071, 0.067, 0.062, 0.08, 0.115, 0.048, 0.01, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.003, 0.002, 0.005, 0.001, 0.002, 0.001, 0.001, 0.001, 0.351, 0.0001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.01, 0.001, 0.037, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.023, 0.003, 0.006, 0.005, 0.017, 0.002, 0.004, 0.004, 0.014, 0.001, 0.003, 0.017, 0.004, 0.011, 0.011, 0.005, 0.0001, 0.013, 0.01, 0.009, 0.009, 0.002, 0.001, 0.001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.387, 1.088, 1.449, 2.206, 0.197, 0.805, 0.228, 0.469, 0.264, 0.003, 0.696, 0.03, 1.797, 0.123, 0.075, 0.643, 0.214, 0.062, 0.057, 0.099, 0.243, 0.013, 0.01, 0.016, 0.072, 0.013, 0.197, 0.034, 0.095, 0.027, 0.015, 0.041, 0.182, 0.109, 0.046, 0.053, 0.025, 0.087, 0.024, 0.038, 0.035, 0.001, 0.001, 0.075, 0.001, 0.022, 0.007, 0.017, 6.908, 0.463, 1.591, 1.254, 1.853, 1.815, 0.195, 0.884, 4.344, 1.376, 1.744, 1.947, 0.879, 2.868, 0.597, 0.413, 0.0001, 0.0001, 0.264, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.007, 0.0001, 0.004, 0.002, 30.62, 13.045, 0.0001, 0.248, 0.0001, 0.001, 0.0001, 0.001, 0.004, 0.007, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.149, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.42, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.857, 0.039, 0.098, 0.0001, 0.0001, 0.008, 0.0001, 0.193, 0.619, 0.652, 0.006, 0.013, 0.576, 0.063, 0.759, 0.031, 0.142, 0.149, 0.106, 0.065, 0.048, 0.064, 0.043, 0.046, 0.035, 0.039, 0.112, 0.029, 0.002, 0.038, 0.003, 0.025, 0.0001, 0.202, 0.147, 0.077, 0.032, 0.406, 0.021, 0.082, 0.019, 0.071, 0.01, 0.184, 0.083, 0.172, 0.138, 0.35, 0.039, 0.002, 0.027, 0.089, 0.063, 0.041, 0.016, 0.06, 0.001, 0.036, 0.019, 0.012, 0.0001, 0.012, 0.0001, 0.01, 0.001, 11.513, 4.158, 0.451, 1.382, 6.569, 0.546, 2.789, 0.349, 6.274, 0.363, 4.548, 2.809, 3.269, 5.614, 5.854, 0.404, 0.013, 2.198, 2.205, 2.706, 6.16, 0.367, 2.254, 0.045, 2.427, 1.395, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 1.181, 0.001, 0.015, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.0001, 0.0001, 0.0001, 0.006, 0.008, 0.842, 0.001, 0.0001, 0.092, 0.085, 0.0001, 0.0001, 0.001, 0.001, 0.113, 0.0001, 0.0001, 0.0001, 0.017, 0.01, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.006, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.181, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.019, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "li": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.944, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.135, 0.002, 0.418, 0.0001, 0.0001, 0.017, 0.001, 1.033, 0.22, 0.22, 0.002, 0.001, 0.717, 0.245, 0.974, 0.02, 0.269, 0.322, 0.176, 0.093, 0.094, 0.096, 0.096, 0.091, 0.103, 0.161, 0.092, 0.054, 0.018, 0.002, 0.018, 0.001, 0.0001, 0.18, 0.177, 0.097, 0.347, 0.099, 0.066, 0.119, 0.148, 0.188, 0.05, 0.105, 0.134, 0.157, 0.158, 0.108, 0.098, 0.003, 0.104, 0.185, 0.093, 0.028, 0.141, 0.105, 0.003, 0.004, 0.083, 0.008, 0.001, 0.008, 0.0001, 0.0001, 0.001, 5.507, 1.139, 0.937, 3.64, 13.741, 0.575, 2.233, 1.264, 5.103, 1.163, 1.751, 2.989, 1.798, 6.008, 4.376, 1.144, 0.011, 4.793, 3.527, 4.666, 1.997, 1.767, 1.153, 0.045, 0.112, 0.704, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.031, 0.005, 0.002, 0.002, 0.002, 0.002, 0.001, 0.001, 0.004, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.01, 0.001, 0.0001, 0.002, 0.0001, 0.007, 0.018, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.002, 0.004, 0.007, 0.003, 0.002, 0.113, 0.003, 0.001, 0.003, 0.424, 0.024, 0.004, 0.246, 0.001, 0.004, 0.001, 0.014, 0.003, 0.003, 0.027, 0.238, 0.005, 0.002, 0.354, 0.001, 0.005, 0.003, 0.003, 0.002, 0.014, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.028, 1.471, 0.005, 0.005, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.001, 0.001, 0.0001, 0.01, 0.004, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.031, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lij": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.115, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.653, 0.006, 0.425, 0.0001, 0.0001, 0.003, 0.001, 1.006, 0.211, 0.212, 0.0001, 0.0001, 1.079, 0.522, 0.689, 0.013, 0.183, 0.34, 0.145, 0.099, 0.1, 0.107, 0.089, 0.101, 0.099, 0.127, 0.107, 0.071, 0.08, 0.003, 0.08, 0.006, 0.0001, 0.288, 0.108, 0.216, 0.12, 0.091, 0.089, 0.116, 0.025, 0.235, 0.016, 0.018, 0.145, 0.148, 0.083, 0.128, 0.166, 0.021, 0.11, 0.224, 0.097, 0.053, 0.082, 0.012, 0.025, 0.004, 0.066, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.001, 7.807, 0.66, 2.955, 3.041, 7.727, 0.79, 1.509, 0.643, 7.15, 0.033, 0.062, 2.465, 2.057, 5.516, 6.662, 1.83, 0.232, 3.742, 3.269, 4.498, 2.078, 1.097, 0.032, 0.327, 0.052, 0.447, 0.0001, 0.015, 0.0001, 0.0001, 0.0001, 0.126, 0.011, 0.006, 0.006, 0.007, 0.003, 0.005, 0.015, 0.003, 0.004, 0.003, 0.001, 0.004, 0.006, 0.001, 0.002, 0.001, 0.002, 0.007, 0.108, 0.002, 0.001, 0.003, 0.001, 0.007, 0.097, 0.001, 0.002, 0.005, 0.004, 0.001, 0.001, 0.105, 0.013, 0.443, 0.002, 0.076, 0.002, 0.52, 0.668, 0.246, 0.118, 0.122, 0.032, 0.129, 0.012, 0.108, 0.033, 0.028, 0.081, 0.222, 0.058, 0.152, 0.005, 0.088, 0.002, 0.006, 0.059, 0.022, 0.1, 0.117, 0.007, 0.005, 0.013, 0.0001, 0.0001, 0.059, 3.444, 0.014, 0.118, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.003, 0.0001, 0.026, 0.013, 0.031, 0.013, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.016, 0.012, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.009, 0.005, 0.121, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lmo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.694, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.003, 0.007, 0.496, 0.0001, 0.002, 0.011, 0.001, 1.536, 0.286, 0.286, 0.0001, 0.001, 1.048, 0.242, 0.905, 0.061, 0.214, 0.291, 0.19, 0.13, 0.124, 0.121, 0.109, 0.107, 0.118, 0.137, 0.12, 0.041, 0.23, 0.036, 0.23, 0.004, 0.0001, 0.256, 0.222, 0.29, 0.092, 0.333, 0.125, 0.138, 0.035, 0.151, 0.022, 0.022, 0.325, 0.213, 0.07, 0.062, 0.237, 0.013, 0.158, 0.284, 0.115, 0.042, 0.131, 0.03, 0.012, 0.005, 0.017, 0.008, 0.0001, 0.008, 0.0001, 0.008, 0.0001, 8.462, 0.843, 2.691, 3.762, 7.44, 0.686, 1.303, 1.109, 4.912, 0.086, 0.225, 4.93, 2.005, 5.17, 2.753, 1.529, 0.12, 4.31, 3.255, 3.626, 1.912, 0.803, 0.038, 0.028, 0.061, 0.501, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.065, 0.004, 0.005, 0.004, 0.003, 0.002, 0.001, 0.001, 0.002, 0.003, 0.001, 0.002, 0.002, 0.003, 0.001, 0.001, 0.001, 0.001, 0.002, 0.011, 0.002, 0.0001, 0.002, 0.001, 0.012, 0.042, 0.001, 0.001, 0.018, 0.002, 0.001, 0.003, 0.883, 0.012, 0.006, 0.001, 0.021, 0.001, 0.002, 0.005, 0.978, 0.311, 0.003, 0.015, 0.376, 0.025, 0.002, 0.002, 0.004, 0.005, 0.393, 0.184, 0.028, 0.003, 0.199, 0.002, 0.003, 0.227, 0.023, 0.007, 0.722, 0.004, 0.002, 0.004, 0.0001, 0.0001, 0.146, 4.287, 0.005, 0.015, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.019, 0.008, 0.013, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.061, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ln": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.397, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.893, 0.03, 0.25, 0.011, 0.001, 0.018, 0.001, 0.058, 0.196, 0.195, 0.019, 0.0001, 0.627, 0.278, 0.997, 0.017, 0.237, 0.316, 0.167, 0.077, 0.074, 0.095, 0.09, 0.07, 0.092, 0.208, 0.084, 0.022, 0.031, 0.028, 0.031, 0.008, 0.0001, 0.272, 0.381, 0.139, 0.08, 0.273, 0.07, 0.073, 0.036, 0.085, 0.047, 0.397, 0.244, 0.485, 0.279, 0.076, 0.136, 0.004, 0.069, 0.216, 0.116, 0.035, 0.048, 0.05, 0.005, 0.052, 0.034, 0.014, 0.018, 0.014, 0.0001, 0.004, 0.0001, 10.636, 2.915, 0.49, 0.988, 4.562, 0.3, 1.532, 0.289, 5.022, 0.059, 3.253, 3.932, 3.872, 5.27, 5.607, 1.218, 0.071, 1.319, 2.651, 2.571, 1.582, 0.27, 0.506, 0.061, 2.255, 1.262, 0.0001, 0.013, 0.0001, 0.0001, 0.0001, 0.045, 0.425, 0.034, 0.001, 0.004, 0.002, 0.016, 0.0001, 0.002, 0.009, 0.003, 0.0001, 0.047, 0.002, 0.03, 0.0001, 0.012, 0.0001, 0.122, 0.011, 0.585, 0.0001, 0.0001, 0.0001, 0.001, 0.025, 0.001, 0.584, 0.003, 0.002, 0.001, 0.0001, 0.21, 1.199, 0.019, 0.009, 0.001, 0.001, 0.002, 0.013, 0.036, 1.009, 0.021, 0.019, 0.002, 0.983, 0.006, 0.015, 0.003, 0.003, 0.005, 0.692, 0.016, 0.003, 0.001, 0.001, 0.001, 0.002, 0.332, 0.02, 0.002, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.228, 4.372, 0.034, 0.004, 0.008, 0.141, 0.0001, 1.137, 0.001, 0.001, 0.5, 0.0001, 0.009, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.014, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.057, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.442, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.079, 0.001, 0.049, 0.0001, 0.0001, 0.006, 0.0001, 0.004, 0.071, 0.071, 0.001, 0.001, 0.152, 0.034, 0.234, 0.012, 0.09, 0.111, 0.08, 0.044, 0.039, 0.045, 0.029, 0.03, 0.029, 0.051, 0.034, 0.006, 0.003, 0.002, 0.003, 0.001, 0.0001, 0.013, 0.008, 0.01, 0.008, 0.006, 0.005, 0.004, 0.005, 0.01, 0.003, 0.004, 0.008, 0.008, 0.007, 0.003, 0.012, 0.0001, 0.005, 0.013, 0.013, 0.003, 0.004, 0.004, 0.001, 0.001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.157, 0.027, 0.063, 0.059, 0.202, 0.033, 0.037, 0.067, 0.14, 0.003, 0.015, 0.078, 0.05, 0.13, 0.139, 0.039, 0.002, 0.117, 0.112, 0.142, 0.055, 0.018, 0.023, 0.006, 0.028, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.694, 1.8, 0.562, 0.336, 0.72, 0.0001, 0.034, 1.352, 1.675, 1.044, 0.455, 0.525, 0.031, 0.727, 0.002, 0.001, 0.005, 0.004, 0.004, 0.01, 1.254, 0.484, 0.162, 0.734, 0.009, 2.294, 0.653, 0.586, 0.209, 0.092, 0.491, 0.038, 0.022, 1.013, 0.148, 0.224, 0.003, 0.796, 0.001, 0.85, 0.016, 0.008, 0.816, 0.509, 0.001, 1.145, 0.216, 0.004, 1.227, 1.202, 2.293, 0.24, 0.573, 0.78, 0.113, 0.39, 1.673, 0.52, 24.114, 5.723, 0.116, 0.133, 0.001, 0.0001, 0.0001, 0.0001, 0.085, 0.006, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.829, 0.002, 0.538, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "lrc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.503, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.494, 0.003, 0.04, 0.0001, 0.0001, 0.008, 0.0001, 0.002, 0.084, 0.084, 0.002, 0.001, 0.009, 0.028, 0.484, 0.015, 0.026, 0.035, 0.019, 0.017, 0.01, 0.011, 0.009, 0.009, 0.015, 0.017, 0.04, 0.001, 0.009, 0.002, 0.009, 0.0001, 0.0001, 0.006, 0.003, 0.003, 0.006, 0.003, 0.002, 0.001, 0.002, 0.005, 0.001, 0.002, 0.002, 0.003, 0.002, 0.001, 0.003, 0.0001, 0.002, 0.003, 0.003, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.003, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.043, 0.006, 0.016, 0.023, 0.041, 0.004, 0.008, 0.011, 0.044, 0.001, 0.008, 0.022, 0.01, 0.037, 0.028, 0.011, 0.001, 0.026, 0.016, 0.024, 0.015, 0.007, 0.006, 0.002, 0.007, 0.003, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.141, 0.397, 0.205, 0.02, 1.605, 1.614, 3.115, 2.266, 3.47, 0.018, 0.099, 0.005, 5.078, 0.005, 0.021, 0.008, 0.02, 0.003, 0.001, 0.004, 0.007, 0.374, 0.0001, 0.001, 0.02, 0.38, 0.001, 0.042, 0.001, 0.001, 0.001, 0.003, 0.001, 0.003, 0.35, 0.86, 0.5, 0.014, 1.898, 5.042, 0.917, 1.365, 1.804, 0.048, 0.445, 0.131, 0.29, 3.021, 0.146, 3.091, 0.704, 1.565, 1.062, 0.145, 0.062, 0.1, 0.06, 0.212, 0.059, 0.025, 0.002, 0.001, 0.485, 0.001, 0.0001, 0.0001, 0.044, 0.006, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.001, 0.017, 0.007, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.007, 20.669, 13.379, 3.076, 5.814, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.002, 0.138, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ltg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.505, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.915, 0.002, 0.48, 0.0001, 0.0001, 0.03, 0.001, 0.011, 0.307, 0.306, 0.001, 0.001, 1.036, 0.186, 1.128, 0.03, 0.246, 0.429, 0.198, 0.13, 0.123, 0.148, 0.107, 0.108, 0.116, 0.317, 0.161, 0.072, 0.029, 0.005, 0.029, 0.004, 0.0001, 0.199, 0.123, 0.06, 0.183, 0.07, 0.028, 0.064, 0.021, 0.12, 0.092, 0.204, 0.323, 0.133, 0.101, 0.065, 0.288, 0.001, 0.16, 0.239, 0.103, 0.036, 0.21, 0.007, 0.022, 0.001, 0.052, 0.002, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 7.469, 0.962, 0.824, 2.269, 4.253, 0.17, 1.648, 0.088, 6.306, 1.422, 2.423, 2.524, 1.996, 2.559, 4.514, 1.853, 0.001, 3.554, 6.061, 4.103, 4.999, 1.941, 0.013, 0.006, 1.629, 1.118, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.287, 1.24, 0.018, 0.009, 0.002, 0.008, 0.371, 0.004, 0.003, 0.001, 0.001, 0.004, 0.014, 0.08, 0.001, 0.011, 0.003, 0.002, 0.002, 0.271, 0.142, 0.001, 0.001, 0.003, 0.003, 0.007, 0.001, 0.001, 0.003, 0.032, 0.034, 0.002, 0.043, 0.709, 0.001, 0.005, 0.004, 0.002, 0.0001, 0.0001, 0.001, 0.001, 0.015, 2.24, 0.001, 0.001, 0.0001, 0.001, 0.04, 0.01, 0.024, 0.01, 0.013, 0.028, 0.003, 0.011, 0.033, 0.006, 0.014, 0.026, 0.687, 0.026, 0.226, 0.009, 0.0001, 0.0001, 0.023, 0.015, 3.578, 2.215, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.0001, 0.003, 0.001, 0.252, 0.098, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.265, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mai": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.888, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.023, 0.001, 0.03, 0.0001, 0.0001, 0.003, 0.001, 0.013, 0.071, 0.074, 0.0001, 0.001, 0.267, 0.061, 0.074, 0.006, 0.01, 0.016, 0.009, 0.005, 0.004, 0.005, 0.004, 0.004, 0.005, 0.012, 0.021, 0.006, 0.004, 0.001, 0.004, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.018, 0.005, 0.005, 0.005, 0.017, 0.003, 0.004, 0.008, 0.015, 0.001, 0.002, 0.009, 0.005, 0.013, 0.013, 0.004, 0.001, 0.014, 0.017, 0.012, 0.006, 0.002, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.792, 0.705, 0.351, 0.05, 0.0001, 0.548, 0.202, 1.331, 0.277, 0.165, 0.004, 0.356, 0.051, 2.185, 0.0001, 0.286, 0.005, 0.001, 0.0001, 0.066, 0.006, 1.874, 0.183, 0.514, 0.043, 0.102, 0.293, 0.463, 0.567, 0.024, 0.087, 0.255, 0.05, 0.178, 0.022, 0.166, 25.43, 6.866, 0.581, 0.373, 1.476, 0.06, 0.857, 0.137, 0.417, 0.41, 1.258, 0.71, 1.883, 0.001, 1.344, 0.001, 0.001, 0.686, 0.286, 0.227, 1.223, 0.469, 0.0001, 0.0001, 0.026, 0.025, 2.747, 1.736, 0.0001, 0.0001, 0.009, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.668, 0.0001, 0.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mdf": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.974, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.901, 0.002, 0.147, 0.0001, 0.0001, 0.003, 0.0001, 0.003, 0.239, 0.241, 0.0001, 0.001, 0.661, 0.233, 0.828, 0.004, 0.16, 0.227, 0.113, 0.065, 0.054, 0.071, 0.072, 0.058, 0.067, 0.13, 0.047, 0.019, 0.002, 0.0001, 0.002, 0.001, 0.0001, 0.006, 0.002, 0.008, 0.002, 0.002, 0.003, 0.002, 0.002, 0.025, 0.001, 0.002, 0.002, 0.005, 0.002, 0.002, 0.006, 0.001, 0.003, 0.005, 0.003, 0.001, 0.008, 0.001, 0.014, 0.0001, 0.0001, 0.004, 0.0001, 0.005, 0.0001, 0.002, 0.0001, 0.07, 0.006, 0.018, 0.016, 0.05, 0.004, 0.011, 0.014, 0.042, 0.003, 0.009, 0.03, 0.013, 0.041, 0.036, 0.013, 0.001, 0.037, 0.035, 0.028, 0.024, 0.005, 0.003, 0.003, 0.006, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.013, 2.98, 2.587, 0.748, 0.583, 0.414, 0.428, 0.203, 0.631, 0.045, 0.095, 0.17, 2.818, 0.257, 0.113, 1.375, 0.157, 0.181, 0.113, 0.066, 0.125, 0.013, 0.006, 0.022, 0.063, 0.005, 0.16, 0.068, 0.186, 0.053, 0.097, 0.114, 0.073, 0.188, 0.099, 0.03, 0.023, 0.016, 0.014, 0.014, 0.049, 0.003, 0.001, 0.054, 0.002, 0.05, 0.007, 0.022, 4.7, 0.292, 1.108, 0.449, 1.264, 2.755, 0.106, 0.711, 2.236, 0.41, 2.142, 1.743, 1.474, 3.418, 3.1, 0.637, 0.0001, 0.0001, 0.118, 0.006, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.003, 0.002, 0.0001, 0.004, 0.002, 28.205, 15.445, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.006, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.0001, 0.122, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.132, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.344, 0.0001, 0.051, 0.0001, 0.0001, 0.003, 0.0001, 1.722, 0.134, 0.134, 0.0001, 0.062, 0.6, 1.054, 1.426, 0.011, 0.88, 0.969, 0.776, 0.547, 0.574, 0.473, 0.464, 0.436, 0.531, 0.535, 0.029, 0.033, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.281, 0.132, 0.16, 0.072, 0.212, 0.148, 0.178, 0.056, 0.346, 0.102, 0.053, 0.101, 0.354, 0.788, 0.05, 0.139, 0.008, 0.098, 0.209, 0.172, 0.049, 0.057, 0.038, 0.005, 0.021, 0.009, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 15.071, 0.568, 0.216, 2.816, 2.902, 0.81, 0.249, 1.395, 7.562, 0.225, 1.469, 1.52, 3.108, 9.36, 4.666, 0.931, 0.023, 4.686, 1.843, 3.288, 0.414, 0.748, 0.044, 0.043, 4.297, 0.559, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.076, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.008, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.001, 0.0001, 0.001, 0.052, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.017, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.15, 0.01, 0.007, 0.008, 0.001, 0.0001, 0.001, 0.006, 0.026, 0.088, 0.003, 0.004, 0.001, 0.005, 0.002, 0.002, 0.137, 0.002, 0.001, 0.004, 0.086, 0.001, 0.002, 0.001, 0.003, 0.001, 0.002, 0.01, 0.003, 0.001, 0.001, 0.008, 0.0001, 0.0001, 0.143, 0.408, 0.006, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.069, 0.004, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.376, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.504, 0.0001, 0.156, 0.0001, 0.0001, 0.0001, 0.039, 0.039, 0.039, 0.039, 0.0001, 0.0001, 1.325, 0.078, 1.247, 0.039, 0.156, 0.039, 0.078, 0.0001, 0.0001, 0.039, 0.0001, 0.0001, 0.039, 0.0001, 0.039, 0.078, 0.078, 0.039, 0.078, 0.0001, 0.0001, 0.701, 0.273, 0.156, 0.078, 0.312, 0.039, 0.156, 0.078, 0.351, 0.779, 0.779, 0.234, 0.779, 0.0001, 0.039, 0.156, 0.0001, 0.312, 0.195, 0.156, 0.195, 0.039, 0.078, 0.0001, 0.195, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.103, 1.558, 0.312, 0.818, 6.584, 0.078, 0.351, 1.013, 7.402, 4.675, 3.584, 3.039, 2.766, 5.804, 6.389, 0.779, 0.078, 4.753, 1.48, 2.337, 1.441, 0.117, 1.597, 0.0001, 1.558, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.351, 0.0001, 0.0001, 0.156, 0.0001, 0.039, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.039, 0.545, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.467, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.078, 0.0001, 0.117, 0.0001, 0.0001, 0.0001, 1.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.078, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.208, 0.429, 0.584, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.662, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mhr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.247, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.433, 0.01, 0.105, 0.0001, 0.0001, 0.003, 0.0001, 0.003, 0.242, 0.243, 0.0001, 0.004, 0.563, 0.341, 0.763, 0.006, 0.23, 0.307, 0.193, 0.103, 0.088, 0.092, 0.076, 0.077, 0.081, 0.164, 0.099, 0.012, 0.003, 0.005, 0.003, 0.006, 0.0001, 0.002, 0.002, 0.003, 0.001, 0.001, 0.002, 0.001, 0.001, 0.045, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.016, 0.001, 0.019, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.02, 0.004, 0.007, 0.008, 0.02, 0.002, 0.003, 0.004, 0.014, 0.0001, 0.002, 0.01, 0.005, 0.01, 0.012, 0.004, 0.0001, 0.013, 0.009, 0.01, 0.005, 0.002, 0.002, 0.0001, 0.002, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.161, 0.998, 2.463, 1.262, 0.079, 0.06, 0.073, 0.732, 2.145, 0.012, 0.024, 3.429, 0.167, 0.157, 0.039, 0.3, 0.114, 0.051, 0.084, 0.076, 0.173, 0.021, 0.005, 0.012, 0.07, 0.035, 0.245, 0.039, 0.204, 0.055, 0.073, 0.108, 0.142, 0.124, 0.167, 0.046, 0.023, 0.257, 0.01, 0.146, 0.069, 0.001, 0.001, 0.099, 0.002, 0.093, 0.02, 0.031, 3.766, 0.43, 0.916, 0.689, 1.067, 3.621, 0.573, 0.276, 1.798, 1.177, 2.133, 2.766, 1.884, 2.711, 2.445, 0.765, 0.0001, 0.0001, 0.222, 0.109, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.008, 0.004, 28.363, 13.911, 0.249, 0.424, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.203, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.242, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 18.048, 0.002, 0.114, 0.0001, 0.0001, 0.007, 0.0001, 0.316, 0.24, 0.24, 0.0001, 0.0001, 0.815, 0.729, 1.027, 0.003, 0.15, 0.245, 0.11, 0.069, 0.067, 0.071, 0.069, 0.066, 0.083, 0.097, 0.029, 0.194, 0.002, 0.0001, 0.002, 0.002, 0.0001, 0.243, 0.042, 0.09, 0.013, 0.207, 0.019, 0.023, 0.227, 0.154, 0.011, 0.858, 0.022, 0.414, 0.264, 0.035, 0.344, 0.001, 0.143, 0.039, 1.088, 0.016, 0.015, 0.518, 0.001, 0.002, 0.003, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 10.57, 0.047, 0.232, 0.102, 7.727, 0.029, 1.763, 3.618, 6.701, 0.008, 3.514, 0.582, 0.854, 4.652, 6.133, 0.788, 0.003, 3.052, 0.255, 6.464, 3.231, 0.037, 1.326, 0.008, 0.217, 0.009, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.025, 2.749, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.072, 0.357, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.284, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.004, 0.003, 0.001, 0.001, 0.004, 0.001, 0.003, 0.004, 0.003, 0.003, 0.013, 0.525, 0.001, 0.002, 0.001, 0.002, 0.003, 0.004, 0.018, 0.005, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.019, 0.015, 3.257, 0.759, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.006, 0.008, 0.006, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.002, 0.004, 0.001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "min": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.172, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.612, 0.0001, 0.04, 0.005, 0.0001, 0.002, 0.004, 0.018, 0.155, 0.155, 0.0001, 0.0001, 1.063, 0.022, 1.041, 0.001, 0.404, 0.298, 0.265, 0.112, 0.103, 0.128, 0.132, 0.113, 0.114, 0.233, 0.009, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.635, 0.069, 0.223, 0.216, 0.107, 0.023, 0.035, 0.059, 0.25, 0.026, 0.062, 0.356, 0.142, 0.089, 0.046, 0.143, 0.014, 0.06, 0.402, 0.123, 0.018, 0.017, 0.016, 0.015, 0.037, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.754, 1.953, 0.961, 4.093, 4.246, 0.532, 1.865, 1.575, 6.705, 0.46, 3.68, 3.421, 3.054, 5.905, 5.613, 2.448, 0.009, 4.152, 3.536, 3.358, 3.758, 0.175, 0.156, 0.045, 0.909, 0.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.018, 0.016, 0.004, 0.004, 0.011, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.017, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.005, 0.0001, 0.0001, 0.014, 0.007, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.016, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.029, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.442, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.507, 0.001, 0.094, 0.0001, 0.0001, 0.006, 0.001, 0.012, 0.086, 0.086, 0.001, 0.004, 0.588, 0.074, 0.535, 0.01, 0.197, 0.23, 0.143, 0.089, 0.082, 0.088, 0.076, 0.074, 0.08, 0.116, 0.032, 0.012, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.015, 0.008, 0.047, 0.006, 0.006, 0.005, 0.034, 0.005, 0.026, 0.002, 0.003, 0.006, 0.012, 0.023, 0.006, 0.014, 0.001, 0.007, 0.019, 0.01, 0.006, 0.006, 0.004, 0.004, 0.001, 0.001, 0.008, 0.0001, 0.008, 0.0001, 0.002, 0.0001, 0.08, 0.013, 0.03, 0.022, 0.08, 0.011, 0.022, 0.023, 0.061, 0.003, 0.011, 0.035, 0.039, 0.054, 0.06, 0.012, 0.001, 0.056, 0.049, 0.047, 0.027, 0.008, 0.006, 0.003, 0.012, 0.004, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.279, 1.922, 3.072, 0.896, 0.157, 0.085, 0.296, 0.344, 0.32, 0.001, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.012, 0.067, 0.066, 0.1, 0.11, 0.062, 0.046, 0.008, 0.029, 0.825, 0.009, 0.229, 0.032, 0.208, 0.077, 0.103, 0.118, 0.054, 0.125, 0.063, 0.016, 0.028, 0.03, 0.013, 0.01, 0.018, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 5.692, 0.585, 1.752, 0.746, 1.619, 3.647, 0.195, 0.665, 3.964, 0.001, 1.64, 1.494, 0.888, 3.068, 4.767, 1.117, 0.0001, 0.0001, 0.015, 0.006, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.003, 33.101, 10.345, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.096, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ml": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.283, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.554, 0.001, 0.034, 0.0001, 0.0001, 0.002, 0.0001, 0.013, 0.046, 0.046, 0.0001, 0.001, 0.155, 0.051, 0.434, 0.004, 0.069, 0.096, 0.051, 0.026, 0.025, 0.029, 0.025, 0.024, 0.03, 0.054, 0.011, 0.004, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.005, 0.003, 0.005, 0.002, 0.002, 0.002, 0.002, 0.002, 0.004, 0.001, 0.001, 0.002, 0.003, 0.002, 0.002, 0.004, 0.0001, 0.002, 0.005, 0.004, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 0.044, 0.007, 0.016, 0.014, 0.045, 0.007, 0.009, 0.015, 0.036, 0.001, 0.004, 0.022, 0.013, 0.031, 0.031, 0.01, 0.001, 0.031, 0.025, 0.029, 0.015, 0.004, 0.005, 0.002, 0.008, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.284, 1.637, 0.889, 0.045, 0.0001, 0.237, 0.843, 0.478, 0.108, 0.077, 0.086, 0.336, 0.062, 4.599, 0.152, 0.029, 0.008, 0.0001, 0.075, 0.022, 0.003, 1.759, 0.042, 0.219, 0.023, 0.382, 0.512, 0.004, 0.161, 0.001, 0.086, 0.887, 0.025, 0.094, 0.002, 0.484, 1.618, 0.083, 0.303, 0.146, 1.873, 0.0001, 0.931, 0.058, 0.143, 0.126, 0.78, 1.209, 1.122, 0.589, 0.667, 0.458, 22.229, 10.029, 0.199, 0.193, 0.652, 0.135, 0.025, 0.171, 0.328, 0.323, 1.631, 2.28, 0.0001, 0.0001, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.391, 0.001, 0.071, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.502, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.684, 0.002, 0.094, 0.001, 0.001, 0.006, 0.001, 0.003, 0.078, 0.078, 0.001, 0.002, 0.423, 0.192, 0.522, 0.019, 0.207, 0.249, 0.16, 0.075, 0.065, 0.07, 0.06, 0.055, 0.066, 0.128, 0.025, 0.008, 0.003, 0.005, 0.004, 0.002, 0.0001, 0.018, 0.012, 0.019, 0.013, 0.012, 0.008, 0.007, 0.009, 0.026, 0.003, 0.004, 0.011, 0.017, 0.01, 0.009, 0.02, 0.002, 0.012, 0.024, 0.016, 0.006, 0.007, 0.006, 0.007, 0.003, 0.001, 0.006, 0.001, 0.006, 0.0001, 0.005, 0.0001, 0.097, 0.016, 0.039, 0.037, 0.119, 0.017, 0.023, 0.03, 0.088, 0.002, 0.012, 0.052, 0.031, 0.08, 0.086, 0.026, 0.002, 0.079, 0.064, 0.078, 0.038, 0.025, 0.012, 0.008, 0.018, 0.003, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 2.438, 1.425, 1.576, 1.589, 0.047, 1.639, 0.295, 0.416, 0.311, 0.001, 0.008, 0.672, 0.369, 2.886, 0.106, 0.163, 0.114, 0.151, 0.023, 0.067, 0.081, 0.017, 0.027, 0.033, 0.044, 0.004, 0.046, 0.028, 0.128, 0.083, 0.044, 0.031, 0.048, 0.074, 0.102, 0.063, 0.021, 0.125, 0.02, 0.022, 0.053, 1.026, 0.001, 0.019, 0.001, 0.067, 0.028, 1.192, 4.733, 1.04, 0.537, 2.615, 2.04, 0.399, 0.621, 0.396, 2.01, 1.723, 0.207, 2.589, 0.943, 3.889, 2.383, 0.107, 0.0001, 0.0001, 0.065, 0.012, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.001, 27.532, 13.908, 1.199, 1.049, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.072, 0.002, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.77, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.47, 0.002, 0.214, 0.0001, 0.0001, 0.017, 0.001, 0.035, 0.128, 0.128, 0.002, 0.001, 0.656, 0.155, 0.49, 0.006, 0.172, 0.19, 0.096, 0.052, 0.062, 0.054, 0.034, 0.043, 0.06, 0.129, 0.06, 0.015, 0.017, 0.012, 0.017, 0.0001, 0.0001, 0.018, 0.009, 0.023, 0.009, 0.011, 0.002, 0.006, 0.004, 0.035, 0.002, 0.005, 0.007, 0.014, 0.008, 0.008, 0.009, 0.001, 0.009, 0.019, 0.008, 0.005, 0.004, 0.007, 0.007, 0.001, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.381, 0.035, 0.167, 0.122, 0.44, 0.045, 0.036, 0.034, 0.432, 0.005, 0.016, 0.206, 0.12, 0.248, 0.177, 0.096, 0.003, 0.253, 0.183, 0.236, 0.214, 0.038, 0.01, 0.011, 0.011, 0.03, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.01, 1.642, 2.712, 2.46, 0.4, 0.066, 0.487, 0.515, 0.507, 0.001, 0.001, 0.622, 0.372, 0.933, 0.029, 0.581, 0.134, 0.087, 0.042, 0.032, 0.081, 0.073, 0.022, 0.008, 0.061, 0.004, 0.139, 0.063, 0.145, 0.05, 0.043, 0.149, 0.144, 0.143, 0.069, 0.113, 0.038, 0.031, 0.007, 0.03, 0.013, 0.002, 0.001, 0.064, 0.002, 0.001, 0.029, 0.007, 3.78, 0.37, 0.558, 0.274, 1.316, 4.346, 0.072, 0.319, 3.558, 0.657, 1.356, 2.204, 1.073, 2.802, 2.13, 1.099, 0.0001, 0.0001, 0.025, 0.051, 0.091, 0.068, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.005, 0.0001, 0.008, 0.004, 27.537, 14.047, 0.001, 0.161, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.005, 0.022, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mr": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.525, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.348, 0.002, 0.043, 0.0001, 0.0001, 0.004, 0.0001, 0.024, 0.061, 0.064, 0.0001, 0.001, 0.221, 0.063, 0.539, 0.009, 0.009, 0.009, 0.006, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.005, 0.03, 0.01, 0.003, 0.004, 0.003, 0.003, 0.0001, 0.008, 0.004, 0.006, 0.004, 0.003, 0.003, 0.003, 0.003, 0.007, 0.002, 0.002, 0.003, 0.006, 0.003, 0.002, 0.005, 0.0001, 0.004, 0.008, 0.009, 0.001, 0.002, 0.002, 0.0001, 0.001, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 0.001, 0.0001, 0.138, 0.021, 0.046, 0.053, 0.162, 0.029, 0.028, 0.063, 0.114, 0.003, 0.011, 0.062, 0.038, 0.106, 0.103, 0.03, 0.002, 0.096, 0.09, 0.116, 0.04, 0.015, 0.019, 0.003, 0.023, 0.002, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 1.224, 0.397, 1.061, 0.056, 0.001, 0.297, 0.351, 1.664, 0.084, 0.127, 0.02, 0.461, 0.026, 2.286, 0.0001, 0.096, 0.005, 0.018, 0.001, 0.019, 0.005, 1.098, 0.145, 0.403, 0.083, 0.015, 0.659, 0.012, 0.404, 0.067, 0.014, 0.287, 0.125, 0.236, 0.039, 0.415, 24.995, 7.065, 0.585, 0.404, 1.081, 0.036, 0.727, 0.118, 0.317, 0.211, 0.844, 1.342, 1.809, 0.018, 1.056, 0.198, 0.001, 0.975, 0.327, 0.194, 1.035, 0.79, 0.001, 0.001, 0.003, 0.001, 3.71, 0.926, 0.0001, 0.0001, 0.015, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.418, 0.001, 0.048, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mrj": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.556, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.792, 0.004, 0.111, 0.0001, 0.0001, 0.008, 0.001, 0.036, 0.371, 0.372, 0.0001, 0.001, 0.508, 0.256, 0.9, 0.015, 0.334, 0.401, 0.27, 0.169, 0.152, 0.17, 0.137, 0.141, 0.168, 0.185, 0.1, 0.046, 0.009, 0.005, 0.008, 0.012, 0.0001, 0.017, 0.012, 0.012, 0.011, 0.006, 0.006, 0.008, 0.006, 0.083, 0.004, 0.011, 0.006, 0.014, 0.007, 0.024, 0.016, 0.001, 0.008, 0.014, 0.009, 0.003, 0.03, 0.002, 0.042, 0.002, 0.001, 0.008, 0.0001, 0.009, 0.0001, 0.003, 0.0001, 0.281, 0.025, 0.082, 0.065, 0.202, 0.013, 0.027, 0.052, 0.157, 0.003, 0.032, 0.08, 0.041, 0.09, 0.092, 0.03, 0.005, 0.117, 0.072, 0.076, 0.073, 0.015, 0.012, 0.004, 0.024, 0.01, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.356, 0.846, 2.179, 0.887, 0.116, 0.285, 0.312, 0.236, 2.316, 0.007, 0.004, 2.565, 0.266, 0.252, 0.05, 0.215, 0.187, 0.062, 0.078, 1.679, 0.285, 0.024, 0.005, 0.016, 0.067, 0.046, 0.237, 0.053, 0.116, 0.054, 0.059, 0.117, 0.058, 0.115, 0.145, 0.033, 0.102, 0.049, 0.064, 0.062, 0.066, 0.006, 0.001, 0.056, 0.003, 0.041, 0.007, 0.023, 2.651, 0.259, 1.194, 0.797, 1.113, 1.956, 0.572, 0.253, 2.277, 2.969, 1.78, 2.755, 1.532, 2.591, 1.704, 0.818, 0.0001, 0.0001, 0.138, 0.095, 0.012, 0.006, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.011, 0.0001, 0.008, 0.006, 24.363, 12.5, 0.002, 4.142, 0.0001, 0.0001, 0.0001, 0.001, 0.015, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.004, 0.341, 0.005, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ms": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.423, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.116, 0.004, 0.276, 0.001, 0.003, 0.028, 0.005, 0.04, 0.153, 0.154, 0.011, 0.002, 0.825, 0.313, 0.841, 0.02, 0.335, 0.324, 0.225, 0.11, 0.099, 0.112, 0.094, 0.087, 0.096, 0.171, 0.041, 0.019, 0.01, 0.005, 0.01, 0.002, 0.001, 0.327, 0.313, 0.169, 0.197, 0.08, 0.09, 0.097, 0.122, 0.22, 0.145, 0.326, 0.158, 0.369, 0.143, 0.065, 0.427, 0.013, 0.147, 0.487, 0.268, 0.071, 0.05, 0.063, 0.007, 0.038, 0.022, 0.015, 0.0001, 0.015, 0.0001, 0.002, 0.0001, 15.253, 2.008, 0.502, 3.234, 6.807, 0.209, 2.704, 2.141, 5.701, 0.605, 3.195, 3.049, 3.025, 7.562, 1.688, 2.054, 0.019, 4.172, 2.861, 3.513, 3.855, 0.159, 0.407, 0.024, 1.19, 0.123, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.025, 0.005, 0.003, 0.004, 0.003, 0.002, 0.002, 0.004, 0.003, 0.002, 0.002, 0.001, 0.002, 0.007, 0.004, 0.002, 0.001, 0.002, 0.001, 0.009, 0.003, 0.001, 0.001, 0.001, 0.002, 0.01, 0.001, 0.003, 0.004, 0.004, 0.001, 0.007, 0.031, 0.013, 0.003, 0.003, 0.003, 0.002, 0.001, 0.006, 0.007, 0.017, 0.002, 0.003, 0.001, 0.007, 0.002, 0.002, 0.004, 0.011, 0.003, 0.006, 0.005, 0.001, 0.006, 0.001, 0.004, 0.002, 0.003, 0.002, 0.008, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.034, 0.074, 0.022, 0.02, 0.0001, 0.0001, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.012, 0.015, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.024, 0.004, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mt": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.717, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.569, 0.003, 0.319, 0.001, 0.001, 0.009, 0.001, 0.699, 0.116, 0.117, 0.001, 0.002, 0.868, 2.789, 0.736, 0.014, 0.299, 0.341, 0.218, 0.093, 0.081, 0.087, 0.085, 0.082, 0.1, 0.201, 0.053, 0.022, 0.013, 0.012, 0.013, 0.002, 0.0001, 0.223, 0.171, 0.118, 0.162, 0.107, 0.236, 0.127, 0.076, 0.3, 0.048, 0.158, 0.199, 0.315, 0.08, 0.056, 0.187, 0.018, 0.103, 0.221, 0.127, 0.065, 0.054, 0.053, 0.02, 0.007, 0.009, 0.022, 0.0001, 0.023, 0.0001, 0.008, 0.002, 9.087, 1.533, 0.244, 1.812, 5.201, 1.498, 1.212, 0.809, 8.439, 2.13, 1.92, 5.784, 2.557, 4.221, 2.69, 1.16, 0.488, 3.837, 2.631, 5.521, 3.106, 0.451, 1.062, 0.484, 0.085, 0.753, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.211, 0.004, 0.004, 0.002, 0.003, 0.001, 0.001, 0.004, 0.002, 0.001, 0.016, 0.407, 0.001, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.042, 0.003, 0.001, 0.001, 0.001, 0.005, 0.141, 0.001, 0.001, 0.01, 0.01, 0.001, 0.002, 0.13, 0.527, 0.002, 0.004, 0.002, 0.001, 0.025, 1.521, 0.007, 0.014, 0.001, 0.004, 0.005, 0.008, 0.001, 0.001, 0.004, 0.005, 0.009, 0.004, 0.002, 0.002, 0.003, 0.001, 0.003, 0.01, 0.003, 0.015, 0.566, 0.003, 0.002, 0.002, 0.0001, 0.0001, 0.015, 0.129, 2.554, 0.578, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.011, 0.005, 0.011, 0.004, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.004, 0.006, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.004, 0.212, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mus": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.612, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 19.388, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.02, 0.0001, 1.02, 0.0001, 1.02, 1.02, 0.0001, 2.041, 1.02, 0.0001, 1.02, 1.02, 4.082, 1.02, 1.02, 2.041, 0.0001, 1.02, 1.02, 1.02, 1.02, 1.02, 1.02, 0.0001, 1.02, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.061, 0.0001, 0.0001, 0.0001, 5.102, 0.0001, 1.02, 0.0001, 1.02, 0.0001, 5.102, 0.0001, 1.02, 1.02, 2.041, 0.0001, 0.0001, 0.0001, 2.041, 0.0001, 0.0001, 2.041, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.02, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.02, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "my": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.476, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.676, 0.0001, 0.018, 0.0001, 0.0001, 0.001, 0.0001, 0.009, 0.072, 0.072, 0.0001, 0.001, 0.013, 0.027, 0.014, 0.004, 0.007, 0.006, 0.005, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.001, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.009, 0.007, 0.011, 0.006, 0.004, 0.004, 0.005, 0.004, 0.006, 0.002, 0.003, 0.004, 0.008, 0.005, 0.004, 0.007, 0.0001, 0.005, 0.011, 0.008, 0.003, 0.002, 0.003, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.087, 0.015, 0.033, 0.032, 0.11, 0.015, 0.02, 0.035, 0.072, 0.001, 0.01, 0.046, 0.027, 0.071, 0.073, 0.021, 0.001, 0.069, 0.054, 0.072, 0.03, 0.01, 0.011, 0.003, 0.016, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 32.171, 1.737, 0.141, 0.03, 1.382, 0.783, 0.273, 0.069, 0.03, 0.083, 0.874, 0.307, 0.061, 0.061, 0.009, 0.119, 1.037, 0.261, 0.115, 0.031, 0.966, 0.888, 0.304, 0.058, 0.131, 1.12, 0.266, 0.843, 0.619, 0.172, 1.057, 0.095, 0.006, 0.703, 0.001, 0.001, 0.009, 0.019, 0.041, 0.006, 0.0001, 0.005, 0.0001, 0.239, 1.811, 1.255, 0.357, 1.497, 0.246, 1.317, 0.249, 0.0001, 0.0001, 0.0001, 0.294, 0.751, 1.889, 0.152, 3.975, 0.6, 0.881, 0.616, 0.651, 0.004, 0.0001, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.801, 0.03, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "myv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.363, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.917, 0.015, 0.248, 0.0001, 0.0001, 0.022, 0.0001, 0.001, 0.283, 0.286, 0.002, 0.004, 0.691, 0.215, 0.812, 0.009, 0.174, 0.262, 0.16, 0.093, 0.073, 0.077, 0.073, 0.069, 0.078, 0.133, 0.142, 0.014, 0.011, 0.005, 0.01, 0.008, 0.0001, 0.003, 0.002, 0.005, 0.001, 0.001, 0.002, 0.001, 0.001, 0.012, 0.001, 0.001, 0.002, 0.003, 0.001, 0.001, 0.004, 0.0001, 0.002, 0.003, 0.002, 0.001, 0.004, 0.001, 0.007, 0.0001, 0.001, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.003, 0.048, 0.012, 0.02, 0.007, 0.038, 0.002, 0.005, 0.006, 0.024, 0.002, 0.008, 0.023, 0.008, 0.017, 0.019, 0.008, 0.0001, 0.032, 0.018, 0.013, 0.014, 0.004, 0.001, 0.001, 0.004, 0.002, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 2.092, 2.863, 2.802, 0.895, 0.06, 0.084, 0.303, 0.361, 0.574, 0.012, 0.006, 0.456, 2.653, 0.734, 0.106, 1.014, 0.129, 0.284, 0.186, 0.058, 0.27, 0.019, 0.007, 0.024, 0.083, 0.006, 0.182, 0.079, 0.175, 0.059, 0.072, 0.148, 0.231, 0.176, 0.101, 0.047, 0.012, 0.013, 0.018, 0.046, 0.024, 0.001, 0.0001, 0.091, 0.002, 0.065, 0.014, 0.024, 3.393, 0.354, 1.588, 0.391, 1.0, 3.63, 0.2, 0.667, 2.033, 0.447, 2.062, 1.616, 1.324, 3.27, 3.572, 0.635, 0.0001, 0.0001, 0.332, 0.006, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.017, 0.0001, 0.001, 0.001, 27.959, 14.855, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.281, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.032, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "mzn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.201, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.629, 0.002, 0.049, 0.0001, 0.0001, 0.001, 0.004, 0.002, 0.134, 0.134, 0.0001, 0.0001, 0.026, 0.054, 0.593, 0.02, 0.019, 0.017, 0.017, 0.008, 0.004, 0.006, 0.012, 0.005, 0.01, 0.015, 0.042, 0.0001, 0.001, 0.014, 0.001, 0.004, 0.0001, 0.004, 0.003, 0.005, 0.003, 0.006, 0.016, 0.002, 0.002, 0.003, 0.001, 0.001, 0.009, 0.006, 0.002, 0.001, 0.004, 0.0001, 0.003, 0.005, 0.007, 0.001, 0.001, 0.01, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.009, 0.0001, 0.072, 0.016, 0.031, 0.045, 0.106, 0.011, 0.011, 0.023, 0.094, 0.004, 0.019, 0.044, 0.012, 0.044, 0.054, 0.042, 0.001, 0.056, 0.056, 0.055, 0.021, 0.007, 0.011, 0.005, 0.015, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.44, 0.427, 0.449, 0.013, 1.516, 2.042, 3.291, 3.912, 3.162, 0.001, 0.032, 0.014, 4.412, 0.002, 0.195, 0.007, 0.446, 0.17, 0.001, 0.002, 0.012, 0.004, 0.0001, 0.001, 0.045, 0.005, 0.0001, 0.006, 0.001, 0.0001, 0.0001, 0.003, 0.003, 0.013, 0.18, 0.011, 0.008, 0.001, 0.211, 5.124, 1.425, 1.013, 2.263, 0.078, 0.559, 0.214, 0.344, 2.205, 0.318, 3.605, 0.725, 1.866, 1.033, 0.295, 0.164, 0.271, 0.156, 0.676, 0.058, 0.031, 0.001, 0.001, 0.258, 0.0001, 0.0001, 0.0001, 0.056, 0.008, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.009, 0.003, 0.0001, 0.003, 0.0001, 0.001, 0.001, 0.002, 19.953, 15.923, 1.548, 5.327, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.427, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "na": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.998, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.709, 0.015, 0.646, 0.0001, 0.002, 0.0001, 0.004, 0.021, 0.659, 0.659, 0.017, 0.002, 0.883, 0.333, 1.719, 0.03, 1.451, 2.231, 1.063, 0.565, 0.61, 0.611, 0.586, 0.586, 0.597, 1.829, 0.199, 0.094, 0.009, 0.006, 0.009, 0.002, 0.0001, 0.49, 0.423, 0.263, 0.348, 0.486, 0.143, 0.225, 0.131, 0.617, 0.095, 0.263, 0.178, 0.552, 0.272, 0.136, 0.483, 0.013, 0.313, 0.36, 0.336, 0.074, 0.114, 0.249, 0.018, 0.046, 0.052, 0.006, 0.0001, 0.007, 0.0001, 0.006, 0.0001, 7.914, 1.267, 0.542, 1.393, 6.136, 0.161, 1.565, 0.525, 5.317, 0.298, 1.632, 1.173, 1.479, 6.133, 5.204, 0.602, 0.04, 3.812, 1.491, 2.75, 1.848, 0.267, 2.105, 0.037, 0.79, 0.308, 0.0001, 0.0001, 0.0001, 0.013, 0.0001, 0.299, 0.053, 0.064, 0.017, 0.038, 0.029, 0.014, 0.008, 0.026, 0.003, 0.007, 0.007, 0.016, 0.016, 0.006, 0.008, 0.013, 0.032, 0.004, 0.043, 0.108, 0.002, 0.004, 0.01, 0.017, 0.017, 0.017, 0.015, 0.011, 0.008, 0.009, 0.017, 0.085, 0.124, 0.117, 0.04, 0.025, 0.023, 0.025, 0.032, 0.017, 0.097, 0.007, 0.031, 0.013, 0.031, 0.009, 0.016, 0.079, 0.095, 0.056, 0.083, 0.021, 0.063, 0.052, 0.013, 0.046, 0.015, 0.047, 0.045, 0.034, 0.035, 0.045, 0.013, 0.0001, 0.0001, 0.04, 0.466, 0.079, 0.167, 0.001, 0.002, 0.0001, 0.023, 0.01, 0.013, 0.002, 0.001, 0.027, 0.006, 0.292, 0.12, 0.0001, 0.0001, 0.009, 0.199, 0.04, 0.007, 0.055, 0.037, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.021, 0.074, 0.244, 0.0001, 0.005, 0.01, 0.006, 0.001, 0.002, 0.006, 0.003, 0.003, 0.009, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nah": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.08, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.795, 0.004, 0.316, 0.0001, 0.0001, 0.001, 0.0001, 0.011, 0.502, 0.505, 0.006, 0.329, 1.148, 0.317, 0.599, 1.663, 0.178, 0.339, 0.18, 0.099, 0.094, 0.088, 0.135, 0.085, 0.092, 0.204, 0.686, 0.012, 0.001, 0.002, 0.002, 0.012, 0.0001, 0.583, 0.136, 0.486, 0.282, 0.369, 0.108, 0.135, 0.149, 0.382, 0.043, 0.01, 0.153, 0.41, 0.267, 0.154, 0.356, 0.041, 0.209, 0.348, 0.531, 0.077, 0.099, 0.006, 0.046, 0.078, 0.021, 0.306, 0.0001, 0.304, 0.0001, 0.018, 0.0001, 8.12, 0.52, 3.826, 1.716, 6.024, 0.239, 0.598, 2.703, 7.016, 0.169, 0.062, 5.071, 1.759, 4.856, 5.013, 1.61, 0.66, 3.183, 2.38, 4.798, 3.279, 0.368, 0.013, 0.578, 0.571, 0.892, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.023, 0.52, 0.003, 0.003, 0.002, 0.001, 0.001, 0.002, 0.002, 0.007, 0.001, 0.001, 0.005, 0.446, 0.001, 0.001, 0.001, 0.002, 0.001, 0.26, 0.002, 0.003, 0.001, 0.001, 0.001, 0.002, 0.003, 0.001, 0.002, 0.001, 0.001, 0.001, 0.003, 0.117, 0.005, 0.001, 0.004, 0.001, 0.001, 0.002, 0.003, 0.168, 0.013, 0.475, 0.001, 0.136, 0.018, 0.008, 0.004, 0.071, 0.003, 0.269, 0.002, 0.003, 0.001, 0.001, 0.003, 0.002, 0.068, 0.005, 0.005, 0.002, 0.003, 0.016, 0.0001, 0.0001, 0.033, 0.838, 1.259, 0.446, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.009, 0.004, 0.012, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.005, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.027, 0.002, 0.008, 0.004, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nap": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.664, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.609, 0.012, 0.443, 0.0001, 0.0001, 0.005, 0.002, 3.603, 0.188, 0.187, 0.001, 0.001, 0.851, 0.111, 0.916, 0.025, 0.289, 0.464, 0.288, 0.212, 0.187, 0.195, 0.184, 0.177, 0.191, 0.229, 0.063, 0.027, 0.064, 0.004, 0.064, 0.004, 0.0001, 0.359, 0.17, 0.431, 0.088, 0.101, 0.128, 0.139, 0.019, 0.153, 0.024, 0.014, 0.18, 0.269, 0.172, 0.129, 0.252, 0.015, 0.136, 0.331, 0.141, 0.042, 0.154, 0.012, 0.021, 0.004, 0.014, 0.007, 0.0001, 0.007, 0.0001, 0.001, 0.0001, 8.472, 0.677, 3.575, 1.818, 8.836, 0.628, 1.161, 0.605, 5.326, 0.294, 0.072, 2.854, 1.959, 5.855, 5.118, 1.978, 0.107, 4.154, 2.774, 4.302, 3.256, 1.068, 0.047, 0.011, 0.049, 0.778, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.167, 0.005, 0.004, 0.005, 0.003, 0.002, 0.001, 0.001, 0.017, 0.002, 0.001, 0.001, 0.001, 0.003, 0.001, 0.001, 0.003, 0.001, 0.001, 0.008, 0.005, 0.001, 0.001, 0.001, 0.033, 0.118, 0.001, 0.001, 0.005, 0.005, 0.001, 0.002, 0.266, 0.085, 0.051, 0.002, 0.003, 0.001, 0.003, 0.003, 0.62, 0.161, 0.023, 0.139, 0.069, 0.03, 0.001, 0.002, 0.025, 0.004, 0.164, 0.026, 0.08, 0.002, 0.003, 0.002, 0.002, 0.107, 0.016, 0.007, 0.005, 0.003, 0.002, 0.002, 0.0001, 0.0001, 0.057, 1.779, 0.007, 0.055, 0.0001, 0.001, 0.0001, 0.003, 0.002, 0.003, 0.0001, 0.0001, 0.013, 0.006, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.002, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.165, 0.003, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nds": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.919, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.282, 0.001, 0.235, 0.0001, 0.0001, 0.09, 0.002, 0.046, 0.155, 0.155, 0.017, 0.001, 0.777, 0.214, 1.137, 0.014, 0.414, 0.571, 0.279, 0.157, 0.152, 0.165, 0.151, 0.162, 0.212, 0.299, 0.042, 0.019, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.383, 0.397, 0.141, 0.527, 0.184, 0.228, 0.238, 0.278, 0.228, 0.153, 0.317, 0.238, 0.331, 0.224, 0.164, 0.212, 0.007, 0.201, 0.654, 0.206, 0.119, 0.194, 0.231, 0.003, 0.008, 0.039, 0.011, 0.0001, 0.011, 0.0001, 0.001, 0.0001, 4.393, 1.051, 1.267, 3.394, 10.917, 0.767, 1.396, 2.581, 3.914, 0.085, 1.325, 2.618, 1.593, 8.321, 3.314, 0.889, 0.009, 5.125, 3.768, 5.421, 2.363, 1.177, 0.929, 0.056, 0.171, 0.239, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.454, 0.002, 0.002, 0.001, 0.006, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.023, 0.001, 0.0001, 0.022, 0.001, 0.009, 0.334, 0.001, 0.001, 0.057, 0.001, 0.038, 0.018, 0.048, 0.004, 0.001, 0.001, 0.208, 0.002, 0.001, 0.001, 0.002, 0.009, 0.001, 0.001, 0.0001, 0.002, 0.0001, 0.001, 0.005, 0.002, 0.014, 0.003, 0.002, 0.002, 0.82, 0.001, 0.004, 0.001, 0.001, 0.001, 0.763, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.055, 1.884, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.007, 0.003, 0.008, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.454, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ne": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.49, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.629, 0.002, 0.033, 0.0001, 0.0001, 0.006, 0.0001, 0.018, 0.053, 0.057, 0.0001, 0.001, 0.2, 0.042, 0.073, 0.008, 0.003, 0.003, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.015, 0.002, 0.005, 0.002, 0.006, 0.002, 0.0001, 0.004, 0.003, 0.004, 0.002, 0.002, 0.002, 0.002, 0.002, 0.003, 0.001, 0.001, 0.002, 0.002, 0.002, 0.002, 0.003, 0.0001, 0.002, 0.004, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.056, 0.012, 0.021, 0.02, 0.066, 0.011, 0.012, 0.023, 0.048, 0.001, 0.005, 0.027, 0.017, 0.042, 0.043, 0.015, 0.001, 0.044, 0.036, 0.045, 0.017, 0.005, 0.008, 0.001, 0.01, 0.001, 0.0001, 0.009, 0.0001, 0.0001, 0.0001, 0.608, 0.76, 0.405, 0.065, 0.0001, 0.231, 0.124, 1.05, 0.333, 0.225, 0.003, 1.089, 0.054, 2.553, 0.0001, 0.268, 0.005, 0.0001, 0.0001, 0.016, 0.009, 1.681, 0.188, 0.574, 0.05, 0.059, 0.235, 0.302, 0.411, 0.024, 0.038, 0.296, 0.063, 0.16, 0.029, 0.16, 24.986, 7.481, 0.637, 0.298, 1.766, 0.034, 0.895, 0.142, 0.406, 0.37, 1.169, 0.857, 2.172, 0.0001, 1.023, 0.0001, 0.0001, 0.652, 0.263, 0.209, 1.099, 0.646, 0.0001, 0.0001, 0.001, 0.001, 3.096, 1.51, 0.0001, 0.0001, 0.006, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.857, 0.0001, 0.028, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "new": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.658, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.736, 0.0001, 0.005, 0.0001, 0.0001, 0.016, 0.0001, 0.016, 0.053, 0.053, 0.0001, 0.0001, 0.168, 0.064, 0.05, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.014, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.003, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.002, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.045, 0.006, 0.015, 0.015, 0.048, 0.008, 0.009, 0.021, 0.034, 0.001, 0.003, 0.019, 0.011, 0.032, 0.03, 0.01, 0.0001, 0.03, 0.026, 0.034, 0.014, 0.004, 0.005, 0.001, 0.007, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.748, 1.473, 1.078, 0.313, 0.0001, 0.165, 0.087, 0.934, 0.049, 0.145, 0.004, 0.213, 0.295, 3.035, 0.001, 0.021, 0.01, 0.0001, 0.001, 0.003, 0.002, 0.891, 0.378, 1.026, 0.007, 0.007, 0.145, 0.227, 0.557, 0.002, 0.008, 0.138, 0.03, 0.275, 0.076, 0.203, 24.519, 8.651, 0.655, 0.317, 1.238, 0.066, 0.765, 0.114, 0.288, 0.474, 0.695, 2.038, 1.25, 0.006, 0.967, 0.005, 0.016, 1.209, 0.15, 0.223, 0.893, 0.295, 0.0001, 0.001, 0.016, 0.0001, 3.268, 1.125, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.648, 0.0001, 0.246, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ng": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.332, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.852, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.028, 0.028, 0.0001, 0.0001, 0.569, 0.014, 0.833, 0.0001, 0.0001, 0.028, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.042, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.291, 0.028, 0.014, 0.069, 0.125, 0.0001, 0.194, 0.153, 0.5, 0.042, 0.069, 0.0001, 0.056, 0.153, 0.402, 0.083, 0.0001, 0.0001, 0.014, 0.18, 0.222, 0.0001, 0.222, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.728, 1.221, 0.236, 1.443, 7.106, 0.347, 2.859, 3.65, 4.136, 0.125, 4.316, 3.539, 3.983, 7.412, 7.883, 1.596, 0.0001, 1.138, 1.901, 3.511, 6.62, 0.402, 2.776, 0.0001, 2.11, 0.194, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.028, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.056, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.056, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.028, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nov": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.223, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.739, 0.005, 0.371, 0.0001, 0.0001, 0.004, 0.0001, 0.014, 0.258, 0.258, 0.003, 0.008, 0.827, 0.256, 1.132, 0.016, 0.643, 0.521, 0.435, 0.122, 0.19, 0.117, 0.125, 0.112, 0.14, 0.247, 0.122, 0.023, 0.02, 0.012, 0.021, 0.004, 0.0001, 0.495, 0.126, 0.101, 0.11, 0.205, 0.084, 0.113, 0.079, 0.113, 0.072, 0.274, 0.517, 0.205, 0.19, 0.072, 0.148, 0.01, 0.107, 0.475, 0.124, 0.103, 0.078, 0.049, 0.006, 0.028, 0.032, 0.002, 0.0001, 0.003, 0.0001, 0.002, 0.0001, 6.407, 1.088, 0.275, 3.233, 10.596, 0.875, 0.958, 0.605, 7.974, 0.212, 2.738, 4.237, 2.737, 5.182, 4.585, 1.557, 0.08, 4.568, 4.834, 4.299, 2.875, 0.823, 0.156, 0.296, 0.238, 0.085, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.026, 0.009, 0.01, 0.005, 0.006, 0.003, 0.001, 0.003, 0.003, 0.003, 0.001, 0.001, 0.003, 0.004, 0.0001, 0.0001, 0.003, 0.001, 0.003, 0.016, 0.003, 0.003, 0.001, 0.001, 0.001, 0.007, 0.002, 0.003, 0.003, 0.007, 0.001, 0.0001, 0.012, 0.008, 0.002, 0.005, 0.005, 0.002, 0.003, 0.003, 0.008, 0.015, 0.002, 0.001, 0.004, 0.007, 0.004, 0.004, 0.003, 0.005, 0.01, 0.013, 0.003, 0.002, 0.006, 0.004, 0.012, 0.004, 0.008, 0.008, 0.012, 0.008, 0.004, 0.006, 0.0001, 0.0001, 0.013, 0.071, 0.012, 0.013, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.04, 0.019, 0.02, 0.007, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.008, 0.025, 0.004, 0.0001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nrm": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.521, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.376, 0.004, 0.467, 0.0001, 0.0001, 0.003, 0.0001, 1.947, 0.163, 0.162, 0.0001, 0.0001, 0.761, 0.157, 0.914, 0.012, 1.102, 1.934, 0.564, 0.483, 0.476, 0.487, 0.557, 0.61, 0.644, 0.66, 0.069, 0.027, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.78, 0.094, 0.435, 0.253, 0.108, 0.06, 0.094, 0.042, 0.231, 0.101, 0.009, 0.332, 0.216, 0.104, 0.043, 0.114, 0.015, 0.096, 0.165, 0.06, 0.048, 0.107, 0.012, 0.147, 0.029, 0.002, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 4.848, 0.485, 1.639, 2.302, 7.56, 0.544, 0.696, 1.469, 3.879, 0.15, 0.04, 3.065, 1.372, 5.618, 3.164, 1.345, 0.499, 2.846, 4.958, 4.48, 3.809, 0.712, 0.015, 0.135, 0.467, 0.062, 0.0001, 1.427, 0.0001, 0.0001, 0.0001, 0.085, 0.003, 0.016, 0.002, 0.004, 0.002, 0.001, 0.0001, 0.002, 0.014, 0.026, 0.0001, 0.001, 0.001, 0.016, 0.0001, 0.001, 0.001, 0.001, 0.016, 0.002, 0.001, 0.0001, 0.0001, 0.002, 0.06, 0.0001, 0.023, 0.002, 0.001, 0.0001, 0.001, 0.219, 0.004, 0.233, 0.004, 0.005, 0.011, 0.0001, 0.016, 0.454, 2.065, 0.259, 0.013, 0.002, 0.004, 0.368, 0.008, 0.001, 0.008, 0.002, 0.004, 0.081, 0.004, 0.002, 0.012, 0.002, 0.151, 0.004, 0.112, 0.003, 0.005, 0.001, 0.003, 0.0001, 0.0001, 0.015, 4.079, 0.017, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.029, 0.013, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.077, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nso": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.78, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.755, 0.002, 0.038, 0.001, 0.0001, 0.004, 0.0001, 0.009, 0.457, 0.457, 0.0001, 0.0001, 0.676, 0.052, 0.694, 0.005, 0.466, 0.863, 0.377, 0.269, 0.237, 0.244, 0.243, 0.245, 0.241, 0.264, 0.019, 0.004, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.278, 0.349, 0.291, 0.135, 0.079, 0.05, 0.105, 0.055, 0.212, 0.029, 0.164, 0.314, 0.912, 0.402, 0.025, 0.107, 0.005, 0.046, 0.407, 0.145, 0.02, 0.095, 0.034, 0.21, 0.005, 0.034, 0.003, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 11.556, 1.304, 0.158, 0.76, 9.745, 0.742, 5.815, 1.511, 2.097, 0.062, 3.221, 3.795, 3.273, 4.341, 8.239, 1.391, 0.015, 2.291, 2.998, 2.898, 0.946, 0.091, 3.286, 0.014, 0.713, 0.058, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.019, 0.718, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.045, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.083, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.134, 0.0001, 0.733, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "nv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.509, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.471, 0.0001, 0.553, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.132, 0.131, 0.0001, 0.0001, 0.333, 0.05, 0.853, 0.008, 0.262, 0.198, 0.155, 0.093, 0.082, 0.107, 0.089, 0.066, 0.073, 0.069, 0.012, 0.267, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.105, 0.358, 0.12, 0.313, 0.022, 0.005, 0.023, 0.24, 0.014, 0.023, 0.045, 0.016, 0.036, 0.298, 0.014, 0.019, 0.001, 0.01, 0.1, 0.28, 0.004, 0.005, 0.04, 0.001, 0.048, 0.004, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 5.817, 1.241, 0.605, 3.905, 1.9, 0.016, 1.415, 4.266, 6.018, 0.364, 1.038, 1.394, 0.149, 2.559, 2.764, 0.063, 0.003, 0.149, 2.248, 2.042, 0.092, 0.019, 0.145, 0.037, 1.033, 1.245, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.08, 1.403, 1.567, 0.013, 0.082, 1.105, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.001, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.067, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.294, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 2.758, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 2.445, 0.0001, 0.311, 0.0001, 4.591, 0.0001, 0.504, 0.001, 0.001, 0.001, 2.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.013, 4.172, 0.001, 0.0001, 0.013, 0.0001, 0.0001, 0.002, 11.893, 1.899, 1.744, 0.0001, 0.311, 0.0001, 0.0001, 4.171, 0.0001, 1.234, 0.0001, 0.002, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.08, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ny": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.625, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.431, 0.001, 0.161, 0.0001, 0.001, 0.013, 0.004, 0.199, 0.151, 0.149, 0.001, 0.0001, 0.726, 0.052, 1.005, 0.011, 0.425, 0.321, 0.242, 0.114, 0.121, 0.146, 0.109, 0.097, 0.1, 0.188, 0.119, 0.008, 0.003, 0.006, 0.003, 0.001, 0.0001, 0.324, 0.194, 0.362, 0.113, 0.083, 0.06, 0.055, 0.057, 0.099, 0.059, 0.134, 0.101, 0.607, 0.172, 0.041, 0.204, 0.005, 0.064, 0.151, 0.1, 0.088, 0.025, 0.048, 0.003, 0.047, 0.083, 0.018, 0.0001, 0.019, 0.0001, 0.0001, 0.003, 13.746, 1.132, 1.623, 2.856, 4.347, 0.427, 1.15, 2.997, 7.993, 0.223, 3.837, 3.15, 3.985, 6.204, 4.4, 1.606, 0.018, 2.007, 1.898, 3.156, 4.108, 0.173, 2.53, 0.014, 1.184, 1.868, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.066, 0.003, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.004, 0.05, 0.0001, 0.0001, 0.006, 0.005, 0.001, 0.001, 0.013, 0.003, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.013, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.004, 0.001, 0.006, 0.001, 0.06, 0.0001, 0.011, 0.002, 0.003, 0.003, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.023, 0.029, 0.004, 0.064, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.009, 0.002, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.066, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "oc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.196, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.065, 0.002, 0.316, 0.046, 0.0001, 0.007, 0.001, 0.708, 0.193, 0.193, 0.002, 0.001, 0.913, 0.337, 0.785, 0.01, 0.177, 0.339, 0.143, 0.091, 0.092, 0.097, 0.087, 0.093, 0.11, 0.155, 0.065, 0.02, 0.037, 0.032, 0.038, 0.002, 0.0001, 0.316, 0.163, 0.28, 0.118, 0.18, 0.101, 0.108, 0.046, 0.126, 0.059, 0.019, 0.366, 0.206, 0.087, 0.061, 0.2, 0.02, 0.116, 0.247, 0.092, 0.045, 0.108, 0.016, 0.03, 0.009, 0.007, 0.013, 0.0001, 0.013, 0.0001, 0.002, 0.0001, 9.22, 0.793, 2.634, 3.53, 8.653, 0.714, 1.084, 0.594, 5.176, 0.154, 0.069, 4.196, 2.017, 5.599, 4.023, 1.809, 0.517, 4.973, 5.482, 4.438, 3.287, 0.768, 0.022, 0.148, 0.146, 0.139, 0.0001, 0.011, 0.002, 0.002, 0.0001, 0.071, 0.004, 0.003, 0.002, 0.001, 0.001, 0.002, 0.002, 0.007, 0.009, 0.001, 0.001, 0.001, 0.004, 0.001, 0.001, 0.001, 0.001, 0.006, 0.007, 0.005, 0.001, 0.0001, 0.0001, 0.001, 0.051, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.145, 0.074, 0.024, 0.002, 0.002, 0.001, 0.002, 0.134, 0.929, 0.452, 0.016, 0.026, 0.001, 0.096, 0.005, 0.03, 0.005, 0.004, 0.448, 0.027, 0.01, 0.002, 0.002, 0.002, 0.002, 0.004, 0.011, 0.027, 0.011, 0.002, 0.002, 0.002, 0.0001, 0.0001, 0.068, 2.417, 0.003, 0.007, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.008, 0.004, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.067, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "olo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.555, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.165, 0.001, 0.091, 0.0001, 0.0001, 0.009, 0.001, 0.061, 0.221, 0.221, 0.0001, 0.001, 0.891, 0.306, 1.442, 0.031, 0.305, 0.513, 0.256, 0.174, 0.154, 0.153, 0.124, 0.134, 0.157, 0.296, 0.102, 0.011, 0.01, 0.003, 0.01, 0.002, 0.001, 0.151, 0.077, 0.024, 0.041, 0.069, 0.036, 0.06, 0.101, 0.085, 0.112, 0.389, 0.128, 0.177, 0.115, 0.068, 0.258, 0.001, 0.092, 0.352, 0.141, 0.032, 0.27, 0.012, 0.021, 0.024, 0.01, 0.006, 0.0001, 0.006, 0.0001, 0.001, 0.005, 7.441, 0.351, 0.076, 1.841, 5.414, 0.122, 0.914, 2.187, 8.145, 1.143, 3.3, 4.3, 1.89, 6.075, 4.589, 1.29, 0.001, 2.71, 3.519, 3.872, 5.598, 2.436, 0.016, 0.008, 1.054, 0.985, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.389, 0.086, 0.073, 0.032, 0.01, 0.011, 0.006, 0.01, 0.008, 0.001, 0.002, 0.006, 0.036, 0.349, 0.005, 0.017, 0.009, 0.004, 0.01, 0.105, 0.013, 0.002, 0.002, 0.002, 0.005, 0.148, 0.017, 0.006, 0.011, 0.056, 0.001, 0.018, 0.051, 0.118, 0.003, 0.002, 1.86, 0.003, 0.001, 0.007, 0.003, 0.003, 0.001, 0.01, 0.001, 0.003, 0.001, 0.002, 0.143, 0.012, 0.077, 0.019, 0.054, 0.096, 0.298, 0.031, 0.077, 0.038, 0.064, 0.07, 0.021, 0.096, 0.259, 0.018, 0.0001, 0.0001, 0.075, 2.173, 0.359, 0.275, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.002, 0.001, 0.0001, 0.01, 0.006, 0.977, 0.34, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.008, 0.007, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.004, 0.001, 0.32, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "om": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.856, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.47, 0.007, 0.135, 0.001, 0.001, 0.02, 0.001, 0.415, 0.149, 0.148, 0.003, 0.001, 0.598, 0.088, 0.774, 0.024, 0.177, 0.196, 0.107, 0.055, 0.058, 0.069, 0.055, 0.055, 0.062, 0.111, 0.03, 0.031, 0.014, 0.003, 0.015, 0.004, 0.0001, 0.377, 0.227, 0.059, 0.14, 0.066, 0.078, 0.179, 0.124, 0.131, 0.063, 0.149, 0.064, 0.172, 0.076, 0.188, 0.061, 0.049, 0.057, 0.159, 0.099, 0.042, 0.016, 0.108, 0.015, 0.076, 0.01, 0.011, 0.0001, 0.011, 0.0001, 0.003, 0.13, 18.959, 2.318, 0.672, 2.536, 5.221, 1.607, 1.449, 2.234, 8.071, 0.935, 2.586, 2.201, 2.811, 5.266, 4.391, 0.29, 0.68, 3.658, 3.072, 4.065, 4.017, 0.087, 0.574, 0.143, 1.425, 0.099, 0.01, 0.001, 0.01, 0.0001, 0.0001, 0.186, 0.003, 0.002, 0.003, 0.006, 0.002, 0.002, 0.001, 0.004, 0.002, 0.003, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.006, 0.004, 0.0001, 0.0001, 0.0001, 0.007, 0.12, 0.0001, 0.0001, 0.011, 0.011, 0.005, 0.0001, 0.099, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.03, 0.008, 0.002, 0.002, 0.003, 0.001, 0.001, 0.002, 0.001, 0.002, 0.003, 0.004, 0.003, 0.002, 0.001, 0.001, 0.002, 0.001, 0.001, 0.003, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.105, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.002, 0.0001, 0.0001, 0.007, 0.004, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.024, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.191, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "or": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.414, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.789, 0.001, 0.049, 0.0001, 0.0001, 0.027, 0.0001, 0.016, 0.066, 0.066, 0.001, 0.0001, 0.194, 0.029, 0.065, 0.008, 0.012, 0.014, 0.009, 0.005, 0.004, 0.005, 0.004, 0.004, 0.004, 0.006, 0.014, 0.004, 0.003, 0.001, 0.003, 0.0001, 0.0001, 0.006, 0.004, 0.006, 0.004, 0.003, 0.002, 0.002, 0.003, 0.007, 0.001, 0.002, 0.003, 0.005, 0.003, 0.003, 0.005, 0.0001, 0.003, 0.007, 0.006, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.081, 0.011, 0.027, 0.026, 0.08, 0.013, 0.015, 0.029, 0.067, 0.002, 0.006, 0.037, 0.021, 0.058, 0.062, 0.019, 0.001, 0.059, 0.056, 0.058, 0.033, 0.007, 0.008, 0.003, 0.014, 0.002, 0.0001, 0.009, 0.0001, 0.0001, 0.0001, 0.461, 0.87, 0.209, 0.086, 0.0001, 0.314, 0.231, 1.688, 0.023, 0.138, 0.001, 0.379, 0.073, 2.56, 0.0001, 0.427, 0.002, 0.0001, 0.0001, 0.16, 0.011, 1.385, 0.13, 0.389, 0.041, 0.233, 0.239, 0.105, 0.371, 0.014, 0.058, 0.871, 0.144, 0.225, 0.017, 0.346, 1.495, 0.883, 0.609, 0.353, 1.21, 0.043, 0.827, 0.113, 24.372, 7.183, 0.945, 0.296, 2.678, 0.059, 0.571, 0.283, 0.0001, 0.05, 0.328, 0.264, 0.929, 0.701, 0.0001, 0.0001, 0.094, 0.0001, 2.794, 2.229, 0.0001, 0.0001, 0.045, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.66, 0.0001, 0.069, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "os": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.314, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.198, 0.001, 0.075, 0.0001, 0.0001, 0.009, 0.0001, 0.003, 0.221, 0.221, 0.0001, 0.001, 0.656, 0.268, 0.647, 0.003, 0.149, 0.239, 0.119, 0.07, 0.068, 0.074, 0.065, 0.065, 0.08, 0.138, 0.043, 0.023, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.003, 0.003, 0.004, 0.002, 0.002, 0.002, 0.002, 0.001, 0.024, 0.001, 0.001, 0.002, 0.003, 0.002, 0.002, 0.003, 0.0001, 0.002, 0.005, 0.002, 0.001, 0.007, 0.001, 0.014, 0.001, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.032, 0.005, 0.009, 0.008, 0.024, 0.004, 0.005, 0.006, 0.02, 0.001, 0.005, 0.014, 0.008, 0.019, 0.019, 0.004, 0.0001, 0.021, 0.013, 0.014, 0.012, 0.003, 0.002, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.723, 1.959, 2.433, 1.742, 0.485, 1.045, 0.733, 0.104, 0.039, 0.003, 0.515, 3.703, 0.088, 0.047, 0.033, 0.054, 0.152, 0.11, 0.038, 0.09, 0.183, 0.021, 0.005, 0.03, 0.137, 0.06, 0.132, 0.043, 0.092, 0.063, 0.026, 0.055, 0.062, 0.15, 0.074, 0.109, 0.063, 0.115, 4.882, 0.027, 0.022, 0.001, 0.001, 0.076, 0.0001, 0.018, 0.005, 0.007, 3.663, 0.542, 0.469, 1.346, 2.223, 0.835, 0.243, 0.949, 1.778, 1.262, 0.952, 1.134, 1.447, 2.532, 1.739, 0.347, 0.0001, 0.0001, 0.16, 4.829, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.01, 0.0001, 0.002, 0.001, 23.204, 15.519, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.01, 0.127, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.424, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.354, 0.003, 0.052, 0.0001, 0.0001, 0.005, 0.0001, 0.026, 0.07, 0.07, 0.0001, 0.001, 0.252, 0.083, 0.057, 0.008, 0.09, 0.134, 0.073, 0.034, 0.034, 0.037, 0.032, 0.033, 0.039, 0.073, 0.023, 0.007, 0.005, 0.003, 0.005, 0.001, 0.0001, 0.004, 0.002, 0.004, 0.002, 0.003, 0.002, 0.002, 0.002, 0.006, 0.001, 0.001, 0.002, 0.003, 0.002, 0.002, 0.003, 0.0001, 0.002, 0.005, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 0.002, 0.003, 0.035, 0.006, 0.011, 0.011, 0.037, 0.006, 0.008, 0.011, 0.028, 0.001, 0.004, 0.018, 0.013, 0.026, 0.027, 0.009, 0.001, 0.025, 0.019, 0.024, 0.012, 0.004, 0.004, 0.001, 0.005, 0.001, 0.0001, 0.008, 0.0001, 0.0001, 0.0001, 1.534, 0.423, 1.17, 0.001, 0.001, 0.437, 0.548, 1.695, 0.606, 0.237, 0.024, 0.573, 0.09, 0.23, 0.001, 0.065, 0.035, 0.0001, 0.001, 0.028, 0.011, 1.172, 0.229, 0.428, 0.077, 0.013, 0.442, 0.041, 0.755, 0.032, 0.001, 0.286, 0.066, 0.192, 0.017, 0.267, 1.499, 0.487, 1.308, 0.154, 24.532, 6.371, 0.647, 0.143, 0.447, 0.172, 0.696, 0.068, 2.373, 0.727, 0.943, 0.005, 0.001, 0.891, 0.001, 0.001, 1.461, 1.12, 0.001, 0.001, 0.465, 0.001, 2.611, 1.487, 0.0001, 0.0001, 0.039, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.006, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 30.092, 0.001, 0.038, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pag": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.03, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.592, 0.019, 0.241, 0.0001, 0.0001, 0.002, 0.0001, 0.022, 0.579, 0.579, 0.001, 0.002, 1.012, 0.179, 1.28, 0.004, 0.607, 0.517, 0.439, 0.246, 0.233, 0.22, 0.206, 0.189, 0.188, 0.203, 0.287, 0.029, 0.2, 0.003, 0.2, 0.007, 0.0001, 0.514, 0.233, 0.299, 0.377, 0.293, 0.091, 0.061, 0.039, 0.141, 0.067, 0.298, 0.143, 0.228, 0.153, 0.107, 0.323, 0.017, 0.066, 0.835, 0.144, 0.158, 0.036, 0.141, 0.001, 0.016, 0.024, 0.044, 0.0001, 0.045, 0.0001, 0.001, 0.0001, 14.553, 2.155, 0.612, 2.213, 4.092, 0.158, 2.144, 0.652, 5.448, 0.026, 2.943, 4.371, 1.62, 6.468, 4.169, 1.489, 0.134, 1.92, 4.171, 4.111, 1.822, 0.133, 0.774, 0.019, 2.966, 0.181, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.082, 0.003, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.005, 0.002, 0.0001, 0.001, 0.001, 0.001, 0.048, 0.0001, 0.001, 0.01, 0.009, 0.0001, 0.0001, 0.004, 0.017, 0.0001, 0.001, 0.002, 0.001, 0.004, 0.002, 0.001, 0.008, 0.001, 0.001, 0.001, 0.005, 0.0001, 0.001, 0.003, 0.012, 0.002, 0.005, 0.002, 0.001, 0.001, 0.001, 0.004, 0.001, 0.005, 0.001, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.004, 0.049, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.003, 0.075, 0.004, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pam": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.69, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.089, 0.008, 0.379, 0.001, 0.002, 0.006, 0.002, 0.032, 0.278, 0.278, 0.002, 0.002, 1.032, 0.272, 0.824, 0.024, 0.328, 0.294, 0.247, 0.119, 0.115, 0.114, 0.097, 0.092, 0.106, 0.173, 0.084, 0.034, 0.037, 0.005, 0.037, 0.004, 0.0001, 0.446, 0.258, 0.283, 0.225, 0.147, 0.167, 0.119, 0.095, 0.427, 0.078, 0.159, 0.17, 0.339, 0.137, 0.085, 0.26, 0.014, 0.119, 0.316, 0.173, 0.073, 0.129, 0.078, 0.01, 0.038, 0.027, 0.056, 0.0001, 0.058, 0.0001, 0.003, 0.0001, 11.717, 1.42, 1.079, 1.934, 5.65, 0.412, 5.535, 0.984, 6.498, 0.051, 2.215, 3.499, 2.546, 9.826, 2.443, 1.882, 0.041, 3.326, 2.846, 3.809, 3.421, 0.311, 0.524, 0.064, 1.429, 0.196, 0.0001, 0.012, 0.001, 0.0001, 0.0001, 0.064, 0.007, 0.004, 0.005, 0.004, 0.002, 0.003, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.006, 0.001, 0.001, 0.002, 0.001, 0.002, 0.019, 0.004, 0.002, 0.002, 0.002, 0.003, 0.009, 0.002, 0.002, 0.017, 0.008, 0.009, 0.013, 0.012, 0.022, 0.007, 0.002, 0.067, 0.005, 0.005, 0.005, 0.009, 0.033, 0.004, 0.003, 0.003, 0.006, 0.006, 0.004, 0.01, 0.012, 0.01, 0.01, 0.006, 0.003, 0.032, 0.002, 0.004, 0.003, 0.008, 0.007, 0.067, 0.001, 0.005, 0.003, 0.0001, 0.0001, 0.014, 0.263, 0.005, 0.006, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.008, 0.006, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.04, 0.011, 0.063, 0.0001, 0.001, 0.004, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pap": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.577, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 17.041, 0.006, 0.256, 0.002, 0.001, 0.008, 0.005, 0.088, 0.145, 0.144, 0.001, 0.001, 0.829, 0.082, 0.948, 0.014, 0.296, 0.379, 0.247, 0.133, 0.132, 0.125, 0.108, 0.098, 0.111, 0.184, 0.198, 0.046, 0.009, 0.003, 0.009, 0.012, 0.0001, 0.325, 0.157, 0.17, 0.173, 0.346, 0.09, 0.081, 0.124, 0.155, 0.09, 0.129, 0.105, 0.233, 0.162, 0.14, 0.176, 0.005, 0.132, 0.285, 0.134, 0.07, 0.056, 0.051, 0.003, 0.069, 0.012, 0.014, 0.0001, 0.014, 0.0001, 0.003, 0.0001, 10.584, 1.755, 0.96, 3.481, 6.611, 0.57, 0.793, 1.086, 6.922, 0.094, 2.168, 2.197, 2.209, 6.462, 5.124, 1.889, 0.017, 4.387, 3.838, 4.459, 3.468, 0.348, 0.249, 0.043, 0.415, 0.112, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.051, 0.006, 0.003, 0.006, 0.004, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.012, 0.002, 0.005, 0.003, 0.001, 0.001, 0.001, 0.006, 0.016, 0.001, 0.001, 0.01, 0.01, 0.001, 0.001, 0.023, 0.288, 0.003, 0.003, 0.003, 0.001, 0.002, 0.007, 0.143, 0.171, 0.002, 0.003, 0.001, 0.133, 0.0001, 0.002, 0.003, 0.162, 0.171, 0.076, 0.001, 0.002, 0.002, 0.001, 0.004, 0.053, 0.027, 0.003, 0.086, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.023, 1.326, 0.004, 0.005, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.007, 0.004, 0.023, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.007, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.007, 0.048, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pcd": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.27, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.657, 0.008, 0.673, 0.0001, 0.0001, 0.003, 0.004, 1.579, 0.485, 0.482, 0.004, 0.002, 0.764, 0.743, 0.844, 0.029, 0.205, 0.439, 0.185, 0.104, 0.105, 0.099, 0.112, 0.109, 0.159, 0.228, 0.141, 0.017, 0.014, 0.103, 0.015, 0.005, 0.0001, 0.322, 0.315, 0.578, 0.163, 0.158, 0.188, 0.128, 0.139, 0.259, 0.095, 0.035, 0.293, 0.23, 0.148, 0.082, 0.416, 0.024, 0.141, 0.362, 0.132, 0.056, 0.121, 0.049, 0.026, 0.011, 0.008, 0.008, 0.0001, 0.009, 0.0001, 0.004, 0.004, 4.164, 0.548, 3.109, 2.876, 7.669, 0.633, 0.742, 2.062, 6.133, 0.168, 0.261, 3.265, 1.584, 5.6, 3.825, 1.718, 0.299, 3.984, 4.345, 3.994, 3.516, 0.729, 0.062, 0.099, 0.331, 0.121, 0.0001, 0.008, 0.001, 0.001, 0.0001, 0.34, 0.006, 0.009, 0.004, 0.003, 0.002, 0.003, 0.003, 0.01, 0.086, 0.002, 0.001, 0.004, 0.005, 0.003, 0.002, 0.003, 0.002, 0.002, 0.018, 0.009, 0.001, 0.001, 0.002, 0.003, 0.283, 0.001, 0.003, 0.003, 0.002, 0.001, 0.001, 0.283, 0.006, 0.038, 0.003, 0.005, 0.006, 0.003, 0.025, 0.548, 2.644, 0.014, 0.04, 0.002, 0.005, 0.009, 0.049, 0.019, 0.006, 0.015, 0.007, 0.051, 0.004, 0.002, 0.022, 0.007, 0.018, 0.005, 0.043, 0.008, 0.005, 0.004, 0.007, 0.0001, 0.0001, 0.109, 3.762, 0.007, 0.017, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.003, 0.0001, 0.0001, 0.018, 0.008, 0.022, 0.007, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.009, 0.005, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.006, 0.329, 0.001, 0.002, 0.009, 0.006, 0.002, 0.003, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pdc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.347, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.345, 0.014, 0.296, 0.0001, 0.002, 0.001, 0.004, 0.083, 0.252, 0.251, 0.004, 0.0001, 0.899, 0.34, 1.232, 0.016, 0.318, 0.569, 0.233, 0.139, 0.122, 0.133, 0.151, 0.187, 0.197, 0.319, 0.11, 0.028, 0.009, 0.001, 0.009, 0.014, 0.001, 0.435, 0.396, 0.269, 0.612, 0.446, 0.261, 0.34, 0.266, 0.158, 0.126, 0.345, 0.316, 0.408, 0.189, 0.112, 0.446, 0.018, 0.164, 0.922, 0.173, 0.1, 0.127, 0.257, 0.003, 0.091, 0.087, 0.001, 0.0001, 0.002, 0.0001, 0.002, 0.001, 5.822, 0.784, 2.856, 3.127, 10.434, 0.913, 1.544, 3.717, 6.407, 0.033, 0.633, 2.751, 1.821, 6.435, 2.483, 0.545, 0.012, 4.834, 4.912, 3.94, 2.397, 0.665, 1.309, 0.053, 0.442, 0.521, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.13, 0.003, 0.001, 0.002, 0.004, 0.002, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.012, 0.001, 0.0001, 0.001, 0.0001, 0.012, 0.052, 0.0001, 0.0001, 0.021, 0.02, 0.013, 0.012, 0.005, 0.005, 0.001, 0.002, 0.087, 0.001, 0.002, 0.004, 0.002, 0.014, 0.002, 0.001, 0.002, 0.005, 0.0001, 0.002, 0.002, 0.007, 0.005, 0.01, 0.013, 0.001, 0.014, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.03, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.019, 0.191, 0.004, 0.004, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.003, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.011, 0.007, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.129, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pfl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.263, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.706, 0.009, 0.364, 0.0001, 0.0001, 0.013, 0.001, 0.091, 0.195, 0.195, 0.003, 0.001, 0.686, 0.342, 1.046, 0.015, 0.201, 0.285, 0.126, 0.084, 0.075, 0.083, 0.073, 0.08, 0.09, 0.133, 0.057, 0.007, 0.004, 0.002, 0.005, 0.003, 0.0001, 0.282, 0.468, 0.129, 0.696, 0.183, 0.211, 0.353, 0.23, 0.145, 0.127, 0.364, 0.254, 0.349, 0.172, 0.165, 0.214, 0.007, 0.306, 0.587, 0.085, 0.112, 0.133, 0.253, 0.004, 0.004, 0.083, 0.004, 0.0001, 0.004, 0.0001, 0.001, 0.001, 5.458, 1.123, 3.147, 5.166, 9.364, 1.012, 2.021, 4.491, 5.715, 0.138, 0.564, 2.856, 2.578, 5.721, 2.982, 0.339, 0.016, 4.316, 5.155, 2.124, 2.997, 0.789, 1.349, 0.04, 0.119, 0.948, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.073, 0.001, 0.001, 0.001, 0.025, 0.007, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.014, 0.001, 0.005, 0.002, 0.0001, 0.001, 0.004, 0.001, 0.001, 0.027, 0.001, 0.026, 0.15, 0.041, 0.008, 0.01, 0.001, 1.309, 0.09, 0.0001, 0.002, 0.017, 0.105, 0.002, 0.002, 0.07, 0.023, 0.0001, 0.002, 0.004, 0.001, 0.016, 0.015, 0.003, 0.033, 0.029, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.044, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.024, 1.987, 0.001, 0.015, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.07, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.055, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.983, 0.003, 0.019, 0.0001, 0.0001, 0.001, 0.0001, 0.005, 0.015, 0.015, 0.0001, 0.0001, 0.196, 0.05, 0.162, 0.001, 0.012, 0.032, 0.016, 0.014, 0.013, 0.015, 0.012, 0.01, 0.008, 0.011, 0.012, 0.002, 0.001, 0.001, 0.001, 0.003, 0.0001, 0.014, 0.008, 0.005, 0.012, 0.009, 0.003, 0.003, 0.008, 0.003, 0.003, 0.005, 0.005, 0.006, 0.016, 0.004, 0.013, 0.0001, 0.005, 0.023, 0.015, 0.011, 0.002, 0.003, 0.0001, 0.036, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.761, 0.196, 0.276, 0.305, 0.454, 0.017, 0.165, 0.648, 0.799, 0.068, 0.545, 0.11, 0.265, 0.512, 0.167, 0.383, 0.0001, 0.263, 0.542, 0.555, 0.3, 0.254, 0.017, 0.002, 0.396, 0.01, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.585, 1.349, 0.631, 0.309, 0.001, 0.704, 0.099, 0.738, 0.496, 0.135, 0.002, 0.598, 0.015, 3.249, 0.0001, 0.471, 0.004, 0.001, 0.0001, 0.007, 0.008, 1.087, 0.017, 0.945, 0.067, 0.032, 0.055, 0.004, 0.076, 0.002, 0.011, 0.133, 0.012, 0.507, 0.001, 0.315, 18.309, 9.394, 0.355, 1.002, 0.59, 0.225, 0.335, 0.42, 0.344, 0.341, 0.537, 1.408, 2.487, 0.078, 0.724, 0.001, 0.0001, 0.527, 0.043, 0.432, 2.004, 0.558, 0.0001, 0.0001, 0.014, 0.0001, 1.176, 0.438, 0.0001, 0.0001, 0.0001, 0.095, 0.876, 0.019, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 26.149, 0.497, 0.061, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pih": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.022, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.521, 0.009, 0.204, 0.0001, 0.0001, 0.004, 0.001, 2.454, 0.291, 0.293, 0.002, 0.001, 0.888, 0.295, 1.488, 0.018, 0.431, 0.479, 0.302, 0.13, 0.163, 0.176, 0.152, 0.154, 0.17, 0.228, 0.107, 0.024, 0.002, 0.004, 0.002, 0.0001, 0.0001, 0.58, 0.327, 0.222, 0.2, 0.438, 0.166, 0.153, 0.179, 0.225, 0.154, 0.281, 0.167, 0.407, 0.329, 0.234, 0.386, 0.004, 0.196, 0.528, 0.379, 0.134, 0.065, 0.116, 0.0001, 0.083, 0.034, 0.002, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 8.21, 0.769, 1.021, 1.638, 6.843, 0.747, 0.93, 1.82, 7.969, 0.261, 1.7, 3.13, 1.378, 5.431, 3.567, 1.341, 0.022, 3.668, 4.749, 4.715, 2.394, 0.289, 0.906, 0.045, 1.135, 0.094, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.092, 0.039, 0.046, 0.01, 0.019, 0.008, 0.006, 0.003, 0.009, 0.001, 0.001, 0.017, 0.011, 0.007, 0.006, 0.02, 0.015, 0.009, 0.001, 0.019, 0.012, 0.0001, 0.001, 0.006, 0.003, 0.028, 0.004, 0.009, 0.002, 0.007, 0.002, 0.006, 0.077, 0.019, 0.006, 0.004, 0.002, 0.001, 0.001, 0.004, 0.006, 0.035, 0.017, 0.004, 0.004, 0.012, 0.004, 0.0001, 0.082, 0.011, 0.044, 0.037, 0.018, 0.034, 0.007, 0.017, 0.057, 0.008, 0.047, 0.04, 0.021, 0.031, 0.077, 0.012, 0.0001, 0.0001, 0.098, 0.125, 0.02, 0.026, 0.002, 0.0001, 0.0001, 0.016, 0.007, 0.004, 0.0001, 0.001, 0.0001, 0.0001, 0.45, 0.193, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.026, 0.048, 0.0001, 0.0001, 0.003, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pms": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.299, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.832, 0.001, 0.162, 0.0001, 0.0001, 0.004, 0.001, 1.011, 0.156, 0.156, 0.0001, 0.0001, 1.253, 0.787, 0.992, 0.342, 0.318, 0.594, 0.327, 0.281, 0.214, 0.205, 0.231, 0.17, 0.187, 0.641, 0.121, 0.014, 0.149, 0.035, 0.149, 0.034, 0.0001, 0.513, 0.293, 0.3, 0.101, 0.054, 0.096, 0.128, 0.035, 0.079, 0.03, 0.029, 0.305, 0.216, 0.126, 0.053, 0.205, 0.008, 0.226, 0.291, 0.098, 0.028, 0.104, 0.023, 0.014, 0.012, 0.01, 0.002, 0.0001, 0.002, 0.0001, 0.011, 0.0001, 9.348, 0.753, 2.346, 3.335, 4.488, 0.731, 0.919, 0.76, 4.936, 0.31, 0.385, 3.85, 2.042, 6.393, 3.543, 1.375, 0.084, 3.728, 4.566, 4.041, 1.559, 0.688, 0.145, 0.036, 0.118, 0.134, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.165, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.007, 0.001, 0.059, 0.002, 0.001, 0.004, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.02, 0.115, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.661, 0.007, 0.005, 0.001, 0.004, 0.0001, 0.001, 0.004, 0.295, 0.64, 0.002, 2.121, 0.312, 0.006, 0.001, 0.001, 0.002, 0.006, 0.658, 0.012, 0.019, 0.001, 0.003, 0.0001, 0.001, 0.07, 0.002, 0.002, 0.005, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.286, 4.639, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.002, 0.007, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.137, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pnb": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.056, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.3, 0.001, 0.061, 0.0001, 0.0001, 0.004, 0.0001, 0.019, 0.084, 0.084, 0.0001, 0.001, 0.02, 0.088, 0.041, 0.008, 0.132, 0.201, 0.102, 0.067, 0.062, 0.067, 0.058, 0.058, 0.067, 0.099, 0.044, 0.011, 0.014, 0.019, 0.014, 0.0001, 0.0001, 0.005, 0.015, 0.004, 0.007, 0.004, 0.002, 0.006, 0.002, 0.006, 0.004, 0.001, 0.002, 0.002, 0.003, 0.002, 0.003, 0.0001, 0.004, 0.004, 0.005, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.0001, 0.016, 0.0001, 0.016, 0.0001, 0.001, 0.001, 0.078, 0.007, 0.025, 0.032, 0.067, 0.025, 0.012, 0.031, 0.075, 0.001, 0.005, 0.047, 0.03, 0.057, 0.061, 0.011, 0.001, 0.056, 0.035, 0.078, 0.015, 0.016, 0.005, 0.001, 0.026, 0.001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.037, 1.78, 0.208, 0.002, 1.668, 1.155, 3.673, 0.01, 3.168, 0.001, 0.005, 0.003, 4.417, 0.001, 0.019, 0.031, 0.026, 0.339, 2.06, 0.022, 0.634, 0.001, 0.0001, 0.0001, 0.015, 0.009, 0.0001, 0.004, 0.002, 0.002, 0.0001, 0.002, 0.01, 0.033, 0.198, 0.001, 0.068, 0.002, 0.419, 5.965, 1.027, 1.695, 1.567, 0.022, 0.752, 0.178, 0.132, 2.73, 0.025, 2.399, 0.214, 1.507, 0.366, 0.211, 0.103, 0.103, 0.037, 0.788, 1.21, 0.001, 0.001, 0.002, 1.61, 0.001, 0.0001, 0.0001, 0.01, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.007, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 17.991, 10.598, 5.545, 8.408, 0.0001, 0.004, 0.0001, 0.0001, 0.008, 0.001, 0.037, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "pnt": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.111, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 8.571, 0.001, 0.271, 0.0001, 0.0001, 0.001, 0.001, 0.535, 0.166, 0.167, 0.003, 0.001, 0.374, 0.066, 0.728, 0.006, 0.22, 0.256, 0.213, 0.123, 0.09, 0.093, 0.091, 0.105, 0.105, 0.136, 0.082, 0.003, 0.006, 0.005, 0.006, 0.0001, 0.0001, 0.027, 0.009, 0.018, 0.007, 0.008, 0.002, 0.007, 0.007, 0.011, 0.005, 0.01, 0.006, 0.014, 0.004, 0.003, 0.01, 0.001, 0.009, 0.009, 0.01, 0.001, 0.002, 0.009, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.102, 0.019, 0.03, 0.031, 0.116, 0.01, 0.025, 0.028, 0.096, 0.002, 0.026, 0.047, 0.026, 0.078, 0.081, 0.022, 0.002, 0.09, 0.05, 0.057, 0.045, 0.011, 0.005, 0.004, 0.012, 0.009, 0.0001, 0.182, 0.0001, 0.0001, 0.0001, 1.086, 2.28, 1.131, 1.649, 3.333, 0.911, 0.24, 0.496, 0.069, 0.319, 0.04, 0.001, 0.823, 0.357, 0.222, 0.002, 0.015, 0.24, 0.073, 0.124, 0.043, 0.159, 0.008, 0.102, 0.032, 0.07, 0.198, 0.037, 0.134, 0.044, 0.005, 0.136, 0.134, 0.042, 0.001, 0.198, 0.245, 0.005, 0.018, 0.079, 0.003, 0.008, 0.001, 0.042, 1.012, 0.786, 0.269, 1.272, 0.017, 4.369, 0.221, 0.746, 0.384, 2.578, 0.144, 1.385, 0.301, 1.937, 1.463, 1.533, 1.22, 4.421, 0.103, 3.268, 0.0001, 0.0001, 0.091, 0.022, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 29.379, 12.776, 0.049, 0.015, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.003, 0.011, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.059, 0.041, 0.0001, 0.001, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ps": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.579, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.932, 0.004, 0.044, 0.0001, 0.0001, 0.003, 0.0001, 0.002, 0.118, 0.118, 0.001, 0.001, 0.026, 0.037, 0.443, 0.009, 0.022, 0.03, 0.021, 0.014, 0.011, 0.012, 0.01, 0.009, 0.01, 0.013, 0.062, 0.001, 0.002, 0.005, 0.002, 0.0001, 0.0001, 0.015, 0.007, 0.011, 0.007, 0.006, 0.005, 0.004, 0.007, 0.009, 0.002, 0.003, 0.005, 0.01, 0.006, 0.004, 0.009, 0.001, 0.006, 0.013, 0.009, 0.003, 0.002, 0.003, 0.001, 0.001, 0.001, 0.004, 0.0001, 0.004, 0.0001, 0.003, 0.0001, 0.147, 0.023, 0.055, 0.054, 0.165, 0.027, 0.031, 0.061, 0.131, 0.002, 0.012, 0.073, 0.048, 0.109, 0.113, 0.034, 0.002, 0.103, 0.097, 0.116, 0.047, 0.015, 0.017, 0.005, 0.027, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.103, 0.528, 0.202, 0.231, 2.393, 1.822, 2.655, 3.163, 4.608, 0.307, 2.451, 0.006, 1.513, 0.136, 0.015, 0.009, 1.675, 0.004, 0.009, 0.507, 0.005, 0.0001, 0.154, 0.001, 0.093, 0.002, 0.229, 0.007, 0.005, 0.003, 0.0001, 0.006, 0.024, 0.025, 0.048, 0.014, 0.025, 0.008, 0.038, 4.145, 0.839, 1.375, 1.43, 0.077, 0.25, 0.229, 0.647, 2.983, 0.085, 2.528, 0.449, 1.14, 0.525, 0.146, 0.073, 0.106, 0.064, 0.333, 0.407, 0.02, 0.265, 0.005, 1.278, 0.002, 0.0001, 0.0001, 0.016, 0.003, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.028, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 16.081, 19.012, 3.763, 3.368, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.026, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.038, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "qu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.204, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.108, 0.002, 0.638, 0.0001, 0.0001, 0.004, 0.002, 0.39, 0.494, 0.494, 0.05, 0.002, 1.04, 0.188, 0.977, 0.036, 0.261, 0.409, 0.214, 0.137, 0.12, 0.137, 0.117, 0.112, 0.136, 0.208, 0.401, 0.061, 0.041, 0.006, 0.041, 0.004, 0.0001, 0.371, 0.173, 0.36, 0.119, 0.076, 0.064, 0.097, 0.189, 0.192, 0.096, 0.255, 0.187, 0.305, 0.078, 0.042, 0.428, 0.148, 0.146, 0.31, 0.198, 0.198, 0.061, 0.174, 0.014, 0.102, 0.014, 0.014, 0.0001, 0.015, 0.0001, 0.002, 0.0001, 14.813, 0.229, 1.579, 0.795, 1.296, 0.084, 0.286, 2.331, 7.773, 0.067, 3.004, 4.09, 3.086, 5.006, 1.165, 2.96, 3.746, 3.293, 3.447, 3.494, 5.678, 0.135, 1.682, 0.024, 2.244, 0.111, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.055, 0.016, 0.009, 0.013, 0.008, 0.006, 0.004, 0.006, 0.004, 0.004, 0.003, 0.002, 0.006, 0.007, 0.003, 0.002, 0.012, 0.023, 0.002, 0.011, 0.004, 0.004, 0.003, 0.002, 0.004, 0.015, 0.003, 0.003, 0.005, 0.003, 0.002, 0.003, 0.038, 0.068, 0.004, 0.005, 0.014, 0.005, 0.006, 0.009, 0.007, 0.056, 0.005, 0.005, 0.005, 0.075, 0.004, 0.006, 0.014, 0.34, 0.013, 0.069, 0.007, 0.008, 0.006, 0.005, 0.016, 0.009, 0.022, 0.008, 0.011, 0.009, 0.01, 0.01, 0.0001, 0.0001, 0.026, 0.649, 0.01, 0.009, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.008, 0.002, 0.0001, 0.042, 0.02, 0.051, 0.016, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.006, 0.016, 0.012, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.031, 0.016, 0.047, 0.001, 0.001, 0.006, 0.005, 0.002, 0.002, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "rm": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.612, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.511, 0.003, 0.167, 0.0001, 0.0001, 0.015, 0.0001, 0.104, 0.151, 0.151, 0.003, 0.0001, 0.439, 0.065, 0.823, 0.012, 0.199, 0.275, 0.114, 0.07, 0.072, 0.078, 0.067, 0.073, 0.099, 0.138, 0.045, 0.054, 0.005, 0.002, 0.005, 0.002, 0.0001, 0.139, 0.111, 0.151, 0.1, 0.17, 0.069, 0.113, 0.045, 0.217, 0.028, 0.029, 0.208, 0.121, 0.055, 0.036, 0.132, 0.042, 0.086, 0.226, 0.106, 0.051, 0.07, 0.023, 0.003, 0.003, 0.008, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.001, 11.404, 0.601, 3.031, 3.677, 6.353, 0.757, 1.578, 1.412, 6.549, 0.076, 0.068, 4.778, 1.866, 6.046, 2.159, 1.856, 0.265, 4.97, 5.963, 4.375, 3.712, 1.407, 0.03, 0.131, 0.049, 0.802, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.828, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.043, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.675, 0.0001, 0.001, 0.003, 0.001, 0.001, 0.0001, 0.294, 0.003, 0.002, 0.0001, 0.006, 0.001, 0.001, 0.002, 0.333, 0.017, 0.002, 0.02, 0.128, 0.003, 0.0001, 0.001, 0.004, 0.002, 0.027, 0.004, 0.001, 0.001, 0.012, 0.0001, 0.001, 0.054, 0.054, 0.02, 0.042, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.079, 0.841, 0.004, 0.004, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.828, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "rmy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.439, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.022, 0.009, 0.624, 0.001, 0.0001, 0.014, 0.003, 0.015, 0.443, 0.441, 0.003, 0.003, 1.038, 0.232, 0.983, 0.037, 0.243, 0.24, 0.172, 0.071, 0.075, 0.081, 0.064, 0.056, 0.058, 0.153, 0.179, 0.028, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 0.429, 0.231, 0.183, 0.167, 0.219, 0.086, 0.091, 0.078, 0.193, 0.094, 0.424, 0.255, 0.23, 0.124, 0.22, 0.316, 0.009, 0.404, 0.577, 0.193, 0.066, 0.142, 0.014, 0.008, 0.107, 0.022, 0.003, 0.0001, 0.004, 0.0001, 0.001, 0.001, 10.986, 1.012, 0.769, 2.129, 6.975, 0.334, 0.958, 2.547, 6.287, 0.364, 2.952, 3.16, 1.944, 5.241, 5.031, 1.512, 0.108, 4.343, 3.649, 3.301, 2.127, 1.805, 0.051, 0.119, 2.702, 0.234, 0.0001, 0.003, 0.001, 0.001, 0.0001, 0.065, 0.024, 0.024, 0.136, 0.011, 0.006, 0.01, 0.023, 0.009, 0.001, 0.005, 0.016, 0.01, 0.054, 0.02, 0.004, 0.003, 0.007, 0.001, 0.025, 0.008, 0.009, 0.004, 0.007, 0.004, 0.054, 0.005, 0.044, 0.006, 0.002, 0.003, 0.008, 0.038, 0.056, 0.061, 0.004, 0.069, 0.023, 0.011, 0.016, 0.012, 0.016, 0.02, 0.006, 0.003, 0.014, 0.084, 0.01, 0.051, 0.028, 0.039, 0.03, 0.013, 0.014, 0.009, 0.007, 0.027, 0.007, 0.021, 0.023, 0.024, 0.034, 0.062, 0.014, 0.0001, 0.0001, 0.036, 0.28, 0.165, 0.061, 0.0001, 0.011, 0.089, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.007, 0.003, 0.242, 0.129, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.026, 0.02, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.128, 0.005, 0.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.004, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "rn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.466, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.984, 0.029, 0.062, 0.0001, 0.0001, 0.003, 0.0001, 0.574, 0.079, 0.089, 0.011, 0.0001, 1.075, 0.049, 1.054, 0.052, 0.102, 0.296, 0.219, 0.136, 0.097, 0.085, 0.071, 0.069, 0.063, 0.086, 0.222, 0.076, 0.048, 0.0001, 0.048, 0.055, 0.0001, 0.35, 0.153, 0.043, 0.033, 0.087, 0.042, 0.05, 0.106, 0.336, 0.016, 0.136, 0.035, 0.208, 0.24, 0.02, 0.055, 0.001, 0.138, 0.132, 0.082, 0.29, 0.029, 0.019, 0.0001, 0.195, 0.032, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 10.973, 3.104, 0.817, 1.265, 5.117, 0.295, 2.193, 1.806, 7.318, 0.542, 2.677, 0.668, 3.393, 5.179, 4.081, 0.677, 0.004, 4.518, 2.135, 2.161, 5.935, 1.185, 2.07, 0.007, 2.3, 1.432, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.174, 0.023, 0.002, 0.005, 0.007, 0.004, 0.003, 0.003, 0.006, 0.0001, 0.004, 0.0001, 0.015, 0.271, 0.012, 0.002, 0.008, 0.004, 0.004, 0.008, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.284, 0.0001, 0.196, 0.005, 0.002, 0.004, 0.014, 0.082, 0.437, 0.009, 0.0001, 0.0001, 0.006, 0.001, 0.018, 0.002, 0.13, 0.002, 0.17, 0.0001, 0.586, 0.007, 0.108, 0.004, 0.019, 0.001, 0.014, 0.007, 0.001, 0.01, 0.001, 0.001, 0.002, 0.049, 0.153, 0.015, 0.123, 0.121, 0.0001, 0.0001, 0.0001, 0.386, 1.335, 0.539, 0.45, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.015, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.02, 0.053, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.167, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "rue": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.059, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.931, 0.003, 0.134, 0.004, 0.0001, 0.006, 0.0001, 0.004, 0.175, 0.175, 0.004, 0.001, 0.601, 0.077, 0.708, 0.007, 0.16, 0.303, 0.147, 0.097, 0.093, 0.095, 0.084, 0.09, 0.099, 0.137, 0.031, 0.011, 0.003, 0.006, 0.002, 0.001, 0.0001, 0.009, 0.006, 0.011, 0.005, 0.005, 0.004, 0.005, 0.007, 0.017, 0.002, 0.003, 0.006, 0.008, 0.01, 0.004, 0.008, 0.0001, 0.006, 0.012, 0.008, 0.004, 0.005, 0.003, 0.005, 0.001, 0.001, 0.002, 0.011, 0.003, 0.0001, 0.004, 0.0001, 0.091, 0.013, 0.033, 0.032, 0.099, 0.015, 0.014, 0.02, 0.081, 0.006, 0.012, 0.045, 0.028, 0.055, 0.071, 0.018, 0.002, 0.069, 0.058, 0.052, 0.039, 0.016, 0.006, 0.004, 0.014, 0.011, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 2.51, 1.935, 2.11, 1.119, 0.168, 0.507, 0.468, 0.486, 0.356, 0.046, 0.009, 1.422, 0.678, 0.003, 0.239, 0.784, 0.089, 0.301, 0.121, 0.074, 0.371, 0.035, 1.647, 0.529, 0.012, 0.009, 0.09, 0.04, 0.101, 0.07, 0.061, 0.137, 0.108, 0.152, 0.055, 0.234, 0.024, 0.016, 0.017, 0.032, 0.025, 0.005, 0.001, 0.015, 0.002, 0.004, 0.009, 0.015, 3.672, 0.621, 2.19, 0.526, 1.267, 2.143, 0.348, 0.764, 1.53, 0.62, 1.849, 1.595, 1.255, 2.617, 4.166, 1.0, 0.0001, 0.0001, 0.065, 0.026, 0.003, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.006, 0.0001, 0.02, 0.009, 27.547, 15.28, 0.159, 0.0001, 0.0001, 0.001, 0.001, 0.004, 0.006, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.004, 0.115, 0.004, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "rw": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.278, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.768, 0.007, 0.605, 0.0001, 0.0001, 0.01, 0.005, 0.156, 0.48, 0.479, 0.0001, 0.001, 0.554, 0.104, 0.846, 0.03, 0.199, 0.216, 0.155, 0.113, 0.085, 0.082, 0.092, 0.069, 0.073, 0.138, 0.279, 0.158, 0.014, 0.006, 0.014, 0.022, 0.0001, 0.463, 0.203, 0.115, 0.093, 0.067, 0.068, 0.134, 0.078, 0.521, 0.056, 0.247, 0.076, 0.283, 0.278, 0.063, 0.134, 0.006, 0.219, 0.18, 0.135, 0.469, 0.053, 0.038, 0.003, 0.047, 0.033, 0.002, 0.005, 0.003, 0.0001, 0.005, 0.003, 10.187, 2.795, 0.85, 1.072, 4.678, 0.399, 2.704, 1.553, 8.747, 0.332, 2.605, 0.938, 3.443, 4.833, 3.164, 0.42, 0.036, 4.477, 2.07, 2.396, 6.084, 0.329, 1.941, 0.023, 2.813, 1.358, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.976, 0.03, 0.025, 0.03, 0.043, 0.049, 0.025, 0.021, 0.028, 0.009, 0.036, 0.011, 0.018, 0.014, 0.026, 0.013, 0.02, 0.015, 0.01, 0.15, 0.008, 0.015, 0.009, 0.008, 0.011, 0.787, 0.007, 0.008, 0.021, 0.011, 0.011, 0.034, 0.016, 0.016, 0.009, 0.011, 0.025, 0.012, 0.025, 0.083, 0.028, 0.057, 0.013, 0.014, 0.038, 0.019, 0.024, 0.039, 0.055, 0.067, 0.03, 0.036, 0.018, 0.034, 0.017, 0.013, 0.045, 0.024, 0.03, 0.026, 0.034, 0.02, 0.028, 0.012, 0.0001, 0.0001, 0.03, 0.13, 0.052, 0.028, 0.001, 0.001, 0.001, 0.009, 0.002, 0.001, 0.003, 0.0001, 0.02, 0.007, 0.21, 0.107, 0.008, 0.005, 0.001, 0.006, 0.005, 0.025, 0.234, 0.162, 0.005, 0.009, 0.0001, 0.0001, 0.009, 0.0001, 0.108, 0.055, 0.961, 0.001, 0.002, 0.013, 0.008, 0.004, 0.003, 0.002, 0.001, 0.001, 0.003, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.358, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.441, 0.003, 0.019, 0.0001, 0.0001, 0.003, 0.0001, 0.034, 0.04, 0.042, 0.0001, 0.001, 0.189, 0.124, 0.061, 0.009, 0.003, 0.004, 0.003, 0.002, 0.002, 0.001, 0.001, 0.001, 0.001, 0.002, 0.022, 0.001, 0.005, 0.003, 0.005, 0.005, 0.0001, 0.002, 0.001, 0.007, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.036, 0.006, 0.009, 0.018, 0.033, 0.003, 0.005, 0.01, 0.026, 0.001, 0.003, 0.015, 0.009, 0.022, 0.022, 0.013, 0.0001, 0.02, 0.014, 0.02, 0.007, 0.002, 0.005, 0.001, 0.004, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.485, 0.531, 0.737, 0.892, 0.001, 0.437, 0.14, 1.014, 0.103, 0.083, 0.003, 0.31, 0.053, 4.186, 0.001, 0.123, 0.004, 0.001, 0.0001, 0.016, 0.005, 0.929, 0.077, 0.397, 0.036, 0.098, 0.308, 0.026, 0.311, 0.017, 0.076, 0.146, 0.037, 0.11, 0.008, 0.362, 26.378, 7.803, 0.723, 0.32, 1.5, 0.025, 0.84, 0.05, 0.176, 0.36, 1.148, 1.481, 1.847, 0.0001, 0.431, 0.017, 0.001, 1.168, 0.412, 0.409, 1.347, 0.264, 0.0001, 0.0001, 0.002, 0.029, 2.443, 1.602, 0.0001, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.344, 0.0001, 0.071, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sah": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.686, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.508, 0.002, 0.063, 0.0001, 0.0001, 0.006, 0.0001, 0.001, 0.091, 0.092, 0.0001, 0.001, 0.559, 0.22, 0.713, 0.008, 0.141, 0.211, 0.115, 0.061, 0.06, 0.065, 0.051, 0.05, 0.056, 0.124, 0.035, 0.013, 0.006, 0.002, 0.006, 0.002, 0.0001, 0.005, 0.004, 0.005, 0.003, 0.002, 0.002, 0.002, 0.002, 0.017, 0.001, 0.002, 0.002, 0.004, 0.003, 0.002, 0.003, 0.0001, 0.002, 0.006, 0.004, 0.001, 0.004, 0.001, 0.007, 0.002, 0.0001, 0.003, 0.0001, 0.003, 0.0001, 0.004, 0.0001, 0.029, 0.008, 0.012, 0.008, 0.028, 0.005, 0.006, 0.038, 0.023, 0.001, 0.004, 0.015, 0.01, 0.02, 0.025, 0.007, 0.0001, 0.024, 0.015, 0.017, 0.012, 0.003, 0.003, 0.001, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.31, 1.601, 3.034, 2.129, 0.054, 0.947, 0.056, 0.303, 0.028, 0.008, 0.002, 2.384, 0.325, 2.811, 0.018, 0.129, 0.129, 0.118, 0.035, 0.051, 0.111, 0.426, 0.011, 0.007, 0.063, 0.002, 0.123, 0.02, 0.075, 0.059, 0.083, 0.041, 0.09, 0.172, 0.066, 0.042, 0.018, 0.342, 0.005, 0.017, 0.028, 0.688, 0.0001, 0.065, 0.003, 0.027, 0.027, 0.911, 6.03, 1.253, 0.256, 0.681, 0.862, 0.464, 0.024, 0.065, 2.76, 0.764, 1.431, 3.082, 0.589, 3.175, 2.114, 0.327, 0.0001, 0.0001, 0.173, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.001, 24.486, 17.038, 2.234, 0.706, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.102, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sc": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.057, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.585, 0.005, 0.337, 0.0001, 0.0001, 0.01, 0.001, 0.519, 0.179, 0.179, 0.0001, 0.001, 0.997, 0.097, 0.746, 0.025, 0.237, 0.292, 0.15, 0.087, 0.082, 0.09, 0.079, 0.083, 0.093, 0.166, 0.067, 0.032, 0.007, 0.002, 0.008, 0.003, 0.0001, 0.224, 0.132, 0.261, 0.092, 0.103, 0.086, 0.108, 0.028, 0.255, 0.028, 0.024, 0.103, 0.181, 0.091, 0.054, 0.171, 0.006, 0.093, 0.455, 0.116, 0.064, 0.058, 0.024, 0.025, 0.008, 0.012, 0.012, 0.0001, 0.012, 0.0001, 0.0001, 0.0001, 9.363, 0.921, 2.394, 4.179, 7.513, 0.745, 1.075, 0.764, 6.94, 0.075, 0.096, 1.956, 1.851, 5.606, 4.069, 1.688, 0.018, 4.534, 7.393, 5.178, 5.316, 0.445, 0.037, 0.029, 0.067, 0.854, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.107, 0.01, 0.006, 0.008, 0.004, 0.002, 0.002, 0.003, 0.006, 0.002, 0.002, 0.002, 0.006, 0.004, 0.002, 0.001, 0.003, 0.002, 0.003, 0.008, 0.004, 0.001, 0.002, 0.001, 0.003, 0.058, 0.001, 0.002, 0.016, 0.017, 0.001, 0.001, 0.306, 0.009, 0.002, 0.003, 0.003, 0.002, 0.001, 0.004, 0.232, 0.016, 0.003, 0.007, 0.252, 0.007, 0.001, 0.002, 0.008, 0.007, 0.176, 0.008, 0.002, 0.004, 0.003, 0.006, 0.005, 0.096, 0.007, 0.007, 0.006, 0.004, 0.004, 0.004, 0.0001, 0.0001, 0.032, 1.097, 0.007, 0.006, 0.0001, 0.0001, 0.0001, 0.011, 0.003, 0.007, 0.001, 0.0001, 0.018, 0.009, 0.023, 0.009, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.003, 0.006, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.096, 0.007, 0.001, 0.002, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "scn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.769, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.859, 0.005, 0.376, 0.001, 0.0001, 0.006, 0.001, 0.62, 0.187, 0.189, 0.001, 0.001, 0.862, 0.093, 0.813, 0.026, 0.237, 0.31, 0.158, 0.093, 0.09, 0.099, 0.092, 0.087, 0.104, 0.161, 0.085, 0.032, 0.027, 0.008, 0.034, 0.003, 0.0001, 0.211, 0.12, 0.299, 0.095, 0.077, 0.106, 0.122, 0.053, 0.143, 0.031, 0.023, 0.333, 0.207, 0.158, 0.044, 0.198, 0.02, 0.123, 0.32, 0.125, 0.061, 0.101, 0.022, 0.022, 0.008, 0.012, 0.019, 0.0001, 0.019, 0.0001, 0.007, 0.001, 8.698, 0.715, 3.649, 2.751, 2.764, 0.729, 1.223, 0.71, 11.435, 0.098, 0.087, 3.105, 2.009, 5.881, 1.955, 1.977, 0.125, 4.751, 3.262, 4.998, 7.156, 1.012, 0.04, 0.022, 0.077, 0.978, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.123, 0.005, 0.005, 0.005, 0.003, 0.001, 0.002, 0.001, 0.009, 0.002, 0.001, 0.001, 0.004, 0.003, 0.001, 0.001, 0.001, 0.002, 0.002, 0.01, 0.003, 0.001, 0.002, 0.001, 0.012, 0.059, 0.001, 0.002, 0.014, 0.013, 0.001, 0.001, 0.271, 0.006, 0.312, 0.002, 0.001, 0.001, 0.001, 0.004, 0.478, 0.013, 0.046, 0.017, 0.359, 0.007, 0.096, 0.002, 0.008, 0.004, 0.23, 0.006, 0.189, 0.003, 0.002, 0.003, 0.004, 0.145, 0.006, 0.184, 0.003, 0.004, 0.002, 0.003, 0.0001, 0.0001, 0.038, 2.342, 0.007, 0.007, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.018, 0.008, 0.018, 0.009, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.107, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sco": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.424, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.792, 0.003, 0.394, 0.001, 0.002, 0.018, 0.003, 0.122, 0.265, 0.265, 0.001, 0.001, 1.079, 0.194, 0.878, 0.014, 0.365, 0.437, 0.262, 0.125, 0.119, 0.131, 0.116, 0.116, 0.135, 0.238, 0.065, 0.052, 0.004, 0.002, 0.004, 0.001, 0.0001, 0.38, 0.213, 0.323, 0.162, 0.132, 0.149, 0.164, 0.147, 0.281, 0.103, 0.117, 0.162, 0.281, 0.134, 0.098, 0.228, 0.015, 0.18, 0.416, 0.389, 0.071, 0.084, 0.096, 0.009, 0.031, 0.022, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.001, 7.525, 0.973, 2.32, 1.915, 9.145, 0.867, 0.966, 3.175, 6.858, 0.086, 0.556, 2.986, 1.72, 5.779, 4.854, 1.317, 0.066, 4.925, 4.607, 6.432, 2.109, 0.676, 1.003, 0.125, 1.018, 0.144, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.052, 0.009, 0.005, 0.004, 0.004, 0.003, 0.002, 0.004, 0.002, 0.003, 0.002, 0.001, 0.002, 0.005, 0.001, 0.002, 0.001, 0.002, 0.001, 0.033, 0.006, 0.001, 0.002, 0.002, 0.002, 0.009, 0.001, 0.002, 0.003, 0.003, 0.001, 0.005, 0.039, 0.026, 0.003, 0.006, 0.015, 0.004, 0.002, 0.007, 0.005, 0.025, 0.002, 0.006, 0.002, 0.019, 0.001, 0.002, 0.01, 0.012, 0.013, 0.016, 0.004, 0.005, 0.011, 0.002, 0.007, 0.003, 0.007, 0.003, 0.009, 0.004, 0.004, 0.002, 0.0001, 0.0001, 0.051, 0.152, 0.018, 0.014, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.011, 0.005, 0.019, 0.007, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.009, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.005, 0.05, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sd": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.527, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.452, 0.004, 0.026, 0.001, 0.0001, 0.002, 0.0001, 0.004, 0.108, 0.108, 0.004, 0.001, 0.009, 0.252, 0.565, 0.015, 0.09, 0.18, 0.083, 0.051, 0.047, 0.052, 0.047, 0.048, 0.055, 0.112, 0.038, 0.003, 0.004, 0.004, 0.004, 0.0001, 0.0001, 0.01, 0.007, 0.009, 0.005, 0.004, 0.003, 0.004, 0.004, 0.005, 0.002, 0.003, 0.004, 0.007, 0.004, 0.003, 0.007, 0.001, 0.004, 0.011, 0.007, 0.002, 0.002, 0.003, 0.0001, 0.001, 0.0001, 0.005, 0.0001, 0.005, 0.001, 0.003, 0.0001, 0.093, 0.018, 0.025, 0.03, 0.086, 0.014, 0.018, 0.031, 0.075, 0.002, 0.009, 0.041, 0.026, 0.061, 0.064, 0.018, 0.001, 0.061, 0.048, 0.062, 0.025, 0.01, 0.009, 0.005, 0.016, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.358, 0.355, 0.367, 0.044, 1.492, 1.56, 3.771, 2.24, 3.043, 0.003, 5.411, 0.006, 0.747, 0.045, 0.229, 0.346, 0.139, 0.006, 0.013, 0.002, 0.041, 0.001, 0.001, 0.003, 0.036, 0.237, 0.0001, 0.007, 0.063, 0.063, 0.001, 0.009, 0.066, 0.346, 0.511, 0.005, 0.013, 0.004, 0.6, 4.552, 0.858, 0.458, 2.417, 0.053, 1.486, 0.357, 0.248, 1.426, 0.07, 2.412, 0.238, 1.475, 0.403, 0.209, 0.078, 0.141, 0.068, 0.553, 0.222, 0.578, 0.001, 0.647, 1.291, 0.291, 0.0001, 0.0001, 0.065, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 17.302, 19.772, 4.118, 0.84, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.198, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.104, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "se": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.476, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.534, 0.002, 0.233, 0.001, 0.001, 0.008, 0.001, 0.011, 0.255, 0.258, 0.0001, 0.001, 1.05, 0.297, 1.247, 0.015, 0.373, 0.513, 0.317, 0.174, 0.148, 0.157, 0.145, 0.145, 0.159, 0.258, 0.106, 0.008, 0.018, 0.002, 0.018, 0.002, 0.0001, 0.188, 0.166, 0.071, 0.251, 0.09, 0.093, 0.235, 0.162, 0.082, 0.134, 0.245, 0.18, 0.186, 0.183, 0.112, 0.147, 0.004, 0.206, 0.487, 0.123, 0.053, 0.171, 0.019, 0.003, 0.015, 0.006, 0.005, 0.0001, 0.005, 0.0001, 0.001, 0.0001, 10.038, 0.915, 0.217, 3.327, 5.602, 0.262, 2.678, 1.589, 6.671, 1.512, 2.136, 5.043, 2.364, 3.492, 4.102, 0.745, 0.01, 2.956, 3.613, 3.601, 3.337, 2.349, 0.035, 0.018, 0.282, 0.057, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.058, 0.044, 0.003, 0.004, 0.008, 0.009, 0.002, 0.003, 0.002, 0.002, 0.001, 0.119, 0.035, 0.369, 0.001, 0.002, 0.002, 0.302, 0.004, 0.024, 0.002, 0.002, 0.006, 0.001, 0.007, 0.006, 0.003, 0.005, 0.009, 0.024, 0.001, 0.003, 0.073, 3.336, 0.013, 0.002, 0.299, 0.044, 0.019, 0.052, 0.004, 0.017, 0.001, 0.011, 0.001, 0.006, 0.001, 0.004, 0.019, 0.004, 0.042, 0.006, 0.01, 0.008, 0.063, 0.001, 0.053, 0.001, 0.006, 0.009, 0.008, 0.006, 0.098, 0.001, 0.0001, 0.0001, 0.118, 3.226, 0.711, 1.0, 0.0001, 0.004, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.008, 0.003, 0.027, 0.008, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.004, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.008, 0.055, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.098, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.879, 0.044, 0.115, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.198, 0.211, 0.0001, 0.0001, 0.85, 0.464, 1.499, 0.007, 0.524, 0.5, 0.381, 0.203, 0.246, 0.244, 0.244, 0.191, 0.262, 0.229, 0.082, 0.038, 0.0001, 0.0001, 0.0001, 0.029, 0.0001, 0.282, 0.315, 0.126, 0.106, 0.101, 0.06, 0.092, 0.086, 0.092, 0.093, 0.251, 0.348, 0.227, 0.266, 0.057, 0.128, 0.0001, 0.081, 0.346, 0.343, 0.013, 0.053, 0.416, 0.005, 0.029, 0.062, 0.002, 0.0001, 0.002, 0.0001, 0.015, 0.0001, 5.706, 1.515, 0.218, 1.433, 4.537, 0.262, 2.208, 0.762, 2.069, 0.092, 2.86, 1.7, 1.242, 5.365, 3.328, 0.599, 0.022, 1.81, 1.981, 3.619, 0.984, 0.189, 0.434, 0.086, 1.565, 0.929, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.004, 0.029, 0.0001, 0.015, 0.0001, 0.0001, 0.007, 0.004, 0.002, 0.007, 0.016, 0.004, 0.004, 0.022, 0.015, 0.018, 0.0001, 0.004, 0.007, 0.022, 0.0001, 0.009, 0.004, 0.0001, 0.005, 0.0001, 0.016, 0.002, 0.0001, 0.002, 0.059, 0.007, 0.009, 1.785, 0.013, 1.12, 0.007, 0.002, 0.044, 0.027, 0.112, 1.609, 0.647, 0.002, 0.026, 3.804, 0.577, 0.007, 0.004, 0.0001, 0.022, 0.564, 0.0001, 1.689, 0.002, 0.005, 0.046, 0.002, 0.403, 0.176, 0.0001, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 12.759, 0.005, 0.07, 0.0001, 0.007, 0.0001, 0.007, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.024, 0.011, 0.007, 0.0001, 0.0001, 0.015, 0.004, 0.002, 0.0001, 0.002, 0.002, 0.004, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.387, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.061, 0.002, 0.275, 0.0001, 0.001, 0.015, 0.001, 0.014, 0.187, 0.187, 0.0001, 0.002, 0.95, 0.147, 1.223, 0.02, 0.376, 0.495, 0.321, 0.161, 0.177, 0.142, 0.127, 0.123, 0.133, 0.217, 0.047, 0.016, 0.003, 0.003, 0.003, 0.002, 0.0001, 0.169, 0.152, 0.152, 0.124, 0.074, 0.068, 0.115, 0.09, 0.132, 0.082, 0.135, 0.104, 0.207, 0.208, 0.116, 0.297, 0.005, 0.117, 0.252, 0.137, 0.082, 0.102, 0.023, 0.008, 0.009, 0.058, 0.012, 0.0001, 0.012, 0.0001, 0.003, 0.0001, 8.404, 0.811, 0.782, 2.282, 6.596, 0.226, 1.221, 0.511, 7.186, 3.593, 2.512, 2.698, 2.143, 5.119, 6.434, 1.798, 0.011, 3.759, 3.618, 2.964, 3.066, 2.297, 0.032, 0.02, 0.068, 1.245, 0.001, 0.003, 0.001, 0.0001, 0.0001, 0.106, 0.072, 0.05, 0.059, 0.003, 0.006, 0.013, 0.266, 0.014, 0.001, 0.001, 0.001, 0.012, 0.537, 0.001, 0.001, 0.005, 0.13, 0.005, 0.01, 0.006, 0.001, 0.001, 0.002, 0.039, 0.019, 0.011, 0.012, 0.016, 0.006, 0.015, 0.006, 0.037, 0.532, 0.005, 0.005, 0.003, 0.001, 0.001, 0.002, 0.003, 0.013, 0.001, 0.004, 0.001, 0.013, 0.001, 0.001, 0.155, 0.023, 0.063, 0.029, 0.039, 0.108, 0.009, 0.019, 0.119, 0.002, 0.045, 0.036, 0.04, 0.092, 0.525, 0.041, 0.0001, 0.0001, 0.038, 0.074, 0.943, 0.945, 0.0001, 0.0001, 0.009, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.013, 0.006, 0.916, 0.332, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.045, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "si": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.314, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.928, 0.001, 0.061, 0.001, 0.001, 0.005, 0.0001, 0.009, 0.059, 0.059, 0.0001, 0.001, 0.185, 0.034, 0.404, 0.009, 0.086, 0.094, 0.056, 0.028, 0.026, 0.03, 0.026, 0.025, 0.029, 0.049, 0.012, 0.004, 0.002, 0.002, 0.002, 0.002, 0.0001, 0.015, 0.008, 0.015, 0.008, 0.007, 0.006, 0.005, 0.007, 0.015, 0.002, 0.003, 0.006, 0.01, 0.006, 0.006, 0.01, 0.001, 0.006, 0.015, 0.013, 0.004, 0.004, 0.005, 0.001, 0.001, 0.001, 0.005, 0.0001, 0.005, 0.0001, 0.003, 0.0001, 0.173, 0.028, 0.067, 0.071, 0.23, 0.039, 0.038, 0.081, 0.157, 0.003, 0.016, 0.086, 0.051, 0.142, 0.142, 0.042, 0.002, 0.132, 0.124, 0.159, 0.054, 0.019, 0.027, 0.007, 0.032, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 2.252, 0.201, 0.275, 1.149, 0.707, 0.497, 0.106, 0.13, 0.003, 0.08, 2.719, 0.062, 0.013, 0.472, 0.0001, 1.466, 0.446, 0.166, 2.231, 0.489, 1.129, 0.007, 0.144, 0.0001, 0.039, 0.612, 2.039, 0.034, 0.759, 0.19, 0.015, 0.026, 0.094, 0.008, 0.192, 0.001, 0.005, 0.01, 0.001, 0.537, 0.012, 0.162, 0.001, 0.275, 0.003, 1.26, 0.067, 0.843, 0.165, 1.921, 0.001, 0.089, 0.809, 0.008, 15.577, 14.437, 1.305, 0.017, 1.681, 1.481, 0.0001, 0.796, 0.0001, 0.001, 0.0001, 0.0001, 0.014, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 29.588, 0.0001, 0.504, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sm": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.213, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 19.463, 0.008, 0.168, 0.0001, 0.003, 0.014, 0.002, 0.885, 0.148, 0.148, 0.0001, 0.001, 1.0, 0.173, 0.914, 0.009, 0.254, 0.312, 0.179, 0.14, 0.095, 0.115, 0.095, 0.086, 0.112, 0.168, 0.033, 0.027, 0.006, 0.002, 0.006, 0.005, 0.0001, 0.462, 0.087, 0.119, 0.039, 0.23, 0.233, 0.074, 0.06, 0.345, 0.031, 0.147, 0.149, 0.348, 0.135, 0.431, 0.236, 0.003, 0.115, 0.459, 0.28, 0.072, 0.088, 0.128, 0.02, 0.007, 0.009, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 15.436, 0.147, 0.251, 0.268, 7.552, 1.798, 1.939, 0.261, 7.65, 0.014, 0.507, 6.117, 2.84, 3.141, 6.14, 1.094, 0.011, 1.189, 2.656, 4.384, 4.707, 0.608, 0.084, 0.018, 0.145, 0.038, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.05, 0.151, 0.0001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.003, 0.002, 0.017, 0.002, 0.001, 0.003, 0.0001, 0.0001, 0.02, 0.001, 0.001, 0.0001, 0.001, 0.039, 0.002, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.005, 0.004, 0.0001, 0.011, 0.001, 0.001, 0.001, 0.001, 0.001, 0.006, 0.001, 0.028, 0.001, 0.004, 0.001, 0.001, 0.003, 0.003, 0.001, 0.003, 0.002, 0.002, 0.0001, 0.001, 0.002, 0.001, 0.002, 0.086, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.005, 0.033, 0.176, 0.042, 0.0001, 0.0001, 0.0001, 0.001, 0.085, 0.001, 0.0001, 0.0001, 0.007, 0.0001, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.046, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.427, 0.001, 0.194, 0.0001, 0.001, 0.007, 0.003, 0.024, 0.281, 0.281, 0.0001, 0.005, 0.597, 0.124, 0.956, 0.038, 0.114, 0.113, 0.073, 0.04, 0.036, 0.036, 0.026, 0.025, 0.034, 0.053, 0.08, 0.124, 0.002, 0.009, 0.002, 0.006, 0.0001, 0.169, 0.097, 0.234, 0.083, 0.107, 0.043, 0.1, 0.097, 0.095, 0.037, 0.196, 0.037, 0.454, 0.178, 0.024, 0.119, 0.003, 0.094, 0.231, 0.097, 0.036, 0.089, 0.031, 0.003, 0.009, 0.113, 0.039, 0.0001, 0.038, 0.0001, 0.002, 0.0001, 12.237, 1.335, 1.505, 2.374, 5.54, 0.412, 1.524, 3.199, 8.126, 0.115, 3.86, 0.667, 3.205, 6.578, 4.667, 1.202, 0.019, 4.537, 2.41, 2.721, 5.562, 2.325, 2.211, 0.043, 1.41, 2.325, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.012, 0.003, 0.001, 0.003, 0.001, 0.001, 0.001, 0.0001, 0.017, 0.001, 0.004, 0.001, 0.004, 0.0001, 0.001, 0.001, 0.01, 0.005, 0.003, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.016, 0.001, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.009, 0.004, 0.001, 0.001, 0.001, 0.001, 0.003, 0.003, 0.003, 0.004, 0.008, 0.001, 0.0001, 0.002, 0.0001, 0.001, 0.004, 0.002, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.011, 0.016, 0.003, 0.002, 0.0001, 0.0001, 0.0001, 0.037, 0.008, 0.027, 0.001, 0.001, 0.002, 0.001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "so": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.235, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.454, 0.003, 0.106, 0.0001, 0.001, 0.01, 0.006, 0.044, 0.175, 0.179, 0.001, 0.006, 0.698, 0.181, 0.663, 0.023, 0.173, 0.237, 0.118, 0.074, 0.068, 0.076, 0.069, 0.062, 0.061, 0.116, 0.103, 0.039, 0.006, 0.095, 0.008, 0.006, 0.001, 0.277, 0.176, 0.197, 0.21, 0.058, 0.067, 0.135, 0.123, 0.156, 0.069, 0.122, 0.08, 0.279, 0.092, 0.046, 0.025, 0.078, 0.077, 0.341, 0.096, 0.053, 0.009, 0.145, 0.085, 0.037, 0.009, 0.058, 0.001, 0.058, 0.0001, 0.009, 0.001, 20.28, 1.752, 0.781, 4.408, 3.807, 0.467, 1.801, 2.804, 6.156, 0.344, 2.692, 2.981, 1.937, 3.517, 5.007, 0.065, 0.666, 2.59, 2.645, 1.488, 3.47, 0.033, 1.517, 1.277, 3.257, 0.024, 0.006, 0.007, 0.006, 0.0001, 0.0001, 0.044, 0.021, 0.016, 0.015, 0.092, 0.046, 0.041, 0.026, 0.037, 0.007, 0.048, 0.005, 0.002, 0.004, 0.027, 0.011, 0.01, 0.009, 0.012, 0.004, 0.002, 0.001, 0.001, 0.002, 0.003, 0.016, 0.0001, 0.0001, 0.009, 0.011, 0.002, 0.005, 0.026, 0.005, 0.004, 0.02, 0.008, 0.009, 0.004, 0.102, 0.029, 0.015, 0.023, 0.008, 0.009, 0.018, 0.009, 0.021, 0.011, 0.034, 0.006, 0.02, 0.009, 0.011, 0.006, 0.006, 0.005, 0.024, 0.019, 0.018, 0.004, 0.003, 0.001, 0.004, 0.0001, 0.0001, 0.03, 0.015, 0.007, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.36, 0.404, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.045, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.034, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sq": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.871, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.83, 0.005, 0.212, 0.0001, 0.001, 0.008, 0.002, 0.025, 0.142, 0.143, 0.001, 0.002, 0.876, 0.197, 0.817, 0.021, 0.247, 0.322, 0.187, 0.096, 0.094, 0.095, 0.084, 0.083, 0.096, 0.185, 0.067, 0.019, 0.003, 0.004, 0.003, 0.004, 0.0001, 0.232, 0.164, 0.084, 0.121, 0.088, 0.104, 0.113, 0.084, 0.118, 0.051, 0.274, 0.113, 0.216, 0.178, 0.042, 0.229, 0.027, 0.103, 0.291, 0.126, 0.044, 0.092, 0.017, 0.024, 0.009, 0.037, 0.024, 0.0001, 0.024, 0.0001, 0.005, 0.001, 5.42, 0.732, 0.432, 2.174, 7.144, 0.635, 1.01, 2.972, 6.09, 2.066, 2.05, 2.101, 2.386, 4.875, 2.895, 1.724, 0.557, 5.177, 3.826, 5.956, 2.462, 1.012, 0.037, 0.057, 0.423, 0.487, 0.0001, 0.007, 0.0001, 0.0001, 0.0001, 0.107, 0.006, 0.004, 0.005, 0.003, 0.002, 0.002, 0.017, 0.002, 0.002, 0.001, 0.01, 0.001, 0.002, 0.002, 0.001, 0.001, 0.008, 0.001, 0.019, 0.002, 0.001, 0.001, 0.001, 0.003, 0.015, 0.001, 0.001, 0.032, 0.031, 0.002, 0.003, 0.048, 0.005, 0.005, 0.002, 0.005, 0.002, 0.002, 0.098, 0.005, 0.011, 0.001, 5.762, 0.002, 0.004, 0.002, 0.002, 0.006, 0.006, 0.012, 0.004, 0.005, 0.003, 0.003, 0.002, 0.003, 0.003, 0.003, 0.004, 0.006, 0.003, 0.003, 0.003, 0.0001, 0.0001, 0.063, 5.926, 0.008, 0.006, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.023, 0.009, 0.015, 0.012, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.007, 0.008, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.106, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "srn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.777, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 18.537, 0.004, 0.236, 0.0001, 0.0001, 0.009, 0.0001, 0.081, 0.222, 0.175, 0.0001, 0.0001, 0.673, 0.268, 1.397, 0.005, 0.412, 0.368, 0.15, 0.085, 0.102, 0.103, 0.102, 0.071, 0.07, 0.14, 0.041, 0.016, 0.015, 0.002, 0.015, 0.0001, 0.0001, 0.384, 0.184, 0.068, 0.478, 0.061, 0.057, 0.098, 0.039, 0.172, 0.08, 0.05, 0.052, 0.288, 0.1, 0.075, 0.116, 0.004, 0.117, 0.271, 0.146, 0.008, 0.023, 0.047, 0.004, 0.014, 0.007, 0.005, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 8.95, 2.176, 0.221, 2.431, 7.818, 1.651, 1.874, 0.226, 8.782, 0.064, 2.479, 1.698, 2.095, 8.318, 4.117, 1.376, 0.003, 4.52, 3.577, 2.919, 3.347, 0.156, 1.329, 0.018, 1.038, 0.054, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.042, 0.007, 0.007, 0.002, 0.003, 0.002, 0.003, 0.006, 0.003, 0.001, 0.002, 0.001, 0.006, 0.003, 0.002, 0.005, 0.004, 0.002, 0.001, 0.035, 0.002, 0.002, 0.002, 0.006, 0.002, 0.002, 0.002, 0.002, 0.002, 0.007, 0.002, 0.002, 0.024, 0.012, 0.002, 0.005, 0.004, 0.007, 0.002, 0.002, 0.012, 0.012, 0.006, 0.009, 0.002, 0.021, 0.005, 0.003, 0.003, 0.003, 0.034, 0.007, 0.002, 0.002, 0.002, 0.0001, 0.005, 0.007, 0.019, 0.009, 0.005, 0.003, 0.004, 0.012, 0.0001, 0.0001, 0.029, 0.098, 0.021, 0.025, 0.002, 0.002, 0.002, 0.005, 0.001, 0.003, 0.0001, 0.0001, 0.01, 0.004, 0.009, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.053, 0.0001, 0.0001, 0.016, 0.016, 0.0001, 0.01, 0.0001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ss": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.873, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.454, 0.015, 0.301, 0.001, 0.003, 0.01, 0.003, 0.035, 0.203, 0.202, 0.001, 0.0001, 0.685, 0.328, 0.962, 0.019, 0.22, 0.221, 0.137, 0.048, 0.066, 0.07, 0.054, 0.061, 0.082, 0.144, 0.105, 0.052, 0.007, 0.003, 0.008, 0.003, 0.0001, 0.231, 0.18, 0.097, 0.094, 0.111, 0.055, 0.072, 0.058, 0.259, 0.082, 0.196, 0.342, 0.348, 0.356, 0.028, 0.088, 0.003, 0.097, 0.319, 0.164, 0.113, 0.024, 0.061, 0.025, 0.043, 0.044, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 10.793, 2.656, 0.706, 1.31, 8.505, 1.004, 2.081, 2.919, 7.091, 0.258, 4.271, 5.701, 2.568, 6.606, 3.595, 0.825, 0.028, 0.782, 3.437, 3.569, 4.546, 0.696, 2.323, 0.017, 1.567, 0.734, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.037, 0.016, 0.007, 0.01, 0.014, 0.008, 0.007, 0.004, 0.009, 0.007, 0.013, 0.004, 0.003, 0.014, 0.015, 0.004, 0.003, 0.006, 0.003, 0.008, 0.006, 0.002, 0.007, 0.004, 0.002, 0.004, 0.007, 0.002, 0.01, 0.003, 0.007, 0.003, 0.09, 0.039, 0.013, 0.006, 0.01, 0.005, 0.005, 0.023, 0.007, 0.024, 0.007, 0.009, 0.005, 0.109, 0.006, 0.007, 0.018, 0.014, 0.009, 0.035, 0.024, 0.01, 0.007, 0.005, 0.015, 0.006, 0.031, 0.01, 0.005, 0.01, 0.008, 0.005, 0.0001, 0.0001, 0.085, 0.273, 0.013, 0.008, 0.0001, 0.0001, 0.0001, 0.005, 0.001, 0.002, 0.002, 0.0001, 0.003, 0.002, 0.061, 0.022, 0.001, 0.0001, 0.0001, 0.003, 0.002, 0.003, 0.059, 0.053, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.042, 0.021, 0.034, 0.0001, 0.001, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.003, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "st": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.411, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.42, 0.002, 0.079, 0.0001, 0.001, 0.016, 0.003, 0.083, 0.165, 0.167, 0.001, 0.001, 0.789, 0.143, 0.973, 0.021, 0.355, 0.325, 0.221, 0.104, 0.116, 0.113, 0.108, 0.098, 0.108, 0.15, 0.061, 0.016, 0.007, 0.005, 0.006, 0.001, 0.0001, 0.408, 0.587, 0.149, 0.148, 0.115, 0.088, 0.067, 0.172, 0.071, 0.055, 0.339, 0.212, 0.509, 0.175, 0.046, 0.141, 0.01, 0.115, 0.317, 0.165, 0.126, 0.071, 0.047, 0.0001, 0.019, 0.026, 0.011, 0.0001, 0.01, 0.0001, 0.005, 0.0001, 12.26, 2.144, 0.403, 1.165, 9.234, 0.827, 1.837, 3.801, 3.704, 0.349, 2.878, 4.66, 2.188, 4.177, 7.024, 1.54, 0.085, 2.344, 4.067, 4.22, 1.114, 0.282, 1.372, 0.049, 0.996, 0.173, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.013, 0.01, 0.009, 0.0001, 0.005, 0.007, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.013, 0.003, 0.001, 0.009, 0.001, 0.001, 0.004, 0.005, 0.0001, 0.0001, 0.002, 0.001, 0.01, 0.006, 0.004, 0.004, 0.003, 0.0001, 0.0001, 0.049, 0.052, 0.003, 0.003, 0.006, 0.002, 0.001, 0.006, 0.002, 0.022, 0.037, 0.001, 0.003, 0.01, 0.0001, 0.001, 0.004, 0.002, 0.001, 0.03, 0.056, 0.001, 0.001, 0.001, 0.004, 0.001, 0.002, 0.007, 0.001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.046, 0.167, 0.019, 0.086, 0.0001, 0.003, 0.001, 0.01, 0.001, 0.003, 0.0001, 0.001, 0.0001, 0.0001, 0.01, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.008, 0.013, 0.0001, 0.001, 0.004, 0.002, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "stq": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.516, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.229, 0.003, 0.416, 0.007, 0.001, 0.015, 0.001, 0.047, 0.208, 0.207, 0.008, 0.003, 0.814, 0.425, 1.065, 0.021, 0.376, 0.623, 0.234, 0.148, 0.183, 0.183, 0.241, 0.167, 0.231, 0.214, 0.089, 0.019, 0.072, 0.007, 0.069, 0.006, 0.0001, 0.293, 0.408, 0.089, 0.454, 0.155, 0.334, 0.214, 0.273, 0.205, 0.248, 0.241, 0.264, 0.372, 0.199, 0.14, 0.214, 0.005, 0.245, 0.798, 0.226, 0.158, 0.049, 0.246, 0.003, 0.006, 0.016, 0.02, 0.0001, 0.02, 0.0001, 0.001, 0.0001, 3.929, 0.935, 0.799, 3.858, 10.176, 1.298, 1.131, 1.308, 4.615, 0.883, 2.156, 2.674, 1.358, 6.685, 4.841, 0.816, 0.012, 4.246, 3.53, 4.621, 4.666, 0.159, 1.055, 0.042, 0.141, 0.124, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.049, 0.004, 0.003, 0.001, 0.07, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.004, 0.002, 0.001, 0.003, 0.001, 0.009, 0.014, 0.001, 0.002, 0.008, 0.004, 0.005, 0.004, 0.021, 0.009, 0.015, 0.001, 2.394, 0.001, 0.001, 0.002, 0.004, 0.014, 0.003, 0.002, 0.001, 0.007, 0.002, 0.002, 0.004, 0.002, 0.026, 0.006, 0.003, 0.001, 0.134, 0.001, 0.003, 0.002, 0.004, 0.004, 0.245, 0.003, 0.002, 0.003, 0.0001, 0.0001, 0.038, 2.918, 0.006, 0.011, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.002, 0.001, 0.0001, 0.013, 0.006, 0.008, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.048, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "su": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.293, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.195, 0.001, 0.272, 0.0001, 0.001, 0.006, 0.001, 0.02, 0.129, 0.129, 0.0001, 0.002, 1.05, 0.168, 1.046, 0.037, 0.48, 0.412, 0.411, 0.202, 0.173, 0.175, 0.161, 0.145, 0.144, 0.197, 0.036, 0.015, 0.003, 0.003, 0.003, 0.001, 0.0001, 0.394, 0.22, 0.151, 0.149, 0.042, 0.047, 0.094, 0.073, 0.227, 0.16, 0.402, 0.071, 0.278, 0.12, 0.097, 0.305, 0.014, 0.09, 0.368, 0.175, 0.05, 0.031, 0.057, 0.016, 0.027, 0.009, 0.008, 0.0001, 0.008, 0.0001, 0.005, 0.0001, 13.373, 1.612, 0.819, 2.725, 4.093, 0.314, 2.685, 1.583, 5.788, 0.997, 2.729, 2.341, 2.09, 7.706, 2.801, 1.889, 0.016, 3.889, 3.272, 4.14, 4.781, 0.134, 0.635, 0.029, 0.708, 0.032, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.025, 0.005, 0.003, 0.004, 0.006, 0.004, 0.004, 0.002, 0.004, 0.073, 0.003, 0.001, 0.001, 0.004, 0.007, 0.003, 0.003, 0.002, 0.003, 0.007, 0.008, 0.001, 0.001, 0.001, 0.001, 0.004, 0.001, 0.001, 0.004, 0.004, 0.001, 0.001, 0.047, 0.002, 0.001, 0.002, 0.004, 0.002, 0.002, 0.006, 0.003, 2.276, 0.003, 0.002, 0.001, 0.002, 0.007, 0.002, 0.004, 0.005, 0.002, 0.002, 0.001, 0.001, 0.002, 0.001, 0.002, 0.003, 0.002, 0.001, 0.002, 0.033, 0.001, 0.033, 0.0001, 0.0001, 0.051, 2.355, 0.003, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.02, 0.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.007, 0.025, 0.004, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.032, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "sw": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.454, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.93, 0.002, 0.217, 0.002, 0.001, 0.01, 0.003, 0.027, 0.171, 0.171, 0.001, 0.001, 0.703, 0.109, 0.942, 0.015, 0.41, 0.383, 0.266, 0.126, 0.108, 0.126, 0.108, 0.107, 0.119, 0.201, 0.062, 0.024, 0.003, 0.004, 0.003, 0.003, 0.0001, 0.226, 0.167, 0.122, 0.086, 0.058, 0.057, 0.065, 0.116, 0.13, 0.09, 0.638, 0.08, 0.504, 0.137, 0.044, 0.113, 0.006, 0.074, 0.173, 0.147, 0.165, 0.059, 0.218, 0.013, 0.04, 0.023, 0.04, 0.0001, 0.04, 0.001, 0.001, 0.001, 16.478, 1.326, 0.611, 1.343, 3.374, 0.678, 1.131, 2.383, 9.629, 0.827, 4.598, 2.609, 3.253, 5.284, 3.187, 0.805, 0.008, 1.616, 2.094, 2.468, 4.443, 0.427, 3.161, 0.026, 2.095, 1.273, 0.001, 0.006, 0.001, 0.0001, 0.0001, 0.04, 0.005, 0.004, 0.002, 0.004, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.013, 0.002, 0.001, 0.001, 0.001, 0.002, 0.006, 0.001, 0.001, 0.009, 0.008, 0.001, 0.004, 0.009, 0.003, 0.002, 0.002, 0.003, 0.001, 0.001, 0.005, 0.003, 0.009, 0.001, 0.002, 0.001, 0.002, 0.001, 0.002, 0.005, 0.009, 0.009, 0.004, 0.002, 0.003, 0.004, 0.001, 0.004, 0.003, 0.003, 0.003, 0.006, 0.003, 0.002, 0.003, 0.0001, 0.0001, 0.018, 0.029, 0.009, 0.005, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.014, 0.007, 0.011, 0.004, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.005, 0.012, 0.01, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.038, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "szl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.884, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.63, 0.002, 0.452, 0.0001, 0.0001, 0.012, 0.001, 0.026, 0.296, 0.296, 0.001, 0.001, 1.094, 0.318, 1.181, 0.015, 0.332, 0.469, 0.289, 0.138, 0.131, 0.151, 0.118, 0.131, 0.157, 0.273, 0.087, 0.014, 0.006, 0.003, 0.006, 0.0001, 0.0001, 0.207, 0.209, 0.155, 0.118, 0.048, 0.111, 0.139, 0.08, 0.122, 0.125, 0.213, 0.123, 0.287, 0.122, 0.062, 0.309, 0.005, 0.156, 0.329, 0.126, 0.154, 0.05, 0.233, 0.034, 0.017, 0.083, 0.004, 0.0001, 0.004, 0.0001, 0.006, 0.001, 5.741, 0.894, 2.016, 2.128, 5.35, 0.327, 1.279, 0.968, 3.438, 2.841, 2.633, 2.099, 2.293, 3.364, 5.857, 1.423, 0.012, 3.389, 2.85, 2.58, 2.277, 0.102, 3.144, 0.017, 3.623, 2.205, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.191, 0.035, 0.624, 0.044, 0.945, 0.014, 0.009, 0.333, 0.008, 0.003, 0.006, 0.005, 0.012, 0.221, 0.005, 0.196, 0.006, 0.005, 0.003, 0.168, 0.01, 0.003, 0.005, 0.005, 0.005, 0.109, 0.059, 0.562, 0.005, 0.005, 0.004, 0.006, 0.062, 0.111, 0.006, 0.016, 0.01, 0.004, 0.004, 0.012, 0.011, 0.03, 0.005, 0.012, 0.003, 0.012, 0.008, 1.67, 0.032, 0.015, 0.058, 0.035, 0.048, 0.018, 0.012, 0.004, 0.02, 0.013, 0.335, 0.026, 0.282, 0.022, 0.098, 0.006, 0.0001, 0.0001, 0.109, 0.208, 0.455, 5.073, 0.0001, 0.001, 0.0001, 0.008, 0.003, 0.003, 0.004, 0.0001, 0.015, 0.008, 0.161, 0.06, 0.003, 0.002, 0.0001, 0.003, 0.001, 0.009, 0.025, 0.019, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.011, 0.01, 0.176, 0.006, 0.001, 0.005, 0.003, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ta": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.357, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.862, 0.001, 0.077, 0.0001, 0.001, 0.006, 0.001, 0.007, 0.055, 0.056, 0.0001, 0.001, 0.234, 0.03, 0.384, 0.005, 0.084, 0.106, 0.063, 0.029, 0.028, 0.034, 0.027, 0.032, 0.031, 0.052, 0.017, 0.006, 0.002, 0.002, 0.002, 0.001, 0.0001, 0.008, 0.004, 0.008, 0.004, 0.004, 0.003, 0.005, 0.004, 0.006, 0.002, 0.003, 0.003, 0.005, 0.004, 0.003, 0.008, 0.0001, 0.004, 0.008, 0.005, 0.002, 0.002, 0.002, 0.001, 0.001, 0.0001, 0.006, 0.0001, 0.006, 0.0001, 0.002, 0.0001, 0.062, 0.006, 0.017, 0.014, 0.042, 0.007, 0.009, 0.018, 0.038, 0.001, 0.006, 0.024, 0.018, 0.035, 0.032, 0.011, 0.001, 0.036, 0.022, 0.032, 0.017, 0.005, 0.004, 0.002, 0.01, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.122, 2.149, 0.144, 0.01, 0.0001, 0.297, 0.436, 0.597, 0.764, 0.136, 0.24, 0.226, 0.005, 5.298, 0.158, 0.027, 0.013, 0.0001, 0.078, 0.014, 0.0001, 2.36, 0.0001, 0.0001, 0.001, 0.171, 0.627, 0.0001, 0.037, 0.002, 0.021, 1.319, 0.014, 0.0001, 0.001, 0.32, 2.012, 0.001, 0.001, 0.0001, 0.539, 0.989, 1.521, 0.0001, 0.0001, 0.001, 23.215, 10.185, 1.322, 0.801, 1.028, 0.757, 0.189, 0.942, 0.0001, 0.015, 0.06, 0.015, 0.0001, 0.0001, 0.0001, 0.0001, 1.18, 2.177, 0.0001, 0.0001, 0.016, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 31.245, 0.0001, 0.013, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tcy": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.391, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.751, 0.001, 0.026, 0.0001, 0.0001, 0.002, 0.0001, 0.028, 0.048, 0.047, 0.0001, 0.001, 0.244, 0.028, 0.533, 0.012, 0.014, 0.02, 0.01, 0.005, 0.005, 0.007, 0.006, 0.004, 0.008, 0.009, 0.009, 0.003, 0.002, 0.003, 0.002, 0.002, 0.0001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.003, 0.0001, 0.001, 0.001, 0.02, 0.002, 0.008, 0.006, 0.018, 0.002, 0.005, 0.006, 0.017, 0.0001, 0.003, 0.009, 0.008, 0.014, 0.015, 0.008, 0.0001, 0.013, 0.012, 0.015, 0.006, 0.002, 0.005, 0.0001, 0.003, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.354, 1.789, 1.221, 0.031, 0.0001, 0.268, 1.686, 0.484, 0.152, 0.21, 0.745, 0.196, 0.087, 4.125, 0.064, 0.014, 0.014, 0.0001, 0.109, 0.011, 0.001, 1.28, 0.033, 0.613, 0.012, 0.007, 0.23, 0.003, 0.404, 0.002, 0.011, 0.433, 0.058, 1.007, 0.002, 0.198, 1.312, 0.064, 1.397, 0.124, 1.439, 0.012, 1.248, 0.035, 0.624, 0.105, 0.769, 0.62, 1.755, 0.0001, 22.872, 9.408, 0.0001, 0.629, 0.164, 0.121, 0.665, 0.124, 0.0001, 0.0001, 0.003, 0.0001, 1.377, 1.63, 0.0001, 0.0001, 0.05, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.955, 0.0001, 0.194, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "te": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.34, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.746, 0.003, 0.051, 0.0001, 0.001, 0.003, 0.002, 0.007, 0.042, 0.043, 0.0001, 0.001, 0.336, 0.028, 0.611, 0.018, 0.129, 0.152, 0.069, 0.038, 0.034, 0.073, 0.03, 0.032, 0.034, 0.047, 0.02, 0.007, 0.002, 0.004, 0.002, 0.002, 0.0001, 0.008, 0.004, 0.006, 0.005, 0.003, 0.003, 0.002, 0.002, 0.006, 0.001, 0.002, 0.003, 0.005, 0.003, 0.002, 0.005, 0.0001, 0.003, 0.008, 0.005, 0.003, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.006, 0.0001, 0.007, 0.0001, 0.005, 0.0001, 0.053, 0.008, 0.019, 0.022, 0.056, 0.009, 0.01, 0.021, 0.046, 0.001, 0.004, 0.022, 0.015, 0.038, 0.038, 0.014, 0.0001, 0.036, 0.036, 0.045, 0.017, 0.006, 0.006, 0.002, 0.007, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.485, 1.801, 1.898, 0.051, 0.0001, 0.236, 0.427, 0.575, 0.238, 0.222, 0.152, 0.685, 0.105, 2.799, 0.055, 0.027, 0.006, 0.0001, 0.047, 0.007, 0.005, 1.329, 0.049, 0.668, 0.014, 0.002, 0.428, 0.004, 0.25, 0.001, 0.004, 0.537, 0.039, 0.598, 0.002, 0.137, 0.864, 0.099, 0.843, 0.149, 1.628, 0.0001, 0.909, 0.085, 0.267, 0.128, 0.942, 0.804, 25.531, 7.165, 1.487, 0.074, 0.0001, 0.877, 0.211, 0.153, 0.855, 0.145, 0.0001, 0.001, 0.0001, 0.0001, 2.169, 2.359, 0.0001, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 30.736, 0.0001, 0.069, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tet": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.506, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.056, 0.014, 0.345, 0.0001, 0.004, 0.018, 0.001, 0.455, 0.383, 0.382, 0.001, 0.004, 1.067, 0.53, 0.968, 0.029, 0.443, 0.39, 0.316, 0.132, 0.112, 0.137, 0.105, 0.106, 0.119, 0.181, 0.186, 0.018, 0.015, 0.005, 0.015, 0.003, 0.0001, 0.338, 0.226, 0.145, 0.169, 0.132, 0.156, 0.098, 0.111, 0.215, 0.061, 0.136, 0.43, 0.301, 0.181, 0.101, 0.266, 0.01, 0.137, 0.345, 0.37, 0.107, 0.065, 0.041, 0.021, 0.008, 0.014, 0.01, 0.0001, 0.01, 0.0001, 0.0001, 0.0001, 11.569, 1.502, 0.408, 2.068, 6.067, 0.587, 0.66, 2.225, 7.509, 0.16, 2.246, 2.814, 2.311, 6.307, 4.401, 1.282, 0.035, 4.022, 4.063, 3.545, 4.826, 0.518, 0.1, 0.064, 0.126, 0.341, 0.0001, 0.009, 0.0001, 0.0001, 0.0001, 0.318, 0.081, 0.003, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.015, 0.001, 0.0001, 0.0001, 0.001, 0.004, 0.275, 0.001, 0.0001, 0.014, 0.013, 0.001, 0.002, 0.021, 0.254, 0.002, 0.025, 0.0001, 0.0001, 0.003, 0.02, 0.002, 0.389, 0.006, 0.001, 0.001, 0.167, 0.001, 0.001, 0.002, 0.048, 0.071, 0.284, 0.01, 0.003, 0.001, 0.0001, 0.001, 0.001, 0.076, 0.003, 0.014, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.1, 1.362, 0.004, 0.006, 0.0001, 0.0001, 0.0001, 0.009, 0.011, 0.0001, 0.0001, 0.0001, 0.007, 0.003, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.316, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tg": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.272, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.893, 0.001, 0.026, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.324, 0.326, 0.0001, 0.001, 0.765, 0.105, 0.581, 0.006, 0.139, 0.257, 0.13, 0.073, 0.063, 0.072, 0.065, 0.068, 0.082, 0.185, 0.026, 0.048, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.026, 0.01, 0.018, 0.007, 0.005, 0.01, 0.006, 0.007, 0.018, 0.002, 0.005, 0.008, 0.009, 0.006, 0.004, 0.009, 0.001, 0.007, 0.015, 0.007, 0.003, 0.006, 0.004, 0.006, 0.002, 0.002, 0.004, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.081, 0.01, 0.03, 0.023, 0.086, 0.012, 0.015, 0.021, 0.065, 0.002, 0.009, 0.037, 0.017, 0.055, 0.061, 0.017, 0.001, 0.07, 0.039, 0.054, 0.023, 0.01, 0.007, 0.003, 0.013, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.968, 1.483, 1.764, 1.455, 0.398, 0.384, 0.008, 0.116, 0.704, 0.002, 0.17, 0.01, 0.024, 0.035, 0.045, 0.663, 0.178, 0.263, 0.119, 0.126, 0.303, 0.007, 0.009, 0.022, 0.136, 0.003, 0.143, 0.343, 0.148, 0.063, 0.071, 0.071, 0.134, 0.159, 0.101, 0.347, 0.121, 0.05, 0.002, 0.026, 0.059, 0.003, 0.003, 0.057, 0.003, 0.035, 0.012, 0.164, 5.899, 1.075, 1.071, 1.816, 2.336, 1.339, 0.082, 0.882, 4.885, 0.258, 1.014, 1.438, 1.445, 2.22, 3.885, 0.208, 0.0001, 0.0001, 0.132, 0.006, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.001, 30.166, 10.131, 1.965, 0.481, 0.0001, 0.0001, 0.0001, 0.0001, 0.024, 0.016, 0.001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.209, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ti": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.164, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.862, 0.026, 0.05, 0.0001, 0.0001, 0.012, 0.0001, 0.044, 0.1, 0.1, 0.0001, 0.0001, 0.075, 0.114, 0.14, 0.02, 0.098, 0.121, 0.073, 0.033, 0.026, 0.04, 0.027, 0.03, 0.029, 0.042, 0.024, 0.004, 0.001, 0.013, 0.001, 0.007, 0.0001, 0.018, 0.013, 0.015, 0.007, 0.006, 0.007, 0.011, 0.013, 0.022, 0.004, 0.004, 0.024, 0.018, 0.012, 0.005, 0.015, 0.004, 0.01, 0.013, 0.022, 0.007, 0.009, 0.006, 0.002, 0.004, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.329, 0.063, 0.099, 0.16, 0.451, 0.14, 0.111, 0.211, 0.297, 0.027, 0.053, 0.155, 0.097, 0.283, 0.275, 0.071, 0.007, 0.228, 0.261, 0.255, 0.122, 0.059, 0.08, 0.007, 0.069, 0.014, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.358, 0.069, 0.074, 0.236, 0.007, 0.331, 0.023, 0.001, 9.303, 5.576, 6.47, 5.805, 1.549, 3.066, 0.251, 0.003, 0.505, 0.172, 0.135, 1.034, 0.015, 2.293, 0.054, 0.001, 0.75, 0.233, 0.32, 0.51, 0.12, 1.725, 0.08, 0.002, 0.83, 0.546, 0.753, 1.425, 0.111, 2.053, 0.138, 0.011, 0.764, 0.373, 0.244, 0.731, 0.034, 1.854, 0.258, 0.004, 1.053, 0.166, 0.551, 0.69, 0.031, 2.007, 0.179, 0.005, 0.189, 0.048, 0.045, 0.156, 0.011, 0.447, 0.067, 0.002, 0.0001, 0.0001, 0.386, 0.04, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.027, 0.012, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.008, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 27.967, 0.209, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tk": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.842, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.847, 0.005, 0.052, 0.0001, 0.001, 0.008, 0.001, 0.006, 0.121, 0.125, 0.004, 0.002, 0.691, 0.455, 1.024, 0.011, 0.191, 0.306, 0.153, 0.096, 0.091, 0.095, 0.077, 0.079, 0.095, 0.155, 0.055, 0.012, 0.028, 0.003, 0.028, 0.005, 0.0001, 0.227, 0.204, 0.012, 0.086, 0.083, 0.04, 0.177, 0.112, 0.174, 0.027, 0.109, 0.037, 0.173, 0.054, 0.141, 0.071, 0.001, 0.074, 0.173, 0.153, 0.029, 0.028, 0.04, 0.045, 0.029, 0.016, 0.01, 0.0001, 0.01, 0.001, 0.003, 0.0001, 8.711, 1.574, 0.069, 3.499, 5.666, 0.119, 2.22, 0.895, 5.266, 0.476, 2.165, 5.087, 2.1, 4.83, 1.754, 1.161, 0.002, 5.326, 1.953, 2.216, 1.612, 0.014, 0.863, 0.003, 4.905, 0.889, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.208, 0.022, 0.019, 0.011, 0.017, 0.007, 0.003, 0.027, 1.247, 0.001, 0.0001, 0.008, 0.005, 0.003, 0.002, 0.006, 0.003, 0.005, 0.002, 0.04, 0.02, 0.001, 0.017, 0.002, 0.001, 0.002, 0.001, 0.001, 0.068, 0.139, 0.083, 1.114, 0.015, 0.004, 0.009, 0.002, 0.694, 0.003, 0.003, 0.67, 0.001, 0.002, 0.0001, 0.027, 0.0001, 0.192, 0.001, 0.002, 0.056, 0.114, 0.02, 0.061, 0.013, 0.043, 0.813, 0.006, 0.038, 0.007, 0.016, 0.096, 0.984, 2.385, 0.053, 0.019, 0.0001, 0.0001, 0.268, 5.753, 0.012, 2.464, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.324, 0.111, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.054, 0.182, 0.0001, 0.005, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tl": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.527, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.015, 0.006, 0.416, 0.001, 0.001, 0.006, 0.002, 0.043, 0.2, 0.202, 0.001, 0.002, 0.702, 0.264, 0.789, 0.017, 0.219, 0.272, 0.17, 0.08, 0.075, 0.082, 0.072, 0.075, 0.087, 0.155, 0.061, 0.022, 0.066, 0.004, 0.066, 0.002, 0.0001, 0.555, 0.199, 0.186, 0.134, 0.118, 0.059, 0.112, 0.181, 0.214, 0.066, 0.204, 0.127, 0.268, 0.176, 0.063, 0.292, 0.011, 0.11, 0.398, 0.188, 0.06, 0.045, 0.055, 0.008, 0.035, 0.014, 0.016, 0.0001, 0.015, 0.001, 0.003, 0.0001, 16.44, 1.457, 0.382, 1.246, 2.379, 0.123, 6.741, 1.192, 6.121, 0.033, 2.118, 3.173, 2.569, 9.845, 3.868, 2.142, 0.019, 2.313, 4.125, 3.402, 2.226, 0.121, 0.559, 0.032, 2.131, 0.078, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.038, 0.008, 0.005, 0.004, 0.004, 0.003, 0.002, 0.002, 0.004, 0.002, 0.002, 0.002, 0.003, 0.007, 0.003, 0.002, 0.004, 0.004, 0.002, 0.014, 0.006, 0.001, 0.002, 0.001, 0.002, 0.008, 0.001, 0.002, 0.013, 0.007, 0.002, 0.002, 0.028, 0.01, 0.003, 0.002, 0.004, 0.002, 0.002, 0.004, 0.003, 0.01, 0.002, 0.004, 0.002, 0.008, 0.002, 0.002, 0.005, 0.01, 0.003, 0.007, 0.003, 0.003, 0.002, 0.002, 0.006, 0.003, 0.004, 0.003, 0.005, 0.003, 0.003, 0.003, 0.0001, 0.0001, 0.029, 0.045, 0.007, 0.011, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.012, 0.006, 0.01, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.008, 0.007, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 0.012, 0.037, 0.005, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.004, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tn": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.716, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 17.981, 0.003, 0.08, 0.013, 0.001, 0.009, 0.002, 0.01, 0.075, 0.075, 0.0001, 0.0001, 0.66, 0.106, 0.757, 0.034, 0.2, 0.226, 0.113, 0.036, 0.039, 0.039, 0.04, 0.035, 0.043, 0.09, 0.021, 0.015, 0.01, 0.005, 0.011, 0.004, 0.0001, 0.148, 0.357, 0.071, 0.097, 0.07, 0.054, 0.125, 0.028, 0.051, 0.019, 0.166, 0.104, 0.374, 0.087, 0.085, 0.102, 0.001, 0.088, 0.173, 0.113, 0.019, 0.017, 0.023, 0.006, 0.007, 0.021, 0.023, 0.0001, 0.022, 0.0001, 0.004, 0.0001, 12.488, 2.445, 0.191, 1.643, 9.389, 0.795, 4.171, 1.899, 3.702, 0.312, 2.67, 5.097, 2.631, 4.499, 8.158, 1.075, 0.008, 1.917, 4.118, 4.684, 0.837, 0.048, 2.161, 0.014, 0.955, 0.029, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.0001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.034, 0.011, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.036, 0.008, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "to": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.293, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.821, 0.001, 0.44, 0.0001, 0.0001, 0.001, 0.005, 0.111, 0.238, 0.237, 0.002, 0.0001, 0.847, 0.076, 1.066, 0.045, 0.084, 0.141, 0.063, 0.039, 0.037, 0.032, 0.036, 0.05, 0.065, 0.067, 0.09, 0.023, 0.003, 0.011, 0.005, 0.027, 0.0001, 0.126, 0.034, 0.039, 0.011, 0.049, 0.193, 0.01, 0.178, 0.123, 0.01, 0.599, 0.145, 0.204, 0.188, 0.245, 0.136, 0.001, 0.012, 0.185, 0.547, 0.059, 0.124, 0.026, 0.001, 0.005, 0.001, 0.004, 0.0001, 0.005, 0.0001, 0.002, 0.001, 10.579, 0.223, 0.423, 0.627, 6.707, 1.724, 1.525, 3.199, 6.545, 0.014, 3.573, 2.547, 1.814, 3.859, 6.712, 1.277, 0.01, 0.909, 1.504, 3.555, 4.441, 0.529, 0.312, 0.02, 0.255, 0.009, 0.0001, 0.0001, 0.0001, 0.004, 0.0001, 0.028, 0.432, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.082, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.183, 0.003, 0.0001, 0.0001, 0.001, 0.011, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.057, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.002, 0.001, 0.078, 0.0001, 0.015, 0.0001, 0.0001, 0.013, 0.0001, 0.001, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 4.517, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.022, 0.094, 0.659, 0.119, 0.0001, 0.0001, 0.0001, 0.0001, 4.513, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.024, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tpi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.506, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.422, 0.004, 0.225, 0.0001, 0.0001, 0.006, 0.0001, 0.033, 0.226, 0.227, 0.001, 0.0001, 0.976, 0.07, 1.357, 0.011, 0.339, 0.409, 0.202, 0.102, 0.113, 0.106, 0.09, 0.101, 0.134, 0.258, 0.112, 0.01, 0.016, 0.001, 0.016, 0.001, 0.0001, 0.28, 0.281, 0.358, 0.108, 0.184, 0.096, 0.132, 0.102, 0.251, 0.103, 0.247, 0.515, 0.27, 0.273, 0.17, 0.405, 0.016, 0.129, 0.696, 0.311, 0.02, 0.133, 0.076, 0.006, 0.097, 0.011, 0.006, 0.0001, 0.006, 0.0001, 0.003, 0.0001, 9.267, 1.534, 0.295, 1.028, 5.418, 0.186, 3.091, 0.44, 8.286, 0.1, 1.968, 5.697, 3.075, 7.815, 5.428, 2.623, 0.013, 2.618, 3.22, 3.51, 1.911, 0.537, 0.798, 0.013, 0.388, 0.104, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.026, 0.016, 0.007, 0.003, 0.007, 0.001, 0.002, 0.003, 0.001, 0.001, 0.001, 0.002, 0.006, 0.002, 0.001, 0.001, 0.004, 0.002, 0.001, 0.01, 0.002, 0.002, 0.002, 0.003, 0.001, 0.004, 0.001, 0.005, 0.009, 0.009, 0.003, 0.002, 0.021, 0.037, 0.001, 0.006, 0.0001, 0.001, 0.001, 0.002, 0.002, 0.013, 0.005, 0.003, 0.004, 0.024, 0.002, 0.002, 0.006, 0.026, 0.007, 0.298, 0.002, 0.005, 0.003, 0.003, 0.01, 0.004, 0.011, 0.015, 0.005, 0.005, 0.003, 0.004, 0.0001, 0.0001, 0.019, 0.408, 0.007, 0.009, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.02, 0.011, 0.021, 0.008, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.012, 0.021, 0.009, 0.003, 0.009, 0.003, 0.001, 0.001, 0.002, 0.004, 0.003, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ts": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.117, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.445, 0.004, 0.183, 0.0001, 0.0001, 0.006, 0.001, 0.136, 0.107, 0.107, 0.0001, 0.0001, 0.868, 0.158, 0.838, 0.021, 0.152, 0.161, 0.081, 0.037, 0.038, 0.052, 0.045, 0.043, 0.056, 0.092, 0.041, 0.025, 0.03, 0.001, 0.03, 0.006, 0.0001, 0.18, 0.088, 0.068, 0.084, 0.075, 0.029, 0.061, 0.137, 0.055, 0.032, 0.132, 0.116, 0.387, 0.232, 0.02, 0.062, 0.002, 0.075, 0.171, 0.121, 0.04, 0.219, 0.021, 0.119, 0.045, 0.021, 0.003, 0.0001, 0.003, 0.0001, 0.002, 0.005, 13.463, 1.384, 0.275, 1.092, 4.958, 0.572, 1.347, 3.614, 7.958, 0.047, 4.285, 4.291, 2.768, 5.921, 3.615, 0.489, 0.025, 2.056, 2.585, 2.874, 4.929, 1.994, 3.082, 0.68, 2.172, 0.64, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.055, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.0001, 0.005, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.031, 0.0001, 0.001, 0.008, 0.008, 0.0001, 0.0001, 0.05, 0.004, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.001, 0.003, 0.0001, 0.002, 0.001, 0.005, 0.002, 0.011, 0.002, 0.0001, 0.0001, 0.001, 0.002, 0.002, 0.001, 0.002, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.0001, 0.051, 0.023, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.018, 0.006, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.054, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tt": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.086, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.219, 0.001, 0.085, 0.0001, 0.0001, 0.04, 0.0001, 0.002, 0.22, 0.221, 0.0001, 0.008, 0.529, 0.164, 0.713, 0.007, 0.223, 0.276, 0.185, 0.093, 0.09, 0.084, 0.067, 0.069, 0.089, 0.159, 0.097, 0.008, 0.002, 0.001, 0.002, 0.003, 0.0001, 0.01, 0.009, 0.017, 0.009, 0.006, 0.003, 0.002, 0.003, 0.017, 0.001, 0.009, 0.003, 0.013, 0.003, 0.003, 0.004, 0.005, 0.005, 0.013, 0.017, 0.009, 0.006, 0.002, 0.01, 0.003, 0.001, 0.002, 0.0001, 0.002, 0.0001, 0.002, 0.0001, 0.245, 0.051, 0.015, 0.059, 0.152, 0.017, 0.027, 0.019, 0.108, 0.002, 0.051, 0.14, 0.059, 0.158, 0.057, 0.025, 0.035, 0.149, 0.073, 0.108, 0.056, 0.01, 0.015, 0.014, 0.048, 0.025, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.852, 1.726, 1.824, 1.398, 0.151, 0.194, 0.076, 0.605, 0.638, 0.004, 0.1, 2.623, 0.236, 0.061, 0.057, 0.479, 0.123, 0.129, 0.053, 0.062, 0.279, 0.075, 0.02, 0.174, 0.096, 1.916, 0.222, 0.025, 0.1, 0.049, 0.069, 0.128, 0.159, 0.146, 0.119, 0.43, 0.164, 0.055, 0.003, 0.065, 0.036, 0.325, 0.0001, 0.038, 0.001, 0.013, 0.042, 0.429, 4.958, 1.044, 0.394, 1.429, 0.959, 3.011, 0.048, 0.384, 1.557, 0.433, 1.901, 3.01, 1.056, 3.108, 1.043, 0.407, 0.0001, 0.0001, 0.106, 0.225, 0.139, 0.034, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.004, 0.0001, 0.003, 0.001, 26.093, 12.748, 1.127, 2.265, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.275, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tum": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.34, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.852, 0.004, 0.573, 0.003, 0.004, 0.004, 0.017, 0.083, 0.308, 0.306, 0.001, 0.0001, 1.303, 0.412, 1.2, 0.024, 0.557, 0.476, 0.366, 0.176, 0.172, 0.213, 0.206, 0.176, 0.165, 0.191, 0.118, 0.025, 0.012, 0.007, 0.012, 0.0001, 0.001, 0.268, 0.377, 0.217, 0.158, 0.11, 0.095, 0.125, 0.123, 0.134, 0.277, 0.29, 0.111, 0.727, 0.21, 0.076, 0.143, 0.01, 0.116, 0.269, 0.294, 0.069, 0.067, 0.069, 0.003, 0.068, 0.042, 0.008, 0.0001, 0.008, 0.0001, 0.0001, 0.0001, 10.116, 1.728, 1.817, 1.937, 5.125, 1.225, 1.488, 3.251, 6.548, 0.159, 2.454, 2.854, 2.514, 5.282, 4.292, 2.074, 0.028, 2.715, 2.7, 3.62, 4.127, 0.602, 1.862, 0.051, 1.299, 0.758, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.102, 0.017, 0.014, 0.014, 0.01, 0.006, 0.008, 0.005, 0.003, 0.001, 0.007, 0.006, 0.02, 0.058, 0.017, 0.003, 0.008, 0.005, 0.001, 0.016, 0.005, 0.005, 0.003, 0.004, 0.009, 0.043, 0.004, 0.001, 0.008, 0.005, 0.006, 0.002, 0.103, 0.006, 0.008, 0.007, 0.001, 0.005, 0.009, 0.025, 0.006, 0.01, 0.003, 0.011, 0.006, 0.004, 0.0001, 0.003, 0.016, 0.015, 0.003, 0.014, 0.008, 0.112, 0.003, 0.014, 0.012, 0.008, 0.012, 0.012, 0.008, 0.009, 0.01, 0.003, 0.0001, 0.0001, 0.101, 0.045, 0.006, 0.195, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.003, 0.063, 0.038, 0.001, 0.001, 0.001, 0.006, 0.003, 0.007, 0.053, 0.034, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.016, 0.022, 0.093, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.012, 0.008, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tw": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.984, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.303, 0.001, 0.389, 0.0001, 0.001, 0.0001, 0.004, 0.077, 0.488, 0.486, 0.0001, 0.0001, 0.756, 0.118, 1.791, 0.025, 0.73, 0.614, 0.579, 0.248, 0.221, 0.18, 0.206, 0.176, 0.192, 0.286, 0.065, 0.035, 0.004, 0.0001, 0.004, 0.01, 0.0001, 0.602, 0.283, 0.296, 0.116, 0.311, 0.173, 0.2, 0.1, 0.303, 0.048, 0.367, 0.187, 0.399, 0.306, 0.149, 0.189, 0.019, 0.18, 0.508, 0.305, 0.203, 0.099, 0.096, 0.049, 0.077, 0.01, 0.003, 0.0001, 0.019, 0.0001, 0.0001, 0.0001, 8.315, 0.995, 0.605, 1.602, 5.365, 0.628, 0.659, 0.955, 4.58, 0.091, 2.249, 1.426, 1.892, 5.378, 5.608, 0.884, 0.03, 3.156, 2.583, 1.888, 2.004, 0.328, 1.708, 0.075, 2.441, 0.168, 0.0001, 0.0001, 0.0001, 0.01, 0.0001, 0.083, 0.035, 0.035, 0.017, 0.032, 0.015, 0.093, 0.059, 0.023, 0.016, 0.025, 0.022, 0.019, 0.022, 0.029, 0.012, 0.046, 0.013, 0.009, 0.017, 0.855, 0.004, 0.017, 0.017, 0.006, 0.004, 0.012, 1.236, 0.017, 0.012, 0.01, 0.004, 0.081, 0.046, 0.012, 0.012, 0.086, 0.028, 0.017, 0.054, 0.03, 0.075, 0.019, 0.012, 0.016, 0.036, 0.009, 0.019, 0.074, 0.048, 0.057, 0.049, 0.013, 2.039, 0.016, 0.03, 0.109, 0.023, 0.064, 0.039, 0.051, 0.048, 0.068, 0.015, 0.0001, 0.0001, 0.075, 0.196, 0.058, 0.036, 0.106, 0.0001, 0.001, 1.812, 0.004, 0.0001, 0.001, 0.0001, 2.053, 0.006, 0.306, 0.086, 0.0001, 0.0001, 0.0001, 0.012, 0.003, 0.267, 0.158, 0.09, 0.007, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.209, 0.016, 0.044, 0.0001, 0.016, 0.052, 0.016, 0.023, 0.012, 0.003, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.019, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ty": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 5.596, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.482, 0.002, 0.148, 0.0001, 0.0001, 0.0001, 0.001, 0.103, 0.185, 0.187, 0.0001, 0.0001, 0.459, 0.229, 1.457, 0.013, 0.217, 0.354, 0.181, 0.099, 0.109, 0.09, 0.093, 0.094, 0.097, 0.295, 0.032, 0.014, 0.002, 0.001, 0.023, 0.0001, 0.0001, 0.336, 0.259, 0.191, 0.056, 0.549, 0.206, 0.061, 0.142, 0.109, 0.062, 0.031, 0.131, 0.411, 0.099, 0.644, 0.477, 0.008, 0.194, 0.401, 0.951, 0.146, 0.18, 0.019, 0.004, 0.015, 0.007, 0.008, 0.0001, 0.01, 0.0001, 0.003, 0.0001, 9.536, 0.253, 0.42, 0.705, 6.452, 0.803, 0.335, 1.722, 7.016, 0.092, 0.277, 1.311, 1.613, 3.693, 4.012, 0.994, 0.04, 4.455, 1.038, 5.804, 2.543, 0.371, 0.019, 0.027, 0.146, 0.201, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.052, 0.908, 0.007, 0.002, 0.007, 0.001, 0.0001, 0.003, 0.006, 0.001, 0.003, 0.002, 0.002, 1.282, 0.0001, 0.001, 0.007, 0.0001, 0.043, 0.549, 0.01, 0.0001, 0.0001, 0.003, 0.114, 1.916, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.19, 0.144, 0.074, 0.002, 0.002, 0.003, 0.003, 0.022, 0.06, 0.039, 0.051, 0.598, 0.116, 0.035, 0.003, 0.018, 0.003, 0.029, 0.506, 0.059, 0.005, 0.003, 0.0001, 0.001, 0.002, 0.008, 0.013, 0.037, 0.005, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.033, 1.417, 1.711, 1.627, 0.0001, 0.0001, 0.0001, 0.008, 0.01, 0.005, 0.002, 0.001, 0.0001, 0.0001, 0.009, 0.006, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.012, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.01, 2.037, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "tyv": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.67, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.942, 0.005, 0.141, 0.0001, 0.0001, 0.004, 0.001, 0.003, 0.097, 0.1, 0.0001, 0.001, 0.649, 0.583, 0.64, 0.009, 0.087, 0.151, 0.08, 0.042, 0.04, 0.04, 0.033, 0.032, 0.035, 0.099, 0.046, 0.011, 0.008, 0.002, 0.008, 0.008, 0.0001, 0.007, 0.002, 0.003, 0.002, 0.002, 0.002, 0.001, 0.002, 0.022, 0.0001, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.001, 0.003, 0.003, 0.001, 0.006, 0.002, 0.011, 0.001, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.005, 0.0001, 0.081, 0.005, 0.006, 0.008, 0.025, 0.002, 0.005, 0.006, 0.02, 0.002, 0.007, 0.012, 0.016, 0.015, 0.021, 0.013, 0.003, 0.017, 0.01, 0.014, 0.01, 0.002, 0.004, 0.007, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.263, 0.883, 1.755, 1.893, 0.056, 0.377, 0.045, 1.004, 0.604, 0.005, 0.051, 2.643, 0.086, 0.75, 0.036, 0.173, 0.125, 0.135, 0.03, 0.065, 0.108, 0.011, 0.018, 0.005, 0.038, 0.005, 0.129, 0.036, 0.079, 0.041, 0.11, 0.022, 0.066, 0.107, 0.147, 0.782, 0.015, 0.082, 0.008, 0.088, 0.054, 0.476, 0.001, 0.089, 0.001, 0.039, 0.018, 0.892, 5.51, 0.98, 0.415, 1.888, 1.904, 2.436, 0.478, 0.679, 2.249, 0.486, 1.593, 2.459, 0.684, 3.034, 1.582, 0.744, 0.0001, 0.0001, 0.143, 0.011, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.002, 0.004, 0.003, 0.01, 0.001, 0.011, 0.002, 28.453, 13.514, 1.663, 0.515, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.001, 0.094, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "udm": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.306, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.09, 0.004, 0.114, 0.0001, 0.0001, 0.008, 0.0001, 0.002, 0.237, 0.238, 0.002, 0.001, 0.557, 0.317, 0.775, 0.018, 0.183, 0.302, 0.16, 0.086, 0.075, 0.092, 0.071, 0.074, 0.085, 0.189, 0.048, 0.012, 0.017, 0.014, 0.016, 0.001, 0.0001, 0.018, 0.008, 0.012, 0.004, 0.003, 0.003, 0.003, 0.003, 0.016, 0.004, 0.004, 0.006, 0.014, 0.003, 0.019, 0.021, 0.0001, 0.006, 0.011, 0.006, 0.003, 0.006, 0.001, 0.009, 0.001, 0.001, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.242, 0.027, 0.103, 0.053, 0.195, 0.007, 0.026, 0.039, 0.148, 0.005, 0.015, 0.074, 0.03, 0.111, 0.083, 0.028, 0.002, 0.108, 0.083, 0.059, 0.078, 0.015, 0.004, 0.004, 0.02, 0.008, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 2.622, 2.823, 2.068, 1.727, 0.105, 0.092, 0.121, 0.28, 0.404, 0.054, 0.451, 2.424, 1.272, 0.932, 0.131, 0.626, 0.166, 0.634, 0.123, 0.164, 0.252, 0.027, 0.006, 0.023, 0.083, 0.009, 0.22, 0.069, 0.124, 0.088, 0.082, 0.223, 0.15, 0.209, 0.107, 0.132, 0.033, 0.405, 0.01, 0.179, 0.05, 0.004, 0.001, 0.088, 0.001, 0.03, 0.018, 0.022, 2.886, 0.44, 0.8, 0.564, 1.075, 2.236, 0.315, 1.165, 1.904, 0.34, 1.795, 2.214, 1.337, 2.854, 2.759, 0.664, 0.0001, 0.0001, 0.24, 0.028, 0.005, 0.005, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.023, 0.0001, 0.001, 0.0001, 25.262, 16.34, 0.005, 0.714, 0.0001, 0.005, 0.001, 0.002, 0.005, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.006, 0.277, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ug": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.4, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 6.843, 0.005, 0.045, 0.0001, 0.0001, 0.006, 0.0001, 0.05, 0.059, 0.061, 0.001, 0.001, 0.064, 0.182, 0.431, 0.006, 0.116, 0.137, 0.086, 0.058, 0.051, 0.055, 0.044, 0.042, 0.045, 0.072, 0.055, 0.007, 0.018, 0.009, 0.017, 0.0001, 0.0001, 0.014, 0.005, 0.004, 0.003, 0.002, 0.001, 0.002, 0.002, 0.011, 0.008, 0.009, 0.003, 0.013, 0.002, 0.002, 0.005, 0.001, 0.002, 0.015, 0.014, 0.019, 0.001, 0.002, 0.002, 0.003, 0.0001, 0.003, 0.001, 0.003, 0.0001, 0.008, 0.0001, 0.198, 0.04, 0.041, 0.081, 0.144, 0.022, 0.07, 0.096, 0.317, 0.009, 0.06, 0.138, 0.069, 0.164, 0.09, 0.038, 0.044, 0.138, 0.091, 0.118, 0.088, 0.011, 0.018, 0.015, 0.072, 0.022, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.146, 0.075, 1.421, 1.142, 2.553, 1.322, 3.07, 1.622, 1.224, 6.252, 1.181, 0.454, 0.501, 0.027, 0.124, 0.02, 0.545, 0.041, 0.008, 0.046, 0.025, 2.705, 0.02, 0.099, 0.121, 0.09, 0.015, 0.082, 0.041, 0.012, 0.015, 0.06, 0.068, 0.006, 0.005, 0.06, 0.019, 0.028, 1.456, 3.601, 1.011, 0.28, 1.856, 0.056, 0.228, 0.623, 0.346, 2.099, 0.163, 2.119, 0.524, 1.075, 0.873, 0.045, 0.014, 0.035, 0.226, 0.052, 1.208, 0.825, 0.077, 0.089, 1.1, 0.024, 0.0001, 0.0001, 0.118, 0.051, 0.009, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.765, 0.262, 0.112, 0.09, 0.0001, 0.0001, 0.0001, 0.001, 14.938, 17.649, 1.694, 5.905, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.067, 0.002, 0.002, 0.006, 0.003, 0.003, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.007, 1.731, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ur": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.979, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.161, 0.002, 0.04, 0.0001, 0.0001, 0.001, 0.0001, 0.006, 0.157, 0.157, 0.0001, 0.001, 0.081, 0.085, 0.055, 0.007, 0.121, 0.179, 0.119, 0.082, 0.072, 0.073, 0.068, 0.065, 0.07, 0.096, 0.098, 0.002, 0.004, 0.003, 0.004, 0.0001, 0.0001, 0.02, 0.016, 0.035, 0.016, 0.006, 0.007, 0.013, 0.009, 0.011, 0.009, 0.012, 0.015, 0.025, 0.011, 0.007, 0.016, 0.003, 0.012, 0.029, 0.016, 0.005, 0.006, 0.007, 0.001, 0.005, 0.003, 0.004, 0.0001, 0.004, 0.0001, 0.004, 0.0001, 0.265, 0.03, 0.059, 0.059, 0.181, 0.032, 0.039, 0.075, 0.194, 0.006, 0.027, 0.102, 0.048, 0.197, 0.175, 0.037, 0.004, 0.142, 0.109, 0.147, 0.083, 0.021, 0.026, 0.005, 0.049, 0.011, 0.0001, 0.014, 0.0001, 0.0001, 0.0001, 0.055, 2.387, 0.534, 0.013, 1.581, 2.193, 2.297, 0.009, 2.712, 0.004, 0.024, 0.012, 4.725, 0.004, 0.025, 0.025, 0.036, 0.091, 1.735, 0.008, 0.507, 0.001, 0.001, 0.002, 0.02, 0.012, 0.0001, 0.005, 0.005, 0.004, 0.001, 0.005, 0.009, 0.069, 0.224, 0.005, 0.08, 0.002, 0.401, 5.353, 1.186, 2.395, 1.412, 0.054, 0.699, 0.376, 0.232, 1.576, 0.068, 2.734, 0.325, 1.531, 0.466, 0.218, 0.1, 0.222, 0.073, 1.112, 0.88, 0.012, 0.002, 0.002, 1.074, 0.003, 0.0001, 0.0001, 0.008, 0.011, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.005, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 18.028, 10.547, 4.494, 8.618, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.001, 0.049, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.043, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "uz": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.321, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.468, 0.001, 0.189, 0.0001, 0.0001, 0.012, 0.0001, 0.019, 0.383, 0.392, 0.002, 0.002, 1.018, 0.346, 1.56, 0.012, 0.451, 0.539, 0.363, 0.217, 0.199, 0.207, 0.182, 0.168, 0.187, 0.31, 0.029, 0.042, 0.003, 0.005, 0.003, 0.002, 0.0001, 0.288, 0.177, 0.127, 0.096, 0.051, 0.092, 0.103, 0.072, 0.123, 0.042, 0.115, 0.075, 0.277, 0.092, 0.158, 0.088, 0.099, 0.095, 0.293, 0.135, 0.08, 0.063, 0.021, 0.043, 0.077, 0.019, 0.006, 0.0001, 0.006, 0.001, 0.001, 0.005, 11.395, 1.621, 0.663, 2.97, 1.946, 0.469, 2.488, 2.791, 9.732, 0.446, 2.32, 4.562, 2.354, 4.897, 4.652, 0.487, 1.34, 4.598, 3.575, 3.341, 2.208, 1.083, 0.027, 0.322, 2.128, 0.799, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 0.456, 0.006, 0.008, 0.004, 0.002, 0.001, 0.001, 0.001, 0.003, 0.002, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 0.001, 0.165, 0.164, 0.0001, 0.001, 0.001, 0.064, 0.017, 0.001, 0.002, 0.019, 0.002, 0.019, 0.002, 0.169, 0.003, 0.003, 0.0001, 0.002, 0.0001, 0.0001, 0.002, 0.007, 0.014, 0.0001, 0.005, 0.001, 0.001, 0.0001, 0.0001, 0.04, 0.006, 0.006, 0.01, 0.015, 0.009, 0.006, 0.002, 0.016, 0.002, 0.006, 0.916, 0.127, 0.009, 0.012, 0.002, 0.0001, 0.0001, 0.192, 0.06, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 1.018, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.124, 0.036, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.449, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "ve": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.731, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.522, 0.012, 0.078, 0.0001, 0.0001, 0.001, 0.0001, 0.009, 0.159, 0.16, 0.0001, 0.001, 0.539, 0.225, 1.016, 0.019, 0.145, 0.2, 0.126, 0.043, 0.046, 0.05, 0.05, 0.043, 0.035, 0.051, 0.043, 0.011, 0.01, 0.003, 0.01, 0.007, 0.001, 0.246, 0.066, 0.041, 0.13, 0.054, 0.04, 0.046, 0.163, 0.081, 0.023, 0.129, 0.141, 0.422, 0.243, 0.021, 0.074, 0.002, 0.073, 0.154, 0.414, 0.061, 0.436, 0.032, 0.007, 0.055, 0.059, 0.001, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 13.088, 1.237, 0.128, 2.934, 4.075, 0.966, 1.256, 7.989, 6.478, 0.01, 1.611, 2.964, 2.428, 5.855, 4.328, 0.793, 0.003, 1.372, 2.898, 2.532, 4.835, 2.93, 2.215, 0.021, 0.876, 1.698, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.04, 0.003, 0.001, 0.0001, 0.002, 0.021, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.005, 0.137, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.006, 0.001, 0.001, 0.006, 0.005, 0.0001, 0.0001, 0.002, 0.001, 0.008, 0.001, 0.0001, 0.0001, 0.007, 0.001, 0.0001, 0.0001, 0.0001, 0.004, 0.002, 0.0001, 0.0001, 0.001, 0.008, 0.049, 0.003, 0.004, 0.0001, 0.0001, 0.001, 0.0001, 0.157, 0.074, 0.001, 0.002, 0.0001, 0.026, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.017, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.014, 0.002, 0.006, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.006, 0.231, 0.039, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "vec": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.253, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.683, 0.003, 0.435, 0.0001, 0.0001, 0.011, 0.001, 0.612, 0.188, 0.187, 0.0001, 0.002, 0.962, 0.099, 0.799, 0.015, 0.255, 0.324, 0.176, 0.103, 0.099, 0.11, 0.096, 0.095, 0.113, 0.179, 0.07, 0.031, 0.016, 0.004, 0.016, 0.001, 0.0001, 0.22, 0.135, 0.257, 0.11, 0.212, 0.092, 0.123, 0.029, 0.211, 0.028, 0.03, 0.164, 0.197, 0.115, 0.055, 0.192, 0.012, 0.112, 0.28, 0.113, 0.043, 0.127, 0.024, 0.034, 0.008, 0.022, 0.006, 0.0001, 0.006, 0.0001, 0.006, 0.0001, 9.014, 0.584, 2.527, 3.084, 9.08, 0.695, 1.267, 0.67, 6.478, 0.14, 0.121, 3.361, 1.486, 5.29, 5.96, 1.776, 0.156, 4.436, 3.403, 4.054, 1.601, 1.042, 0.044, 0.834, 0.071, 0.222, 0.0001, 0.006, 0.0001, 0.0001, 0.0001, 0.081, 0.084, 1.282, 0.004, 0.002, 0.002, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.003, 0.004, 0.001, 0.001, 0.002, 0.013, 0.001, 0.01, 0.002, 0.001, 0.001, 0.008, 0.004, 0.058, 0.055, 0.001, 0.003, 0.003, 0.0001, 0.001, 0.74, 0.012, 0.002, 0.002, 0.005, 0.001, 0.002, 0.041, 0.204, 0.163, 0.002, 0.004, 0.188, 0.007, 0.001, 0.002, 0.019, 0.005, 0.113, 0.084, 0.004, 0.003, 0.003, 0.001, 0.003, 0.085, 0.013, 0.006, 0.006, 0.01, 0.027, 0.003, 0.0001, 0.0001, 0.074, 1.6, 0.013, 1.389, 0.061, 0.0001, 0.005, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.014, 0.007, 0.012, 0.005, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.013, 0.075, 0.002, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "vep": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.78, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.379, 0.003, 0.471, 0.0001, 0.001, 0.103, 0.0001, 0.568, 0.495, 0.495, 0.0001, 0.017, 1.052, 0.379, 1.489, 0.012, 0.568, 0.707, 0.478, 0.223, 0.214, 0.232, 0.198, 0.192, 0.203, 0.325, 0.211, 0.045, 0.002, 0.001, 0.002, 0.001, 0.0001, 0.203, 0.112, 0.053, 0.077, 0.109, 0.05, 0.072, 0.067, 0.085, 0.066, 0.318, 0.157, 0.187, 0.127, 0.087, 0.197, 0.001, 0.106, 0.305, 0.17, 0.046, 0.359, 0.008, 0.005, 0.004, 0.023, 0.011, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 7.907, 0.771, 0.299, 4.189, 5.699, 0.182, 1.123, 1.305, 7.031, 1.198, 2.907, 3.562, 2.965, 5.97, 3.852, 1.33, 0.003, 2.724, 3.29, 3.069, 2.779, 1.746, 0.01, 0.004, 0.024, 0.95, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.243, 0.042, 0.031, 0.026, 0.016, 0.009, 0.007, 0.007, 0.018, 0.003, 0.008, 0.014, 0.04, 0.228, 0.004, 0.014, 0.011, 0.008, 0.007, 0.006, 0.198, 0.004, 0.004, 0.004, 0.004, 0.01, 0.011, 0.006, 0.059, 0.006, 0.007, 0.007, 0.049, 0.512, 0.005, 0.004, 1.459, 0.005, 0.005, 0.012, 0.007, 0.009, 0.006, 0.076, 0.003, 0.005, 0.006, 0.008, 0.087, 0.02, 0.049, 0.021, 0.019, 0.048, 0.155, 0.011, 0.041, 0.019, 0.037, 0.102, 0.539, 0.049, 0.808, 0.016, 0.0001, 0.0001, 0.208, 2.197, 0.255, 1.283, 0.0001, 0.0001, 0.0001, 0.018, 0.007, 0.013, 0.002, 0.001, 0.025, 0.012, 0.469, 0.173, 0.003, 0.003, 0.001, 0.006, 0.006, 0.011, 0.026, 0.019, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.026, 0.012, 0.203, 0.002, 0.001, 0.003, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "vls": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.228, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.739, 0.003, 0.38, 0.0001, 0.0001, 0.005, 0.003, 0.744, 0.196, 0.195, 0.001, 0.001, 0.727, 0.325, 0.943, 0.009, 0.279, 0.491, 0.2, 0.128, 0.127, 0.144, 0.128, 0.137, 0.161, 0.217, 0.083, 0.01, 0.008, 0.003, 0.008, 0.002, 0.0001, 0.184, 0.236, 0.118, 0.332, 0.112, 0.115, 0.126, 0.103, 0.261, 0.107, 0.122, 0.141, 0.163, 0.108, 0.113, 0.118, 0.004, 0.127, 0.191, 0.088, 0.03, 0.223, 0.122, 0.006, 0.022, 0.104, 0.001, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 4.751, 0.962, 1.1, 3.988, 12.635, 0.533, 2.162, 1.118, 4.159, 0.386, 1.909, 2.864, 1.62, 7.645, 4.865, 1.022, 0.013, 4.762, 3.511, 4.63, 2.292, 1.812, 1.033, 0.041, 0.74, 0.83, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.13, 0.003, 0.003, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.008, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.008, 0.015, 0.0001, 0.0001, 0.0001, 0.025, 0.093, 0.0001, 0.0001, 0.002, 0.002, 0.001, 0.001, 0.016, 0.003, 0.001, 0.001, 0.002, 0.001, 0.001, 0.004, 0.09, 0.034, 0.493, 0.075, 0.001, 0.002, 0.001, 0.006, 0.006, 0.003, 0.004, 0.004, 0.299, 0.002, 0.003, 0.001, 0.002, 0.001, 0.002, 0.002, 0.005, 0.002, 0.001, 0.002, 0.0001, 0.0001, 0.02, 1.045, 0.002, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.007, 0.004, 0.008, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.002, 0.13, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "vo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.865, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 14.101, 0.0001, 0.089, 0.0001, 0.177, 0.768, 0.0001, 0.013, 0.471, 0.471, 0.0001, 0.0001, 1.958, 0.301, 1.263, 0.002, 1.009, 1.484, 1.145, 0.885, 0.977, 0.988, 0.827, 0.571, 0.867, 0.731, 0.368, 0.112, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.099, 0.202, 0.186, 0.179, 0.034, 0.122, 0.068, 0.069, 0.028, 0.029, 0.035, 0.486, 0.223, 0.193, 0.038, 0.198, 0.004, 0.074, 0.506, 0.089, 0.221, 0.126, 0.048, 0.001, 0.008, 0.039, 0.004, 0.001, 0.005, 0.0001, 0.0001, 0.0001, 5.558, 2.077, 0.284, 2.834, 4.622, 1.332, 0.379, 0.28, 4.679, 0.128, 1.147, 4.377, 2.51, 5.854, 4.077, 1.175, 0.015, 1.237, 3.788, 2.427, 1.276, 0.657, 0.06, 0.029, 0.621, 0.304, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.73, 0.001, 0.0001, 0.005, 0.073, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.0001, 0.033, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.623, 0.0001, 0.0001, 0.045, 0.0001, 0.038, 0.009, 0.001, 0.006, 0.006, 0.01, 2.184, 0.0001, 0.0001, 0.003, 0.022, 0.052, 0.002, 0.001, 0.0001, 0.004, 0.0001, 0.0001, 0.27, 0.001, 0.247, 0.003, 0.014, 0.006, 1.503, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 1.216, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.516, 5.121, 0.006, 0.01, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.73, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "wa": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.065, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 16.234, 0.018, 0.387, 0.0001, 0.0001, 0.001, 0.005, 1.403, 0.391, 0.397, 0.0001, 0.006, 1.323, 0.328, 1.748, 0.02, 0.212, 0.344, 0.172, 0.086, 0.07, 0.086, 0.076, 0.078, 0.098, 0.148, 0.393, 0.059, 0.003, 0.003, 0.006, 0.012, 0.0001, 0.126, 0.117, 0.176, 0.177, 0.152, 0.211, 0.071, 0.055, 0.154, 0.041, 0.016, 0.325, 0.219, 0.065, 0.097, 0.121, 0.003, 0.069, 0.125, 0.076, 0.016, 0.053, 0.079, 0.005, 0.007, 0.005, 0.103, 0.0001, 0.103, 0.0001, 0.0001, 0.0001, 4.343, 0.71, 2.121, 3.465, 9.326, 0.692, 0.491, 0.929, 5.047, 0.968, 0.844, 3.108, 1.647, 4.913, 4.614, 1.529, 0.028, 3.303, 5.504, 4.286, 1.947, 1.135, 0.682, 0.179, 1.059, 0.366, 0.0001, 0.075, 0.0001, 0.0001, 0.0001, 0.076, 0.002, 0.002, 0.001, 0.001, 0.022, 0.001, 0.008, 0.005, 0.003, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.065, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.001, 0.371, 0.002, 0.017, 0.001, 0.001, 0.706, 0.003, 0.089, 0.451, 0.662, 0.205, 0.03, 0.001, 0.001, 0.639, 0.002, 0.006, 0.002, 0.002, 0.001, 0.243, 0.004, 0.001, 0.001, 0.001, 0.001, 0.002, 0.257, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.478, 3.239, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.006, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.08, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "war": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.118, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 12.933, 0.0001, 1.377, 0.0001, 0.0001, 0.0001, 0.003, 0.004, 0.008, 0.008, 0.0001, 0.0001, 0.432, 0.073, 1.214, 0.001, 0.079, 0.266, 0.062, 0.046, 0.041, 0.046, 0.05, 0.055, 0.111, 0.217, 0.037, 0.004, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 1.082, 0.154, 0.38, 0.175, 0.141, 0.098, 0.127, 0.173, 0.102, 0.057, 0.046, 0.208, 0.316, 0.091, 0.096, 0.293, 0.004, 0.105, 0.232, 0.146, 0.033, 0.038, 0.367, 0.012, 0.008, 0.019, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.129, 0.835, 2.123, 1.488, 5.092, 0.584, 3.71, 3.47, 8.491, 0.033, 1.376, 3.841, 1.504, 9.228, 3.14, 2.313, 0.025, 2.807, 5.239, 2.428, 2.957, 0.216, 0.413, 0.116, 1.506, 0.106, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.006, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.002, 0.004, 0.019, 0.0001, 0.001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.004, 0.003, 0.0001, 0.004, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.006, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.06, 0.002, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "wo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.906, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 18.371, 0.007, 0.083, 0.0001, 0.0001, 0.002, 0.0001, 0.048, 0.243, 0.244, 0.0001, 0.001, 1.526, 0.299, 0.6, 0.011, 0.077, 0.162, 0.075, 0.048, 0.048, 0.043, 0.038, 0.041, 0.05, 0.065, 0.149, 0.021, 0.001, 0.005, 0.001, 0.009, 0.0001, 0.248, 0.196, 0.082, 0.079, 0.037, 0.083, 0.06, 0.026, 0.08, 0.079, 0.082, 0.102, 0.179, 0.109, 0.049, 0.052, 0.005, 0.054, 0.208, 0.113, 0.015, 0.012, 0.059, 0.037, 0.106, 0.002, 0.002, 0.0001, 0.002, 0.0001, 0.001, 0.0001, 10.502, 2.142, 1.408, 2.296, 5.004, 0.815, 2.647, 0.171, 6.017, 1.265, 2.73, 3.516, 3.296, 5.064, 5.377, 0.616, 0.08, 2.151, 1.518, 2.39, 4.356, 0.021, 1.494, 1.066, 2.37, 0.019, 0.002, 0.0001, 0.004, 0.0001, 0.0001, 0.102, 0.006, 0.003, 0.003, 0.01, 0.005, 0.004, 0.003, 0.005, 0.001, 0.005, 0.02, 0.001, 0.001, 0.008, 0.002, 0.005, 0.039, 0.003, 0.026, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.041, 0.001, 0.0001, 0.016, 0.015, 0.0001, 0.0001, 0.641, 0.001, 0.002, 0.004, 0.002, 0.001, 0.001, 0.012, 0.011, 0.402, 0.004, 0.775, 0.001, 0.002, 0.001, 0.002, 0.004, 0.912, 0.013, 0.056, 0.002, 0.002, 0.001, 0.002, 0.003, 0.003, 0.002, 0.013, 0.001, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.028, 2.826, 0.002, 0.019, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.002, 0.0001, 0.004, 0.002, 0.016, 0.018, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.007, 0.033, 0.053, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.096, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "wuu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.208, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.344, 0.001, 0.064, 0.0001, 0.0001, 0.012, 0.001, 0.005, 0.037, 0.032, 0.001, 0.002, 0.029, 0.05, 0.042, 0.019, 0.267, 0.364, 0.21, 0.108, 0.106, 0.12, 0.107, 0.1, 0.123, 0.181, 0.013, 0.001, 0.013, 0.002, 0.013, 0.001, 0.0001, 0.027, 0.021, 0.029, 0.015, 0.013, 0.01, 0.014, 0.013, 0.018, 0.007, 0.011, 0.017, 0.022, 0.016, 0.01, 0.023, 0.002, 0.017, 0.03, 0.019, 0.009, 0.006, 0.008, 0.002, 0.003, 0.002, 0.03, 0.0001, 0.03, 0.0001, 0.003, 0.0001, 0.184, 0.024, 0.041, 0.051, 0.161, 0.019, 0.037, 0.056, 0.143, 0.005, 0.024, 0.082, 0.047, 0.138, 0.118, 0.028, 0.006, 0.111, 0.081, 0.088, 0.07, 0.016, 0.015, 0.01, 0.024, 0.008, 0.001, 0.002, 0.001, 0.001, 0.0001, 2.843, 1.238, 1.324, 0.655, 0.418, 1.022, 0.586, 0.937, 1.267, 1.305, 0.731, 1.421, 2.335, 0.988, 0.859, 1.016, 1.143, 0.568, 0.436, 0.439, 0.836, 0.673, 0.873, 1.003, 0.932, 0.655, 0.691, 1.033, 1.591, 0.82, 0.469, 0.875, 0.536, 0.577, 0.431, 0.453, 0.911, 0.859, 0.578, 0.722, 0.777, 0.496, 1.371, 0.496, 0.553, 1.219, 0.891, 1.125, 1.185, 0.888, 0.563, 0.66, 0.876, 0.472, 0.61, 0.726, 3.021, 1.231, 1.855, 1.189, 2.708, 1.052, 0.869, 1.001, 0.0001, 0.0001, 0.059, 0.019, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.005, 0.002, 0.002, 0.002, 0.0001, 0.011, 0.004, 0.02, 0.007, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.003, 0.011, 0.009, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.0001, 0.068, 0.005, 0.208, 1.565, 4.388, 9.361, 5.679, 3.099, 2.882, 2.131, 0.002, 0.004, 0.008, 0.002, 0.0001, 1.953, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "xal": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 2.016, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 7.801, 0.002, 0.076, 0.0001, 0.0001, 0.005, 0.0001, 0.002, 0.134, 0.134, 0.001, 0.003, 0.529, 0.574, 0.918, 0.006, 0.214, 0.423, 0.268, 0.17, 0.177, 0.128, 0.129, 0.128, 0.121, 0.185, 0.028, 0.007, 0.006, 0.001, 0.006, 0.006, 0.0001, 0.005, 0.004, 0.004, 0.001, 0.002, 0.002, 0.002, 0.002, 0.006, 0.001, 0.002, 0.002, 0.003, 0.001, 0.001, 0.002, 0.0001, 0.002, 0.005, 0.003, 0.001, 0.002, 0.003, 0.004, 0.001, 0.001, 0.005, 0.0001, 0.006, 0.0001, 0.005, 0.0001, 0.064, 0.016, 0.035, 0.026, 0.079, 0.017, 0.024, 0.144, 0.059, 0.003, 0.012, 0.04, 0.028, 0.059, 0.05, 0.015, 0.002, 0.048, 0.045, 0.048, 0.035, 0.008, 0.009, 0.006, 0.012, 0.006, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 2.512, 1.678, 1.585, 1.178, 0.036, 0.859, 0.336, 0.487, 0.211, 0.008, 0.012, 0.272, 0.319, 0.492, 0.054, 0.135, 0.09, 0.152, 0.041, 0.073, 0.19, 0.017, 0.022, 0.69, 0.054, 1.446, 0.115, 0.043, 0.168, 0.153, 0.159, 0.053, 0.055, 0.105, 0.151, 0.242, 0.028, 0.118, 0.031, 0.02, 0.093, 0.554, 0.004, 0.02, 0.002, 0.072, 0.031, 0.849, 3.75, 1.252, 0.825, 1.816, 2.139, 1.256, 0.115, 0.387, 2.666, 0.446, 0.987, 3.364, 1.079, 4.101, 2.147, 0.166, 0.0001, 0.0001, 0.041, 0.006, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.038, 0.0001, 0.0001, 0.004, 0.0001, 0.007, 0.004, 27.749, 10.017, 2.264, 1.98, 0.0001, 0.003, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.024, 0.035, 0.127, 0.0001, 0.0001, 0.004, 0.002, 0.001, 0.001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "xh": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.827, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 11.133, 0.013, 0.259, 0.004, 0.001, 0.009, 0.002, 0.046, 0.125, 0.123, 0.001, 0.005, 0.846, 0.831, 0.912, 0.026, 0.163, 0.218, 0.112, 0.059, 0.052, 0.058, 0.048, 0.051, 0.067, 0.118, 0.048, 0.023, 0.018, 0.006, 0.018, 0.006, 0.0001, 0.218, 0.122, 0.114, 0.05, 0.111, 0.054, 0.063, 0.043, 0.32, 0.057, 0.15, 0.086, 0.186, 0.216, 0.074, 0.101, 0.011, 0.057, 0.136, 0.094, 0.198, 0.022, 0.071, 0.041, 0.042, 0.046, 0.076, 0.001, 0.076, 0.0001, 0.013, 0.0001, 10.703, 2.404, 0.805, 1.231, 8.068, 0.529, 2.029, 3.142, 7.484, 0.244, 4.325, 4.529, 2.518, 6.863, 5.226, 0.943, 0.434, 1.064, 2.867, 2.574, 4.687, 0.307, 2.513, 0.353, 2.341, 2.213, 0.002, 0.028, 0.002, 0.0001, 0.0001, 0.043, 0.003, 0.001, 0.001, 0.002, 0.0001, 0.004, 0.012, 0.003, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.004, 0.01, 0.003, 0.0001, 0.0001, 0.001, 0.003, 0.018, 0.0001, 0.0001, 0.005, 0.005, 0.0001, 0.001, 0.1, 0.005, 0.001, 0.004, 0.001, 0.0001, 0.0001, 0.003, 0.001, 0.007, 0.001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.001, 0.004, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.101, 0.03, 0.014, 0.003, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.004, 0.003, 0.004, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.049, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "xmf": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.601, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 4.701, 0.001, 0.058, 0.0001, 0.0001, 0.01, 0.0001, 0.002, 0.121, 0.121, 0.0001, 0.001, 0.458, 0.166, 0.464, 0.005, 0.164, 0.192, 0.121, 0.06, 0.056, 0.064, 0.055, 0.055, 0.065, 0.102, 0.028, 0.018, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.008, 0.006, 0.008, 0.007, 0.003, 0.004, 0.003, 0.003, 0.027, 0.001, 0.002, 0.006, 0.007, 0.003, 0.003, 0.005, 0.0001, 0.004, 0.007, 0.009, 0.002, 0.008, 0.003, 0.01, 0.001, 0.0001, 0.006, 0.0001, 0.006, 0.0001, 0.001, 0.0001, 0.041, 0.006, 0.016, 0.012, 0.042, 0.004, 0.007, 0.012, 0.032, 0.001, 0.006, 0.021, 0.011, 0.029, 0.03, 0.007, 0.001, 0.029, 0.023, 0.023, 0.015, 0.005, 0.003, 0.002, 0.006, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.172, 0.003, 0.002, 30.333, 0.002, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 4.083, 0.506, 0.555, 0.957, 2.283, 0.421, 0.156, 0.803, 3.59, 0.653, 1.19, 1.236, 1.788, 2.02, 0.312, 0.098, 2.097, 1.217, 0.638, 1.469, 0.698, 0.389, 0.172, 0.093, 1.339, 0.152, 0.183, 0.083, 0.259, 0.102, 0.41, 0.184, 0.054, 0.009, 0.013, 0.002, 0.001, 0.003, 0.001, 0.323, 0.062, 0.002, 0.002, 0.002, 0.002, 0.003, 0.004, 0.002, 0.0001, 0.0001, 0.043, 0.004, 0.001, 0.001, 0.007, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.001, 0.0001, 0.011, 0.002, 0.023, 0.008, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.001, 0.004, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.009, 30.332, 0.17, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "yi": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.709, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.298, 0.002, 0.186, 0.0001, 0.001, 0.004, 0.006, 0.121, 0.075, 0.076, 0.0001, 0.0001, 0.466, 0.059, 0.46, 0.006, 0.099, 0.114, 0.062, 0.037, 0.035, 0.037, 0.03, 0.03, 0.038, 0.064, 0.034, 0.015, 0.001, 0.001, 0.001, 0.002, 0.0001, 0.003, 0.003, 0.004, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002, 0.001, 0.001, 0.002, 0.003, 0.002, 0.002, 0.002, 0.0001, 0.002, 0.004, 0.003, 0.001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.003, 0.0001, 0.003, 0.0001, 0.001, 0.0001, 0.02, 0.003, 0.006, 0.007, 0.022, 0.003, 0.004, 0.006, 0.017, 0.0001, 0.003, 0.01, 0.006, 0.015, 0.021, 0.004, 0.006, 0.015, 0.011, 0.018, 0.013, 0.002, 0.003, 0.001, 0.003, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.013, 0.004, 0.003, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 0.001, 0.0001, 0.0001, 0.001, 5.002, 1.068, 1.228, 1.611, 0.814, 3.904, 1.071, 0.178, 2.364, 5.673, 0.275, 0.347, 1.459, 0.389, 1.018, 2.472, 1.73, 1.057, 4.356, 0.098, 1.356, 0.06, 0.547, 0.832, 3.227, 0.975, 0.239, 0.001, 0.001, 0.001, 0.0001, 0.001, 0.02, 0.006, 0.026, 0.005, 0.016, 0.005, 0.002, 0.163, 0.104, 0.003, 0.002, 0.002, 0.041, 0.002, 0.022, 0.034, 0.0001, 0.0001, 0.015, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.003, 0.001, 0.029, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.372, 43.367, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.0001, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "yo": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 3.162, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 13.013, 0.002, 0.102, 0.0001, 0.001, 0.004, 0.001, 0.025, 0.251, 0.249, 0.0001, 0.001, 0.499, 0.259, 1.047, 0.013, 0.386, 0.744, 0.471, 0.336, 0.305, 0.301, 0.323, 0.299, 0.314, 0.417, 0.09, 0.08, 0.008, 0.009, 0.008, 0.006, 0.0001, 0.462, 0.171, 0.128, 0.102, 0.134, 0.101, 0.156, 0.11, 0.251, 0.116, 0.194, 0.108, 0.188, 0.187, 0.263, 0.133, 0.007, 0.102, 0.27, 0.148, 0.037, 0.042, 0.07, 0.006, 0.044, 0.016, 0.007, 0.0001, 0.008, 0.0001, 0.001, 0.001, 4.068, 1.959, 0.507, 1.515, 3.958, 0.547, 1.326, 0.747, 4.508, 1.331, 1.562, 2.445, 1.011, 4.469, 3.265, 1.008, 0.02, 3.063, 1.958, 2.732, 1.408, 0.219, 0.852, 0.039, 0.732, 0.092, 0.0001, 0.013, 0.0001, 0.0001, 0.0001, 0.678, 1.441, 0.002, 0.002, 0.064, 0.002, 0.001, 0.002, 0.025, 0.003, 0.001, 0.001, 0.172, 1.046, 0.0001, 0.0001, 0.001, 0.001, 0.032, 0.052, 0.002, 0.0001, 0.0001, 0.0001, 0.018, 0.066, 0.002, 0.001, 0.007, 0.006, 0.0001, 0.001, 1.085, 1.316, 0.01, 0.17, 0.004, 0.001, 0.001, 0.003, 0.307, 0.812, 0.001, 0.003, 1.559, 1.199, 0.001, 0.002, 0.003, 0.004, 0.287, 0.374, 0.003, 0.002, 0.006, 0.001, 0.038, 1.787, 1.887, 1.09, 0.005, 0.003, 0.003, 0.001, 0.0001, 0.0001, 0.021, 7.862, 0.009, 0.075, 0.0001, 0.008, 0.0001, 0.001, 0.001, 0.001, 1.898, 0.0001, 0.005, 0.002, 0.012, 0.004, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.005, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.004, 2.718, 0.12, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "za": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.779, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 9.452, 0.003, 0.07, 0.0001, 0.001, 0.016, 0.002, 0.054, 0.186, 0.179, 0.001, 0.0001, 0.82, 0.089, 0.74, 0.012, 0.236, 0.344, 0.171, 0.097, 0.104, 0.109, 0.078, 0.094, 0.113, 0.172, 0.091, 0.029, 0.001, 0.001, 0.002, 0.003, 0.0001, 0.117, 0.253, 0.245, 0.236, 0.047, 0.096, 0.232, 0.128, 0.101, 0.031, 0.049, 0.109, 0.142, 0.114, 0.031, 0.114, 0.005, 0.051, 0.316, 0.07, 0.028, 0.136, 0.041, 0.012, 0.157, 0.02, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 4.452, 1.127, 1.557, 2.16, 5.66, 0.54, 3.525, 2.807, 4.357, 1.245, 0.519, 1.215, 1.057, 5.149, 2.46, 0.332, 0.75, 1.554, 1.842, 1.639, 2.859, 0.55, 1.169, 0.375, 1.034, 2.115, 0.002, 0.0001, 0.002, 0.001, 0.0001, 1.059, 0.53, 0.446, 0.215, 0.472, 0.297, 0.257, 0.268, 0.372, 0.375, 0.213, 0.338, 0.751, 0.361, 0.284, 0.332, 0.27, 0.144, 0.117, 0.272, 0.266, 0.278, 0.305, 0.293, 0.26, 0.335, 0.49, 0.247, 0.537, 0.19, 0.142, 0.27, 0.209, 0.19, 0.122, 0.13, 0.301, 0.259, 0.231, 0.235, 0.283, 0.134, 0.154, 0.156, 0.162, 0.375, 0.302, 0.377, 0.293, 0.227, 0.124, 0.201, 0.231, 0.092, 0.229, 0.184, 0.748, 0.296, 0.646, 0.455, 0.756, 0.262, 0.268, 0.277, 0.0001, 0.0001, 0.072, 0.167, 0.018, 0.011, 0.0001, 0.002, 0.0001, 0.002, 0.001, 0.001, 0.001, 0.0001, 0.006, 0.002, 0.014, 0.004, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.012, 0.01, 0.002, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.022, 0.008, 0.114, 0.555, 1.309, 2.559, 1.698, 1.364, 0.916, 0.712, 0.001, 0.001, 0.001, 0.0001, 0.0001, 0.518, 0.001, 0.0001, 0.0001, 0.003, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "zea": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.532, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 15.056, 0.008, 0.162, 0.0001, 0.0001, 0.007, 0.001, 1.415, 0.162, 0.162, 0.0001, 0.0001, 1.0, 0.532, 1.127, 0.004, 0.395, 0.563, 0.389, 0.394, 0.405, 0.319, 0.329, 0.24, 0.265, 0.382, 0.062, 0.076, 0.002, 0.003, 0.001, 0.008, 0.0001, 0.28, 0.228, 0.122, 0.346, 0.208, 0.185, 0.11, 0.117, 0.317, 0.071, 0.084, 0.154, 0.152, 0.245, 0.188, 0.145, 0.004, 0.099, 0.307, 0.104, 0.026, 0.15, 0.089, 0.002, 0.005, 0.114, 0.003, 0.0001, 0.003, 0.0001, 0.0001, 0.001, 4.665, 0.916, 0.779, 3.731, 13.123, 0.39, 1.695, 1.202, 4.867, 0.455, 1.861, 2.604, 1.621, 7.033, 3.935, 1.063, 0.011, 4.601, 3.105, 3.908, 1.82, 1.832, 0.958, 0.04, 0.135, 0.573, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.482, 0.005, 0.003, 0.002, 0.003, 0.002, 0.001, 0.001, 0.002, 0.005, 0.002, 0.001, 0.001, 0.002, 0.0001, 0.001, 0.001, 0.001, 0.001, 0.005, 0.003, 0.001, 0.0001, 0.001, 0.021, 0.432, 0.001, 0.001, 0.01, 0.009, 0.003, 0.005, 0.009, 0.008, 0.021, 0.001, 0.002, 0.001, 0.003, 0.005, 0.09, 0.052, 0.453, 0.056, 0.009, 0.006, 0.003, 0.006, 0.115, 0.002, 0.14, 0.027, 0.252, 0.001, 0.064, 0.0001, 0.002, 0.002, 0.002, 0.006, 0.004, 0.002, 0.002, 0.001, 0.0001, 0.0001, 0.239, 1.084, 0.009, 0.01, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.005, 0.002, 0.008, 0.003, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.002, 0.007, 0.005, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.003, 0.481, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], + "zu": [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 1.261, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 10.94, 0.004, 0.267, 0.001, 0.002, 0.016, 0.003, 0.041, 0.181, 0.181, 0.001, 0.001, 0.907, 0.49, 0.797, 0.099, 0.343, 0.379, 0.279, 0.134, 0.118, 0.116, 0.102, 0.097, 0.11, 0.223, 0.065, 0.035, 0.134, 0.003, 0.135, 0.005, 0.0001, 0.296, 0.147, 0.142, 0.093, 0.11, 0.08, 0.077, 0.065, 0.3, 0.114, 0.141, 0.151, 0.361, 0.387, 0.067, 0.128, 0.012, 0.082, 0.239, 0.152, 0.188, 0.039, 0.182, 0.012, 0.045, 0.07, 0.138, 0.0001, 0.139, 0.0001, 0.001, 0.0001, 10.325, 2.215, 0.829, 1.627, 7.521, 0.687, 2.042, 3.525, 7.719, 0.199, 3.874, 4.421, 2.406, 6.494, 4.881, 0.951, 0.342, 1.361, 3.011, 2.552, 4.691, 0.394, 2.227, 0.134, 1.688, 1.779, 0.0001, 0.002, 0.0001, 0.0001, 0.0001, 0.08, 0.007, 0.001, 0.001, 0.002, 0.0001, 0.014, 0.002, 0.002, 0.001, 0.0001, 0.001, 0.003, 0.005, 0.001, 0.002, 0.002, 0.014, 0.001, 0.01, 0.003, 0.0001, 0.001, 0.001, 0.002, 0.06, 0.0001, 0.001, 0.003, 0.003, 0.001, 0.0001, 0.084, 0.004, 0.0001, 0.001, 0.001, 0.0001, 0.002, 0.004, 0.002, 0.005, 0.003, 0.001, 0.001, 0.002, 0.001, 0.0001, 0.004, 0.003, 0.003, 0.005, 0.002, 0.002, 0.001, 0.006, 0.005, 0.002, 0.003, 0.005, 0.002, 0.003, 0.003, 0.0001, 0.0001, 0.0001, 0.089, 0.024, 0.004, 0.007, 0.0001, 0.0001, 0.0001, 0.002, 0.001, 0.001, 0.0001, 0.0001, 0.002, 0.001, 0.029, 0.011, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.002, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.002, 0.002, 0.091, 0.001, 0.0001, 0.001, 0.002, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001], +}); + +/** + * Determines whether two ArrayBuffers contain the same values. + * + * @param {ArrayBuffer} a + * @param {ArrayBuffer} b + * @returns {boolean} + */ +function _buffersEqual(a, b) { + if (a === b) { + return true; + } + + if (a.byteLength !== b.byteLength) { + return false; + } + + const ai = new Uint8Array(a), + bi = new Uint8Array(b); + + let i = a.byteLength; + while (i--) { + if (ai[i] !== bi[i]) { + return false; + } + } + + return true; +} + +export default Magic; diff --git a/src/core/lib/PGP.mjs b/src/core/lib/PGP.mjs new file mode 100644 index 00000000..8970b486 --- /dev/null +++ b/src/core/lib/PGP.mjs @@ -0,0 +1,117 @@ +/** + * PGP functions. + * + * @author tlwr [toby@toby.codes] + * @author Matt C [matt@artemisbot.uk] + * @author n1474335 [n1474335@gmail.com] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + * + */ + +import OperationError from "../errors/OperationError"; +import kbpgp from "kbpgp"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * Progress callback + */ +export const ASP = kbpgp.ASP({ + "progress_hook": info => { + let msg = ""; + + switch (info.what) { + case "guess": + msg = "Guessing a prime"; + break; + case "fermat": + msg = "Factoring prime using Fermat's factorization method"; + break; + case "mr": + msg = "Performing Miller-Rabin primality test"; + break; + case "passed_mr": + msg = "Passed Miller-Rabin primality test"; + break; + case "failed_mr": + msg = "Failed Miller-Rabin primality test"; + break; + case "found": + msg = "Prime found"; + break; + default: + msg = `Stage: ${info.what}`; + } + + if (ENVIRONMENT_IS_WORKER()) + self.sendStatusMessage(msg); + } +}); + +/** + * Get size of subkey + * + * @param {number} keySize + * @returns {number} + */ +export function getSubkeySize(keySize) { + return { + 1024: 1024, + 2048: 1024, + 4096: 2048, + 256: 256, + 384: 256, + }[keySize]; +} + +/** +* Import private key and unlock if necessary +* +* @param {string} privateKey +* @param {string} [passphrase] +* @returns {Object} +*/ +export async function importPrivateKey(privateKey, passphrase) { + try { + const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({ + armored: privateKey, + opts: { + "no_check_keys": true + } + }); + if (key.is_pgp_locked()) { + if (passphrase) { + await promisify(key.unlock_pgp.bind(key))({ + passphrase + }); + } else { + throw new OperationError("Did not provide passphrase with locked private key."); + } + } + return key; + } catch (err) { + throw new OperationError(`Could not import private key: ${err}`); + } +} + +/** + * Import public key + * + * @param {string} publicKey + * @returns {Object} + */ +export async function importPublicKey (publicKey) { + try { + const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({ + armored: publicKey, + opts: { + "no_check_keys": true + } + }); + return key; + } catch (err) { + throw new OperationError(`Could not import public key: ${err}`); + } +} diff --git a/src/core/operations/AESDecrypt.mjs b/src/core/operations/AESDecrypt.mjs new file mode 100644 index 00000000..7d9ac5ca --- /dev/null +++ b/src/core/operations/AESDecrypt.mjs @@ -0,0 +1,108 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import forge from "node-forge/dist/forge.min.js"; +import OperationError from "../errors/OperationError"; + +/** + * AES Decrypt operation + */ +class AESDecrypt extends Operation { + + /** + * AESDecrypt constructor + */ + constructor() { + super(); + + this.name = "AES Decrypt"; + this.module = "Ciphers"; + this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256


IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.

GCM Tag: This field is ignored unless 'GCM' mode is used."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + }, + { + "name": "IV", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + }, + { + "name": "Mode", + "type": "option", + "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"] + }, + { + "name": "Input", + "type": "option", + "value": ["Hex", "Raw"] + }, + { + "name": "Output", + "type": "option", + "value": ["Raw", "Hex"] + }, + { + "name": "GCM Tag", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if cannot decrypt input or invalid key length + */ + run(input, args) { + const key = Utils.convertToByteArray(args[0].string, args[0].option), + iv = Utils.convertToByteArray(args[1].string, args[1].option), + mode = args[2], + inputType = args[3], + outputType = args[4], + gcmTag = Utils.convertToByteString(args[5].string, args[5].option); + + if ([16, 24, 32].indexOf(key.length) < 0) { + throw new OperationError(`Invalid key length: ${key.length} bytes + +The following algorithms will be used based on the size of the key: + 16 bytes = AES-128 + 24 bytes = AES-192 + 32 bytes = AES-256`); + } + + input = Utils.convertToByteString(input, inputType); + + const decipher = forge.cipher.createDecipher("AES-" + mode, key); + decipher.start({ + iv: iv, + tag: gcmTag + }); + decipher.update(forge.util.createBuffer(input)); + const result = decipher.finish(); + + if (result) { + return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes(); + } else { + throw new OperationError("Unable to decrypt input with these parameters."); + } + } + +} + +export default AESDecrypt; diff --git a/src/core/operations/AESEncrypt.mjs b/src/core/operations/AESEncrypt.mjs new file mode 100644 index 00000000..98a4c259 --- /dev/null +++ b/src/core/operations/AESEncrypt.mjs @@ -0,0 +1,106 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import forge from "node-forge/dist/forge.min.js"; +import OperationError from "../errors/OperationError"; + +/** + * AES Encrypt operation + */ +class AESEncrypt extends Operation { + + /** + * AESEncrypt constructor + */ + constructor() { + super(); + + this.name = "AES Encrypt"; + this.module = "Ciphers"; + this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256
You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + }, + { + "name": "IV", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + }, + { + "name": "Mode", + "type": "option", + "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"] + }, + { + "name": "Input", + "type": "option", + "value": ["Raw", "Hex"] + }, + { + "name": "Output", + "type": "option", + "value": ["Hex", "Raw"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if invalid key length + */ + run(input, args) { + const key = Utils.convertToByteArray(args[0].string, args[0].option), + iv = Utils.convertToByteArray(args[1].string, args[1].option), + mode = args[2], + inputType = args[3], + outputType = args[4]; + + if ([16, 24, 32].indexOf(key.length) < 0) { + throw new OperationError(`Invalid key length: ${key.length} bytes + +The following algorithms will be used based on the size of the key: + 16 bytes = AES-128 + 24 bytes = AES-192 + 32 bytes = AES-256`); + } + + input = Utils.convertToByteString(input, inputType); + + const cipher = forge.cipher.createCipher("AES-" + mode, key); + cipher.start({iv: iv}); + cipher.update(forge.util.createBuffer(input)); + cipher.finish(); + + if (outputType === "Hex") { + if (mode === "GCM") { + return cipher.output.toHex() + "\n\n" + + "Tag: " + cipher.mode.tag.toHex(); + } + return cipher.output.toHex(); + } else { + if (mode === "GCM") { + return cipher.output.getBytes() + "\n\n" + + "Tag: " + cipher.mode.tag.getBytes(); + } + return cipher.output.getBytes(); + } + } + +} + +export default AESEncrypt; diff --git a/src/core/operations/AddLineNumbers.mjs b/src/core/operations/AddLineNumbers.mjs new file mode 100644 index 00000000..7e53d685 --- /dev/null +++ b/src/core/operations/AddLineNumbers.mjs @@ -0,0 +1,46 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Add line numbers operation + */ +class AddLineNumbers extends Operation { + + /** + * AddLineNumbers constructor + */ + constructor() { + super(); + + this.name = "Add line numbers"; + this.module = "Default"; + this.description = "Adds line numbers to the output."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const lines = input.split("\n"), + width = lines.length.toString().length; + let output = ""; + + for (let n = 0; n < lines.length; n++) { + output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n"; + } + return output.slice(0, output.length-1); + } + +} + +export default AddLineNumbers; diff --git a/src/core/operations/Adler32Checksum.mjs b/src/core/operations/Adler32Checksum.mjs new file mode 100644 index 00000000..3e8013bd --- /dev/null +++ b/src/core/operations/Adler32Checksum.mjs @@ -0,0 +1,52 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Adler-32 Checksum operation + */ +class Adler32Checksum extends Operation { + + /** + * Adler32Checksum constructor + */ + constructor() { + super(); + + this.name = "Adler-32 Checksum"; + this.module = "Hashing"; + this.description = "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).

Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const MOD_ADLER = 65521; + let a = 1, + b = 0; + + for (let i = 0; i < input.length; i++) { + a += input[i]; + b += a; + } + + a %= MOD_ADLER; + b %= MOD_ADLER; + + return Utils.hex(((b << 16) | a) >>> 0, 8); + } + +} + +export default Adler32Checksum; diff --git a/src/core/operations/AffineCipherDecode.mjs b/src/core/operations/AffineCipherDecode.mjs new file mode 100644 index 00000000..3f65c150 --- /dev/null +++ b/src/core/operations/AffineCipherDecode.mjs @@ -0,0 +1,105 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; + +/** + * Affine Cipher Decode operation + */ +class AffineCipherDecode extends Operation { + + /** + * AffineCipherDecode constructor + */ + constructor() { + super(); + + this.name = "Affine Cipher Decode"; + this.module = "Ciphers"; + this.description = "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "a", + "type": "number", + "value": 1 + }, + { + "name": "b", + "type": "number", + "value": 0 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if a or b values are invalid + */ + run(input, args) { + const alphabet = "abcdefghijklmnopqrstuvwxyz", + [a, b] = args, + aModInv = Utils.modInv(a, 26); // Calculates modular inverse of a + let output = ""; + + if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) { + throw new OperationError("The values of a and b can only be integers."); + } + + if (Utils.gcd(a, 26) !== 1) { + throw new OperationError("The value of `a` must be coprime to 26."); + } + + for (let i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + // Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse) + output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)]; + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + // Same as above, accounting for uppercase + output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase(); + } else { + // Non-alphabetic characters + output += input[i]; + } + } + return output; + } + + /** + * Highlight Affine Cipher Decode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Affine Cipher Decode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default AffineCipherDecode; diff --git a/src/core/operations/AffineCipherEncode.mjs b/src/core/operations/AffineCipherEncode.mjs new file mode 100644 index 00000000..e9aeec32 --- /dev/null +++ b/src/core/operations/AffineCipherEncode.mjs @@ -0,0 +1,77 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { affineEncode } from "../lib/Ciphers"; + +/** + * Affine Cipher Encode operation + */ +class AffineCipherEncode extends Operation { + + /** + * AffineCipherEncode constructor + */ + constructor() { + super(); + + this.name = "Affine Cipher Encode"; + this.module = "Ciphers"; + this.description = "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, (ax + b) % 26, and converted back to a letter."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "a", + "type": "number", + "value": 1 + }, + { + "name": "b", + "type": "number", + "value": 0 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return affineEncode(input, args); + } + + /** + * Highlight Affine Cipher Encode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Affine Cipher Encode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default AffineCipherEncode; diff --git a/src/core/operations/AnalyseHash.mjs b/src/core/operations/AnalyseHash.mjs new file mode 100644 index 00000000..e53b515e --- /dev/null +++ b/src/core/operations/AnalyseHash.mjs @@ -0,0 +1,183 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Analyse hash operation + */ +class AnalyseHash extends Operation { + + /** + * AnalyseHash constructor + */ + constructor() { + super(); + + this.name = "Analyse hash"; + this.module = "Hashing"; + this.description = "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + input = input.replace(/\s/g, ""); + + let output = "", + possibleHashFunctions = []; + const byteLength = input.length / 2, + bitLength = byteLength * 8; + + if (!/^[a-f0-9]+$/i.test(input)) { + throw new OperationError("Invalid hash"); + } + + output += "Hash length: " + input.length + "\n" + + "Byte length: " + byteLength + "\n" + + "Bit length: " + bitLength + "\n\n" + + "Based on the length, this hash could have been generated by one of the following hashing functions:\n"; + + switch (bitLength) { + case 4: + possibleHashFunctions = [ + "Fletcher-4", + "Luhn algorithm", + "Verhoeff algorithm", + ]; + break; + case 8: + possibleHashFunctions = [ + "Fletcher-8", + ]; + break; + case 16: + possibleHashFunctions = [ + "BSD checksum", + "CRC-16", + "SYSV checksum", + "Fletcher-16" + ]; + break; + case 32: + possibleHashFunctions = [ + "CRC-32", + "Fletcher-32", + "Adler-32", + ]; + break; + case 64: + possibleHashFunctions = [ + "CRC-64", + "RIPEMD-64", + "SipHash", + ]; + break; + case 128: + possibleHashFunctions = [ + "MD5", + "MD4", + "MD2", + "HAVAL-128", + "RIPEMD-128", + "Snefru", + "Tiger-128", + ]; + break; + case 160: + possibleHashFunctions = [ + "SHA-1", + "SHA-0", + "FSB-160", + "HAS-160", + "HAVAL-160", + "RIPEMD-160", + "Tiger-160", + ]; + break; + case 192: + possibleHashFunctions = [ + "Tiger", + "HAVAL-192", + ]; + break; + case 224: + possibleHashFunctions = [ + "SHA-224", + "SHA3-224", + "ECOH-224", + "FSB-224", + "HAVAL-224", + ]; + break; + case 256: + possibleHashFunctions = [ + "SHA-256", + "SHA3-256", + "BLAKE-256", + "ECOH-256", + "FSB-256", + "GOST", + "Grøstl-256", + "HAVAL-256", + "PANAMA", + "RIPEMD-256", + "Snefru", + ]; + break; + case 320: + possibleHashFunctions = [ + "RIPEMD-320", + ]; + break; + case 384: + possibleHashFunctions = [ + "SHA-384", + "SHA3-384", + "ECOH-384", + "FSB-384", + ]; + break; + case 512: + possibleHashFunctions = [ + "SHA-512", + "SHA3-512", + "BLAKE-512", + "ECOH-512", + "FSB-512", + "Grøstl-512", + "JH", + "MD6", + "Spectral Hash", + "SWIFFT", + "Whirlpool", + ]; + break; + case 1024: + possibleHashFunctions = [ + "Fowler-Noll-Vo", + ]; + break; + default: + possibleHashFunctions = [ + "Unknown" + ]; + break; + } + + return output + possibleHashFunctions.join("\n"); + } + +} + +export default AnalyseHash; diff --git a/src/core/operations/AtbashCipher.mjs b/src/core/operations/AtbashCipher.mjs new file mode 100644 index 00000000..9c4657ef --- /dev/null +++ b/src/core/operations/AtbashCipher.mjs @@ -0,0 +1,66 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { affineEncode } from "../lib/Ciphers"; + +/** + * Atbash Cipher operation + */ +class AtbashCipher extends Operation { + + /** + * AtbashCipher constructor + */ + constructor() { + super(); + + this.name = "Atbash Cipher"; + this.module = "Ciphers"; + this.description = "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return affineEncode(input, [25, 25]); + } + + /** + * Highlight Atbash Cipher + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Atbash Cipher in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default AtbashCipher; diff --git a/src/core/operations/BSONDeserialise.mjs b/src/core/operations/BSONDeserialise.mjs new file mode 100644 index 00000000..b0225569 --- /dev/null +++ b/src/core/operations/BSONDeserialise.mjs @@ -0,0 +1,50 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import bsonjs from "bson"; +import OperationError from "../errors/OperationError"; + +/** + * BSON deserialise operation + */ +class BSONDeserialise extends Operation { + + /** + * BSONDeserialise constructor + */ + constructor() { + super(); + + this.name = "BSON deserialise"; + this.module = "BSON"; + this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be in a raw bytes format."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (!input.byteLength) return ""; + + const bson = new bsonjs(); + + try { + const data = bson.deserialize(new Buffer(input)); + return JSON.stringify(data, null, 2); + } catch (err) { + throw new OperationError(err.toString()); + } + } + +} + +export default BSONDeserialise; diff --git a/src/core/operations/BSONSerialise.mjs b/src/core/operations/BSONSerialise.mjs new file mode 100644 index 00000000..a82296b3 --- /dev/null +++ b/src/core/operations/BSONSerialise.mjs @@ -0,0 +1,50 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import bsonjs from "bson"; +import OperationError from "../errors/OperationError"; + +/** + * BSON serialise operation + */ +class BSONSerialise extends Operation { + + /** + * BSONSerialise constructor + */ + constructor() { + super(); + + this.name = "BSON serialise"; + this.module = "BSON"; + this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be valid JSON."; + this.inputType = "string"; + this.outputType = "ArrayBuffer"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + if (!input) return new ArrayBuffer(); + + const bson = new bsonjs(); + + try { + const data = JSON.parse(input); + return bson.serialize(data).buffer; + } catch (err) { + throw new OperationError(err.toString()); + } + } + +} + +export default BSONSerialise; diff --git a/src/core/operations/Bcrypt.mjs b/src/core/operations/Bcrypt.mjs new file mode 100644 index 00000000..cccf4131 --- /dev/null +++ b/src/core/operations/Bcrypt.mjs @@ -0,0 +1,54 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import bcrypt from "bcryptjs"; + +/** + * Bcrypt operation + */ +class Bcrypt extends Operation { + + /** + * Bcrypt constructor + */ + constructor() { + super(); + + this.name = "Bcrypt"; + this.module = "Hashing"; + this.description = "bcrypt is a password hashing function designed by Niels Provos and David Mazi\xe8res, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

Enter the password in the input to generate its hash."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Rounds", + "type": "number", + "value": 10 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + async run(input, args) { + const rounds = args[0]; + const salt = await bcrypt.genSalt(rounds); + + return await bcrypt.hash(input, salt, null, p => { + // Progress callback + if (ENVIRONMENT_IS_WORKER()) + self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); + }); + + } + +} + +export default Bcrypt; diff --git a/src/core/operations/BcryptCompare.mjs b/src/core/operations/BcryptCompare.mjs new file mode 100644 index 00000000..32f275b5 --- /dev/null +++ b/src/core/operations/BcryptCompare.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import bcrypt from "bcryptjs"; + +/** + * Bcrypt compare operation + */ +class BcryptCompare extends Operation { + + /** + * BcryptCompare constructor + */ + constructor() { + super(); + + this.name = "Bcrypt compare"; + this.module = "Hashing"; + this.description = "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Hash", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + async run(input, args) { + const hash = args[0]; + + const match = await bcrypt.compare(input, hash, null, p => { + // Progress callback + if (ENVIRONMENT_IS_WORKER()) + self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); + }); + + return match ? "Match: " + input : "No match"; + + } + +} + +export default BcryptCompare; diff --git a/src/core/operations/BcryptParse.mjs b/src/core/operations/BcryptParse.mjs new file mode 100644 index 00000000..149bdaa0 --- /dev/null +++ b/src/core/operations/BcryptParse.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; +import bcrypt from "bcryptjs"; + +/** + * Bcrypt parse operation + */ +class BcryptParse extends Operation { + + /** + * BcryptParse constructor + */ + constructor() { + super(); + + this.name = "Bcrypt parse"; + this.module = "Hashing"; + this.description = "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + async run(input, args) { + try { + return `Rounds: ${bcrypt.getRounds(input)} +Salt: ${bcrypt.getSalt(input)} +Password hash: ${input.split(bcrypt.getSalt(input))[1]} +Full hash: ${input}`; + } catch (err) { + throw new OperationError("Error: " + err.toString()); + } + } + +} + +export default BcryptParse; diff --git a/src/core/operations/BifidCipherDecode.mjs b/src/core/operations/BifidCipherDecode.mjs new file mode 100644 index 00000000..f5e2ad47 --- /dev/null +++ b/src/core/operations/BifidCipherDecode.mjs @@ -0,0 +1,124 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { genPolybiusSquare } from "../lib/Ciphers"; +import OperationError from "../errors/OperationError"; + +/** + * Bifid Cipher Decode operation + */ +class BifidCipherDecode extends Operation { + + /** + * BifidCipherDecode constructor + */ + constructor() { + super(); + + this.name = "Bifid Cipher Decode"; + this.module = "Ciphers"; + this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Keyword", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if invalid key + */ + run(input, args) { + const keywordStr = args[0].toUpperCase().replace("J", "I"), + keyword = keywordStr.split("").unique(), + alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ", + structure = []; + + let output = "", + count = 0, + trans = ""; + + if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0) + throw new OperationError("The key must consist only of letters in the English alphabet"); + + const polybius = genPolybiusSquare(keywordStr); + + input.replace("J", "I").split("").forEach((letter) => { + const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0; + let polInd; + + if (alpInd) { + for (let i = 0; i < 5; i++) { + polInd = polybius[i].indexOf(letter.toLocaleUpperCase()); + if (polInd >= 0) { + trans += `${i}${polInd}`; + } + } + + if (alpha.split("").indexOf(letter) >= 0) { + structure.push(true); + } else if (alpInd) { + structure.push(false); + } + } else { + structure.push(letter); + } + }); + + structure.forEach(pos => { + if (typeof pos === "boolean") { + const coords = [trans[count], trans[count+trans.length/2]]; + + output += pos ? + polybius[coords[0]][coords[1]] : + polybius[coords[0]][coords[1]].toLocaleLowerCase(); + count++; + } else { + output += pos; + } + }); + + return output; + } + + /** + * Highlight Bifid Cipher Decode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Bifid Cipher Decode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default BifidCipherDecode; diff --git a/src/core/operations/BifidCipherEncode.mjs b/src/core/operations/BifidCipherEncode.mjs new file mode 100644 index 00000000..41c29db0 --- /dev/null +++ b/src/core/operations/BifidCipherEncode.mjs @@ -0,0 +1,129 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; +import { genPolybiusSquare } from "../lib/Ciphers"; + +/** + * Bifid Cipher Encode operation + */ +class BifidCipherEncode extends Operation { + + /** + * BifidCipherEncode constructor + */ + constructor() { + super(); + + this.name = "Bifid Cipher Encode"; + this.module = "Ciphers"; + this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Keyword", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if key is invalid + */ + run(input, args) { + const keywordStr = args[0].toUpperCase().replace("J", "I"), + keyword = keywordStr.split("").unique(), + alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ", + xCo = [], + yCo = [], + structure = []; + + let output = "", + count = 0; + + + if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0) + throw new OperationError("The key must consist only of letters in the English alphabet"); + + const polybius = genPolybiusSquare(keywordStr); + + input.replace("J", "I").split("").forEach(letter => { + const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0; + let polInd; + + if (alpInd) { + for (let i = 0; i < 5; i++) { + polInd = polybius[i].indexOf(letter.toLocaleUpperCase()); + if (polInd >= 0) { + xCo.push(polInd); + yCo.push(i); + } + } + + if (alpha.split("").indexOf(letter) >= 0) { + structure.push(true); + } else if (alpInd) { + structure.push(false); + } + } else { + structure.push(letter); + } + }); + + const trans = `${yCo.join("")}${xCo.join("")}`; + + structure.forEach(pos => { + if (typeof pos === "boolean") { + const coords = trans.substr(2*count, 2).split(""); + + output += pos ? + polybius[coords[0]][coords[1]] : + polybius[coords[0]][coords[1]].toLocaleLowerCase(); + count++; + } else { + output += pos; + } + }); + + return output; + } + + /** + * Highlight Bifid Cipher Encode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Bifid Cipher Encode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default BifidCipherEncode; diff --git a/src/core/operations/BitShiftLeft.mjs b/src/core/operations/BitShiftLeft.mjs new file mode 100644 index 00000000..59c740f2 --- /dev/null +++ b/src/core/operations/BitShiftLeft.mjs @@ -0,0 +1,75 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Bit shift left operation + */ +class BitShiftLeft extends Operation { + + /** + * BitShiftLeft constructor + */ + constructor() { + super(); + + this.name = "Bit shift left"; + this.module = "Default"; + this.description = "Shifts the bits in each byte towards the left by the specified amount."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Amount", + "type": "number", + "value": 1 + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const amount = args[0]; + + return input.map(b => { + return (b << amount) & 0xff; + }); + } + + /** + * Highlight Bit shift left + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Bit shift left in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default BitShiftLeft; diff --git a/src/core/operations/BitShiftRight.mjs b/src/core/operations/BitShiftRight.mjs new file mode 100644 index 00000000..8207f353 --- /dev/null +++ b/src/core/operations/BitShiftRight.mjs @@ -0,0 +1,82 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Bit shift right operation + */ +class BitShiftRight extends Operation { + + /** + * BitShiftRight constructor + */ + constructor() { + super(); + + this.name = "Bit shift right"; + this.module = "Default"; + this.description = "Shifts the bits in each byte towards the right by the specified amount.

Logical shifts replace the leftmost bits with zeros.
Arithmetic shifts preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative)."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Amount", + "type": "number", + "value": 1 + }, + { + "name": "Type", + "type": "option", + "value": ["Logical shift", "Arithmetic shift"] + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const amount = args[0], + type = args[1], + mask = type === "Logical shift" ? 0 : 0x80; + + return input.map(b => { + return (b >>> amount) ^ (b & mask); + }); + } + + /** + * Highlight Bit shift right + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Bit shift right in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default BitShiftRight; diff --git a/src/core/operations/Bzip2Decompress.mjs b/src/core/operations/Bzip2Decompress.mjs new file mode 100644 index 00000000..e31b3d2c --- /dev/null +++ b/src/core/operations/Bzip2Decompress.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import bzip2 from "../vendor/bzip2.js"; +import OperationError from "../errors/OperationError"; + +/** + * Bzip2 Decompress operation + */ +class Bzip2Decompress extends Operation { + + /** + * Bzip2Decompress constructor + */ + constructor() { + super(); + + this.name = "Bzip2 Decompress"; + this.module = "Compression"; + this.description = "Decompresses data using the Bzip2 algorithm."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + this.patterns = [ + { + "match": "^\\x42\\x5a\\x68", + "flags": "", + "args": [] + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const compressed = new Uint8Array(input); + + try { + const bzip2Reader = bzip2.array(compressed); + return bzip2.simple(bzip2Reader); + } catch (err) { + throw new OperationError(err); + } + } + +} + +export default Bzip2Decompress; diff --git a/src/core/operations/CRC16Checksum.mjs b/src/core/operations/CRC16Checksum.mjs new file mode 100644 index 00000000..c4c5d633 --- /dev/null +++ b/src/core/operations/CRC16Checksum.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import JSCRC from "js-crc"; + +/** + * CRC-16 Checksum operation + */ +class CRC16Checksum extends Operation { + + /** + * CRC16Checksum constructor + */ + constructor() { + super(); + + this.name = "CRC-16 Checksum"; + this.module = "Hashing"; + this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return JSCRC.crc16(input); + } + +} + +export default CRC16Checksum; diff --git a/src/core/operations/CRC32Checksum.mjs b/src/core/operations/CRC32Checksum.mjs new file mode 100644 index 00000000..5982273e --- /dev/null +++ b/src/core/operations/CRC32Checksum.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import JSCRC from "js-crc"; + +/** + * CRC-32 Checksum operation + */ +class CRC32Checksum extends Operation { + + /** + * CRC32Checksum constructor + */ + constructor() { + super(); + + this.name = "CRC-32 Checksum"; + this.module = "Hashing"; + this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return JSCRC.crc32(input); + } + +} + +export default CRC32Checksum; diff --git a/src/core/operations/CTPH.mjs b/src/core/operations/CTPH.mjs new file mode 100644 index 00000000..39f52af4 --- /dev/null +++ b/src/core/operations/CTPH.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import ctphjs from "ctph.js"; + +/** + * CTPH operation + */ +class CTPH extends Operation { + + /** + * CTPH constructor + */ + constructor() { + super(); + + this.name = "CTPH"; + this.module = "Hashing"; + this.description = "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return ctphjs.digest(input); + } + +} + +export default CTPH; diff --git a/src/core/operations/CartesianProduct.mjs b/src/core/operations/CartesianProduct.mjs index 5125511b..0d5346fb 100644 --- a/src/core/operations/CartesianProduct.mjs +++ b/src/core/operations/CartesianProduct.mjs @@ -41,7 +41,7 @@ class CartesianProduct extends Operation { * Validate input length * * @param {Object[]} sets - * @throws {Error} if fewer than 2 sets + * @throws {OperationError} if fewer than 2 sets */ validateSampleNumbers(sets) { if (!sets || sets.length < 2) { diff --git a/src/core/operations/ChiSquare.mjs b/src/core/operations/ChiSquare.mjs new file mode 100644 index 00000000..89cb2214 --- /dev/null +++ b/src/core/operations/ChiSquare.mjs @@ -0,0 +1,53 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Chi Square operation + */ +class ChiSquare extends Operation { + + /** + * ChiSquare constructor + */ + constructor() { + super(); + + this.name = "Chi Square"; + this.module = "Default"; + this.description = "Calculates the Chi Square distribution of values."; + this.inputType = "ArrayBuffer"; + this.outputType = "number"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {number} + */ + run(input, args) { + const data = new Uint8Array(input); + const distArray = new Array(256).fill(0); + let total = 0; + + for (let i = 0; i < data.length; i++) { + distArray[data[i]]++; + } + + for (let i = 0; i < distArray.length; i++) { + if (distArray[i] > 0) { + total += Math.pow(distArray[i] - data.length / 256, 2) / (data.length / 256); + } + } + + return total; + } + +} + +export default ChiSquare; diff --git a/src/core/operations/Comment.mjs b/src/core/operations/Comment.mjs new file mode 100644 index 00000000..2c941089 --- /dev/null +++ b/src/core/operations/Comment.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Comment operation + */ +class Comment extends Operation { + + /** + * Comment constructor + */ + constructor() { + super(); + + this.name = "Comment"; + this.flowControl = true; + this.module = "Default"; + this.description = "Provides a place to write comments within the flow of the recipe. This operation has no computational effect."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "", + "type": "text", + "value": "" + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + run(state) { + return state; + } + +} + +export default Comment; diff --git a/src/core/operations/CompareCTPHHashes.mjs b/src/core/operations/CompareCTPHHashes.mjs new file mode 100644 index 00000000..7194d89f --- /dev/null +++ b/src/core/operations/CompareCTPHHashes.mjs @@ -0,0 +1,51 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {HASH_DELIM_OPTIONS} from "../lib/Delim"; +import ctphjs from "ctph.js"; +import OperationError from "../errors/OperationError"; + +/** + * Compare CTPH hashes operation + */ +class CompareCTPHHashes extends Operation { + + /** + * CompareCTPHHashes constructor + */ + constructor() { + super(); + + this.name = "Compare CTPH hashes"; + this.module = "Hashing"; + this.description = "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100."; + this.inputType = "string"; + this.outputType = "Number"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": HASH_DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {Number} + */ + run(input, args) { + const samples = input.split(Utils.charRep(args[0])); + if (samples.length !== 2) throw new OperationError("Incorrect number of samples."); + return ctphjs.similarity(samples[0], samples[1]); + } + +} + +export default CompareCTPHHashes; diff --git a/src/core/operations/CompareSSDEEPHashes.mjs b/src/core/operations/CompareSSDEEPHashes.mjs new file mode 100644 index 00000000..aa39d5cf --- /dev/null +++ b/src/core/operations/CompareSSDEEPHashes.mjs @@ -0,0 +1,51 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {HASH_DELIM_OPTIONS} from "../lib/Delim"; +import ssdeepjs from "ssdeep.js"; +import OperationError from "../errors/OperationError"; + +/** + * Compare SSDEEP hashes operation + */ +class CompareSSDEEPHashes extends Operation { + + /** + * CompareSSDEEPHashes constructor + */ + constructor() { + super(); + + this.name = "Compare SSDEEP hashes"; + this.module = "Hashing"; + this.description = "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100."; + this.inputType = "string"; + this.outputType = "Number"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": HASH_DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {Number} + */ + run(input, args) { + const samples = input.split(Utils.charRep(args[0])); + if (samples.length !== 2) throw new OperationError("Incorrect number of samples."); + return ssdeepjs.similarity(samples[0], samples[1]); + } + +} + +export default CompareSSDEEPHashes; diff --git a/src/core/operations/ConditionalJump.mjs b/src/core/operations/ConditionalJump.mjs new file mode 100644 index 00000000..d102ea72 --- /dev/null +++ b/src/core/operations/ConditionalJump.mjs @@ -0,0 +1,84 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Dish from "../Dish"; +import { getLabelIndex } from "../lib/FlowControl"; + +/** + * Conditional Jump operation + */ +class ConditionalJump extends Operation { + + /** + * ConditionalJump constructor + */ + constructor() { + super(); + + this.name = "Conditional Jump"; + this.flowControl = true; + this.module = "Default"; + this.description = "Conditionally jump forwards or backwards to the specified Label based on whether the data matches the specified regular expression."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Match (regex)", + "type": "string", + "value": "" + }, + { + "name": "Invert match", + "type": "boolean", + "value": false + }, + { + "name": "Label name", + "type": "shortString", + "value": "" + }, + { + "name": "Maximum jumps (if jumping backwards)", + "type": "number", + "value": 10 + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @param {number} state.numJumps - The number of jumps taken so far. + * @returns {Object} The updated state of the recipe. + */ + async run(state) { + const ings = state.opList[state.progress].ingValues, + dish = state.dish, + [regexStr, invert, label, maxJumps] = ings, + jmpIndex = getLabelIndex(label, state); + + if (state.numJumps >= maxJumps || jmpIndex === -1) { + return state; + } + + if (regexStr !== "") { + const str = await dish.get(Dish.STRING); + const strMatch = str.search(regexStr) > -1; + if (!invert && strMatch || invert && !strMatch) { + state.progress = jmpIndex; + state.numJumps++; + } + } + + return state; + } + +} + +export default ConditionalJump; diff --git a/src/core/operations/ConvertArea.mjs b/src/core/operations/ConvertArea.mjs new file mode 100644 index 00000000..dd88f52e --- /dev/null +++ b/src/core/operations/ConvertArea.mjs @@ -0,0 +1,112 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Convert area operation + */ +class ConvertArea extends Operation { + + /** + * ConvertArea constructor + */ + constructor() { + super(); + + this.name = "Convert area"; + this.module = "Default"; + this.description = "Converts a unit of area to another format."; + this.inputType = "BigNumber"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": AREA_UNITS + }, + { + "name": "Output units", + "type": "option", + "value": AREA_UNITS + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const [inputUnits, outputUnits] = args; + + input = input.times(AREA_FACTOR[inputUnits]); + return input.div(AREA_FACTOR[outputUnits]); + } + +} + + +const AREA_UNITS = [ + "[Metric]", "Square metre (sq m)", "Square kilometre (sq km)", "Centiare (ca)", "Deciare (da)", "Are (a)", "Decare (daa)", "Hectare (ha)", "[/Metric]", + "[Imperial]", "Square inch (sq in)", "Square foot (sq ft)", "Square yard (sq yd)", "Square mile (sq mi)", "Perch (sq per)", "Rood (ro)", "International acre (ac)", "[/Imperial]", + "[US customary units]", "US survey acre (ac)", "US survey square mile (sq mi)", "US survey township", "[/US customary units]", + "[Nuclear physics]", "Yoctobarn (yb)", "Zeptobarn (zb)", "Attobarn (ab)", "Femtobarn (fb)", "Picobarn (pb)", "Nanobarn (nb)", "Microbarn (μb)", "Millibarn (mb)", "Barn (b)", "Kilobarn (kb)", "Megabarn (Mb)", "Outhouse", "Shed", "Planck area", "[/Nuclear physics]", + "[Comparisons]", "Washington D.C.", "Isle of Wight", "Wales", "Texas", "[/Comparisons]", +]; + +const AREA_FACTOR = { // Multiples of a square metre + // Metric + "Square metre (sq m)": 1, + "Square kilometre (sq km)": 1e6, + + "Centiare (ca)": 1, + "Deciare (da)": 10, + "Are (a)": 100, + "Decare (daa)": 1e3, + "Hectare (ha)": 1e4, + + // Imperial + "Square inch (sq in)": 0.00064516, + "Square foot (sq ft)": 0.09290304, + "Square yard (sq yd)": 0.83612736, + "Square mile (sq mi)": 2589988.110336, + "Perch (sq per)": 42.21, + "Rood (ro)": 1011, + "International acre (ac)": 4046.8564224, + + // US customary units + "US survey acre (ac)": 4046.87261, + "US survey square mile (sq mi)": 2589998.470305239, + "US survey township": 93239944.9309886, + + // Nuclear physics + "Yoctobarn (yb)": 1e-52, + "Zeptobarn (zb)": 1e-49, + "Attobarn (ab)": 1e-46, + "Femtobarn (fb)": 1e-43, + "Picobarn (pb)": 1e-40, + "Nanobarn (nb)": 1e-37, + "Microbarn (μb)": 1e-34, + "Millibarn (mb)": 1e-31, + "Barn (b)": 1e-28, + "Kilobarn (kb)": 1e-25, + "Megabarn (Mb)": 1e-22, + + "Planck area": 2.6e-70, + "Shed": 1e-52, + "Outhouse": 1e-34, + + // Comparisons + "Washington D.C.": 176119191.502848, + "Isle of Wight": 380000000, + "Wales": 20779000000, + "Texas": 696241000000, +}; + + +export default ConvertArea; diff --git a/src/core/operations/ConvertDataUnits.mjs b/src/core/operations/ConvertDataUnits.mjs new file mode 100644 index 00000000..dc22e351 --- /dev/null +++ b/src/core/operations/ConvertDataUnits.mjs @@ -0,0 +1,111 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Convert data units operation + */ +class ConvertDataUnits extends Operation { + + /** + * ConvertDataUnits constructor + */ + constructor() { + super(); + + this.name = "Convert data units"; + this.module = "Default"; + this.description = "Converts a unit of data to another format."; + this.inputType = "BigNumber"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": DATA_UNITS + }, + { + "name": "Output units", + "type": "option", + "value": DATA_UNITS + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const [inputUnits, outputUnits] = args; + + input = input.times(DATA_FACTOR[inputUnits]); + return input.div(DATA_FACTOR[outputUnits]); + } + +} + +const DATA_UNITS = [ + "Bits (b)", "Nibbles", "Octets", "Bytes (B)", + "[Binary bits (2^n)]", "Kibibits (Kib)", "Mebibits (Mib)", "Gibibits (Gib)", "Tebibits (Tib)", "Pebibits (Pib)", "Exbibits (Eib)", "Zebibits (Zib)", "Yobibits (Yib)", "[/Binary bits (2^n)]", + "[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]", + "[Binary bytes (8 x 2^n)]", "Kibibytes (KiB)", "Mebibytes (MiB)", "Gibibytes (GiB)", "Tebibytes (TiB)", "Pebibytes (PiB)", "Exbibytes (EiB)", "Zebibytes (ZiB)", "Yobibytes (YiB)", "[/Binary bytes (8 x 2^n)]", + "[Decimal bytes (8 x 10^n)]", "Kilobytes (KB)", "Megabytes (MB)", "Gigabytes (GB)", "Terabytes (TB)", "Petabytes (PB)", "Exabytes (EB)", "Zettabytes (ZB)", "Yottabytes (YB)", "[/Decimal bytes (8 x 10^n)]" +]; + +const DATA_FACTOR = { // Multiples of a bit + "Bits (b)": 1, + "Nibbles": 4, + "Octets": 8, + "Bytes (B)": 8, + + // Binary bits (2^n) + "Kibibits (Kib)": 1024, + "Mebibits (Mib)": 1048576, + "Gibibits (Gib)": 1073741824, + "Tebibits (Tib)": 1099511627776, + "Pebibits (Pib)": 1125899906842624, + "Exbibits (Eib)": 1152921504606846976, + "Zebibits (Zib)": 1180591620717411303424, + "Yobibits (Yib)": 1208925819614629174706176, + + // Decimal bits (10^n) + "Decabits": 10, + "Hectobits": 100, + "Kilobits (Kb)": 1e3, + "Megabits (Mb)": 1e6, + "Gigabits (Gb)": 1e9, + "Terabits (Tb)": 1e12, + "Petabits (Pb)": 1e15, + "Exabits (Eb)": 1e18, + "Zettabits (Zb)": 1e21, + "Yottabits (Yb)": 1e24, + + // Binary bytes (8 x 2^n) + "Kibibytes (KiB)": 8192, + "Mebibytes (MiB)": 8388608, + "Gibibytes (GiB)": 8589934592, + "Tebibytes (TiB)": 8796093022208, + "Pebibytes (PiB)": 9007199254740992, + "Exbibytes (EiB)": 9223372036854775808, + "Zebibytes (ZiB)": 9444732965739290427392, + "Yobibytes (YiB)": 9671406556917033397649408, + + // Decimal bytes (8 x 10^n) + "Kilobytes (KB)": 8e3, + "Megabytes (MB)": 8e6, + "Gigabytes (GB)": 8e9, + "Terabytes (TB)": 8e12, + "Petabytes (PB)": 8e15, + "Exabytes (EB)": 8e18, + "Zettabytes (ZB)": 8e21, + "Yottabytes (YB)": 8e24, +}; + + +export default ConvertDataUnits; diff --git a/src/core/operations/ConvertDistance.mjs b/src/core/operations/ConvertDistance.mjs new file mode 100644 index 00000000..278a1c6d --- /dev/null +++ b/src/core/operations/ConvertDistance.mjs @@ -0,0 +1,95 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Convert distance operation + */ +class ConvertDistance extends Operation { + + /** + * ConvertDistance constructor + */ + constructor() { + super(); + + this.name = "Convert distance"; + this.module = "Default"; + this.description = "Converts a unit of distance to another format."; + this.inputType = "BigNumber"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": DISTANCE_UNITS + }, + { + "name": "Output units", + "type": "option", + "value": DISTANCE_UNITS + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const [inputUnits, outputUnits] = args; + + input = input.times(DISTANCE_FACTOR[inputUnits]); + return input.div(DISTANCE_FACTOR[outputUnits]); + } + +} + +const DISTANCE_UNITS = [ + "[Metric]", "Nanometres (nm)", "Micrometres (µm)", "Millimetres (mm)", "Centimetres (cm)", "Metres (m)", "Kilometers (km)", "[/Metric]", + "[Imperial]", "Thou (th)", "Inches (in)", "Feet (ft)", "Yards (yd)", "Chains (ch)", "Furlongs (fur)", "Miles (mi)", "Leagues (lea)", "[/Imperial]", + "[Maritime]", "Fathoms (ftm)", "Cables", "Nautical miles", "[/Maritime]", + "[Comparisons]", "Cars (4m)", "Buses (8.4m)", "American football fields (91m)", "Football pitches (105m)", "[/Comparisons]", + "[Astronomical]", "Earth-to-Moons", "Earth's equators", "Astronomical units (au)", "Light-years (ly)", "Parsecs (pc)", "[/Astronomical]", +]; + +const DISTANCE_FACTOR = { // Multiples of a metre + "Nanometres (nm)": 1e-9, + "Micrometres (µm)": 1e-6, + "Millimetres (mm)": 1e-3, + "Centimetres (cm)": 1e-2, + "Metres (m)": 1, + "Kilometers (km)": 1e3, + + "Thou (th)": 0.0000254, + "Inches (in)": 0.0254, + "Feet (ft)": 0.3048, + "Yards (yd)": 0.9144, + "Chains (ch)": 20.1168, + "Furlongs (fur)": 201.168, + "Miles (mi)": 1609.344, + "Leagues (lea)": 4828.032, + + "Fathoms (ftm)": 1.853184, + "Cables": 185.3184, + "Nautical miles": 1853.184, + + "Cars (4m)": 4, + "Buses (8.4m)": 8.4, + "American football fields (91m)": 91, + "Football pitches (105m)": 105, + + "Earth-to-Moons": 380000000, + "Earth's equators": 40075016.686, + "Astronomical units (au)": 149597870700, + "Light-years (ly)": 9460730472580800, + "Parsecs (pc)": 3.0856776e16 +}; + + +export default ConvertDistance; diff --git a/src/core/operations/ConvertMass.mjs b/src/core/operations/ConvertMass.mjs new file mode 100644 index 00000000..18c0c84a --- /dev/null +++ b/src/core/operations/ConvertMass.mjs @@ -0,0 +1,143 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Convert mass operation + */ +class ConvertMass extends Operation { + + /** + * ConvertMass constructor + */ + constructor() { + super(); + + this.name = "Convert mass"; + this.module = "Default"; + this.description = "Converts a unit of mass to another format."; + this.inputType = "BigNumber"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": MASS_UNITS + }, + { + "name": "Output units", + "type": "option", + "value": MASS_UNITS + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const [inputUnits, outputUnits] = args; + + input = input.times(MASS_FACTOR[inputUnits]); + return input.div(MASS_FACTOR[outputUnits]); + } + +} + + +const MASS_UNITS = [ + "[Metric]", "Yoctogram (yg)", "Zeptogram (zg)", "Attogram (ag)", "Femtogram (fg)", "Picogram (pg)", "Nanogram (ng)", "Microgram (μg)", "Milligram (mg)", "Centigram (cg)", "Decigram (dg)", "Gram (g)", "Decagram (dag)", "Hectogram (hg)", "Kilogram (kg)", "Megagram (Mg)", "Tonne (t)", "Gigagram (Gg)", "Teragram (Tg)", "Petagram (Pg)", "Exagram (Eg)", "Zettagram (Zg)", "Yottagram (Yg)", "[/Metric]", + "[Imperial Avoirdupois]", "Grain (gr)", "Dram (dr)", "Ounce (oz)", "Pound (lb)", "Nail", "Stone (st)", "Quarter (gr)", "Tod", "US hundredweight (cwt)", "Imperial hundredweight (cwt)", "US ton (t)", "Imperial ton (t)", "[/Imperial Avoirdupois]", + "[Imperial Troy]", "Grain (gr)", "Pennyweight (dwt)", "Troy dram (dr t)", "Troy ounce (oz t)", "Troy pound (lb t)", "Mark", "[/Imperial Troy]", + "[Archaic]", "Wey", "Wool wey", "Suffolk wey", "Wool sack", "Coal sack", "Load", "Last", "Flax or feather last", "Gunpowder last", "Picul", "Rice last", "[/Archaic]", + "[Comparisons]", "Big Ben (14 tonnes)", "Blue whale (180 tonnes)", "International Space Station (417 tonnes)", "Space Shuttle (2,041 tonnes)", "RMS Titanic (52,000 tonnes)", "Great Pyramid of Giza (6,000,000 tonnes)", "Earth's oceans (1.4 yottagrams)", "[/Comparisons]", + "[Astronomical]", "A teaspoon of neutron star (5,500 million tonnes)", "Lunar mass (ML)", "Earth mass (M⊕)", "Jupiter mass (MJ)", "Solar mass (M☉)", "Sagittarius A* (7.5 x 10^36 kgs-ish)", "Milky Way galaxy (1.2 x 10^42 kgs)", "The observable universe (1.45 x 10^53 kgs)", "[/Astronomical]", +]; + +const MASS_FACTOR = { // Multiples of a gram + // Metric + "Yoctogram (yg)": 1e-24, + "Zeptogram (zg)": 1e-21, + "Attogram (ag)": 1e-18, + "Femtogram (fg)": 1e-15, + "Picogram (pg)": 1e-12, + "Nanogram (ng)": 1e-9, + "Microgram (μg)": 1e-6, + "Milligram (mg)": 1e-3, + "Centigram (cg)": 1e-2, + "Decigram (dg)": 1e-1, + "Gram (g)": 1, + "Decagram (dag)": 10, + "Hectogram (hg)": 100, + "Kilogram (kg)": 1000, + "Megagram (Mg)": 1e6, + "Tonne (t)": 1e6, + "Gigagram (Gg)": 1e9, + "Teragram (Tg)": 1e12, + "Petagram (Pg)": 1e15, + "Exagram (Eg)": 1e18, + "Zettagram (Zg)": 1e21, + "Yottagram (Yg)": 1e24, + + // Imperial Avoirdupois + "Grain (gr)": 64.79891e-3, + "Dram (dr)": 1.7718451953125, + "Ounce (oz)": 28.349523125, + "Pound (lb)": 453.59237, + "Nail": 3175.14659, + "Stone (st)": 6.35029318e3, + "Quarter (gr)": 12700.58636, + "Tod": 12700.58636, + "US hundredweight (cwt)": 45.359237e3, + "Imperial hundredweight (cwt)": 50.80234544e3, + "US ton (t)": 907.18474e3, + "Imperial ton (t)": 1016.0469088e3, + + // Imperial Troy + "Pennyweight (dwt)": 1.55517384, + "Troy dram (dr t)": 3.8879346, + "Troy ounce (oz t)": 31.1034768, + "Troy pound (lb t)": 373.2417216, + "Mark": 248.8278144, + + // Archaic + "Wey": 76.5e3, + "Wool wey": 101.7e3, + "Suffolk wey": 161.5e3, + "Wool sack": 153000, + "Coal sack": 50.80234544e3, + "Load": 918000, + "Last": 1836000, + "Flax or feather last": 770e3, + "Gunpowder last": 1090e3, + "Picul": 60.478982e3, + "Rice last": 1200e3, + + // Comparisons + "Big Ben (14 tonnes)": 14e6, + "Blue whale (180 tonnes)": 180e6, + "International Space Station (417 tonnes)": 417e6, + "Space Shuttle (2,041 tonnes)": 2041e6, + "RMS Titanic (52,000 tonnes)": 52000e6, + "Great Pyramid of Giza (6,000,000 tonnes)": 6e12, + "Earth's oceans (1.4 yottagrams)": 1.4e24, + + // Astronomical + "A teaspoon of neutron star (5,500 million tonnes)": 5.5e15, + "Lunar mass (ML)": 7.342e25, + "Earth mass (M⊕)": 5.97219e27, + "Jupiter mass (MJ)": 1.8981411476999997e30, + "Solar mass (M☉)": 1.98855e33, + "Sagittarius A* (7.5 x 10^36 kgs-ish)": 7.5e39, + "Milky Way galaxy (1.2 x 10^42 kgs)": 1.2e45, + "The observable universe (1.45 x 10^53 kgs)": 1.45e56, +}; + + +export default ConvertMass; diff --git a/src/core/operations/ConvertSpeed.mjs b/src/core/operations/ConvertSpeed.mjs new file mode 100644 index 00000000..71c43a54 --- /dev/null +++ b/src/core/operations/ConvertSpeed.mjs @@ -0,0 +1,96 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Convert speed operation + */ +class ConvertSpeed extends Operation { + + /** + * ConvertSpeed constructor + */ + constructor() { + super(); + + this.name = "Convert speed"; + this.module = "Default"; + this.description = "Converts a unit of speed to another format."; + this.inputType = "BigNumber"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": SPEED_UNITS + }, + { + "name": "Output units", + "type": "option", + "value": SPEED_UNITS + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const [inputUnits, outputUnits] = args; + + input = input.times(SPEED_FACTOR[inputUnits]); + return input.div(SPEED_FACTOR[outputUnits]); + } + +} + +const SPEED_UNITS = [ + "[Metric]", "Metres per second (m/s)", "Kilometres per hour (km/h)", "[/Metric]", + "[Imperial]", "Miles per hour (mph)", "Knots (kn)", "[/Imperial]", + "[Comparisons]", "Human hair growth rate", "Bamboo growth rate", "World's fastest snail", "Usain Bolt's top speed", "Jet airliner cruising speed", "Concorde", "SR-71 Blackbird", "Space Shuttle", "International Space Station", "[/Comparisons]", + "[Scientific]", "Sound in standard atmosphere", "Sound in water", "Lunar escape velocity", "Earth escape velocity", "Earth's solar orbit", "Solar system's Milky Way orbit", "Milky Way relative to the cosmic microwave background", "Solar escape velocity", "Neutron star escape velocity (0.3c)", "Light in a diamond (0.4136c)", "Signal in an optical fibre (0.667c)", "Light (c)", "[/Scientific]", +]; + +const SPEED_FACTOR = { // Multiples of m/s + // Metric + "Metres per second (m/s)": 1, + "Kilometres per hour (km/h)": 0.2778, + + // Imperial + "Miles per hour (mph)": 0.44704, + "Knots (kn)": 0.5144, + + // Comparisons + "Human hair growth rate": 4.8e-9, + "Bamboo growth rate": 1.4e-5, + "World's fastest snail": 0.00275, + "Usain Bolt's top speed": 12.42, + "Jet airliner cruising speed": 250, + "Concorde": 603, + "SR-71 Blackbird": 981, + "Space Shuttle": 1400, + "International Space Station": 7700, + + // Scientific + "Sound in standard atmosphere": 340.3, + "Sound in water": 1500, + "Lunar escape velocity": 2375, + "Earth escape velocity": 11200, + "Earth's solar orbit": 29800, + "Solar system's Milky Way orbit": 200000, + "Milky Way relative to the cosmic microwave background": 552000, + "Solar escape velocity": 617700, + "Neutron star escape velocity (0.3c)": 100000000, + "Light in a diamond (0.4136c)": 124000000, + "Signal in an optical fibre (0.667c)": 200000000, + "Light (c)": 299792458, +}; + + +export default ConvertSpeed; diff --git a/src/core/operations/CountOccurrences.mjs b/src/core/operations/CountOccurrences.mjs new file mode 100644 index 00000000..5027a0f0 --- /dev/null +++ b/src/core/operations/CountOccurrences.mjs @@ -0,0 +1,65 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Count occurrences operation + */ +class CountOccurrences extends Operation { + + /** + * CountOccurrences constructor + */ + constructor() { + super(); + + this.name = "Count occurrences"; + this.module = "Default"; + this.description = "Counts the number of times the provided string occurs in the input."; + this.inputType = "string"; + this.outputType = "number"; + this.args = [ + { + "name": "Search string", + "type": "toggleString", + "value": "", + "toggleValues": ["Regex", "Extended (\\n, \\t, \\x...)", "Simple string"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + run(input, args) { + let search = args[0].string; + const type = args[0].option; + + if (type === "Regex" && search) { + try { + const regex = new RegExp(search, "gi"), + matches = input.match(regex); + return matches.length; + } catch (err) { + return 0; + } + } else if (search) { + if (type.indexOf("Extended") === 0) { + search = Utils.parseEscapedChars(search); + } + return input.count(search); + } else { + return 0; + } + } + +} + +export default CountOccurrences; diff --git a/src/core/operations/DecodeNetBIOSName.mjs b/src/core/operations/DecodeNetBIOSName.mjs new file mode 100644 index 00000000..19624889 --- /dev/null +++ b/src/core/operations/DecodeNetBIOSName.mjs @@ -0,0 +1,59 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Decode NetBIOS Name operation + */ +class DecodeNetBIOSName extends Operation { + + /** + * DecodeNetBIOSName constructor + */ + constructor() { + super(); + + this.name = "Decode NetBIOS Name"; + this.module = "Default"; + this.description = "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation decodes the first level of encoding. See RFC 1001 for full details."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Offset", + "type": "number", + "value": 65 + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const output = [], + offset = args[0]; + + if (input.length <= 32 && (input.length % 2) === 0) { + for (let i = 0; i < input.length; i += 2) { + output.push((((input[i] & 0xff) - offset) << 4) | + (((input[i + 1] & 0xff) - offset) & 0xf)); + } + for (let i = output.length - 1; i > 0; i--) { + if (output[i] === 32) output.splice(i, i); + else break; + } + } + + return output; + } + +} + +export default DecodeNetBIOSName; diff --git a/src/core/operations/DecodeText.mjs b/src/core/operations/DecodeText.mjs new file mode 100644 index 00000000..9e51199f --- /dev/null +++ b/src/core/operations/DecodeText.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import cptable from "../vendor/js-codepage/cptable.js"; +import {IO_FORMAT} from "../lib/ChrEnc"; + +/** + * Decode text operation + */ +class DecodeText extends Operation { + + /** + * DecodeText constructor + */ + constructor() { + super(); + + this.name = "Decode text"; + this.module = "CharEnc"; + this.description = [ + "Decodes text from the chosen character encoding.", + "

", + "Supported charsets are:", + "
    ", + Object.keys(IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n"), + "
", + ].join("\n"); + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Encoding", + "type": "option", + "value": Object.keys(IO_FORMAT) + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const format = IO_FORMAT[args[0]]; + return cptable.utils.decode(format, input); + } + +} + +export default DecodeText; diff --git a/src/core/operations/DeriveEVPKey.mjs b/src/core/operations/DeriveEVPKey.mjs new file mode 100644 index 00000000..ad17f0b1 --- /dev/null +++ b/src/core/operations/DeriveEVPKey.mjs @@ -0,0 +1,144 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import CryptoJS from "crypto-js"; + +/** + * Derive EVP key operation + */ +class DeriveEVPKey extends Operation { + + /** + * DeriveEVPKey constructor + */ + constructor() { + super(); + + this.name = "Derive EVP key"; + this.module = "Ciphers"; + this.description = "EVP is a password-based key derivation function (PBKDF) used extensively in OpenSSL. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Passphrase", + "type": "toggleString", + "value": "", + "toggleValues": ["UTF8", "Latin1", "Hex", "Base64"] + }, + { + "name": "Key size", + "type": "number", + "value": 128 + }, + { + "name": "Iterations", + "type": "number", + "value": 1 + }, + { + "name": "Hashing function", + "type": "option", + "value": ["SHA1", "SHA256", "SHA384", "SHA512", "MD5"] + }, + { + "name": "Salt", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const passphrase = Utils.convertToByteString(args[0].string, args[0].option), + keySize = args[1] / 32, + iterations = args[2], + hasher = args[3], + salt = Utils.convertToByteString(args[4].string, args[4].option), + key = CryptoJS.EvpKDF(passphrase, salt, { + keySize: keySize, + hasher: CryptoJS.algo[hasher], + iterations: iterations, + }); + + return key.toString(CryptoJS.enc.Hex); + } + +} + +export default DeriveEVPKey; + +/** + * Overwriting the CryptoJS OpenSSL key derivation function so that it is possible to not pass a + * salt in. + + * @param {string} password - The password to derive from. + * @param {number} keySize - The size in words of the key to generate. + * @param {number} ivSize - The size in words of the IV to generate. + * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be + * generated randomly. If set to false, no salt will be added. + * + * @returns {CipherParams} A cipher params object with the key, IV, and salt. + * + * @static + * + * @example + * // Randomly generates a salt + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); + * // Uses the salt 'saltsalt' + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); + * // Does not use a salt + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, false); + */ +CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) { + // Generate random salt if no salt specified and not set to false + // This line changed from `if (!salt) {` to the following + if (salt === undefined || salt === null) { + salt = CryptoJS.lib.WordArray.random(64/8); + } + + // Derive key and IV + const key = CryptoJS.algo.EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); + + // Separate key and IV + const iv = CryptoJS.lib.WordArray.create(key.words.slice(keySize), ivSize * 4); + key.sigBytes = keySize * 4; + + // Return params + return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt }); +}; + + +/** + * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse + * the hex string. + * + * @param {string} hexStr + * @returns {CryptoJS.lib.WordArray} + */ +CryptoJS.enc.Hex.parse = function (hexStr) { + // Remove whitespace + hexStr = hexStr.replace(/\s/g, ""); + + // Shortcut + const hexStrLength = hexStr.length; + + // Convert + const words = []; + for (let i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2); +}; diff --git a/src/core/operations/DetectFileType.mjs b/src/core/operations/DetectFileType.mjs new file mode 100644 index 00000000..ddf9a2de --- /dev/null +++ b/src/core/operations/DetectFileType.mjs @@ -0,0 +1,54 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Magic from "../lib/Magic"; + +/** + * Detect File Type operation + */ +class DetectFileType extends Operation { + + /** + * DetectFileType constructor + */ + constructor() { + super(); + + this.name = "Detect File Type"; + this.module = "Default"; + this.description = "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.

Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const data = new Uint8Array(input), + type = Magic.magicFileType(data); + + if (!type) { + return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?"; + } else { + let output = "File extension: " + type.ext + "\n" + + "MIME type: " + type.mime; + + if (type.desc && type.desc.length) { + output += "\nDescription: " + type.desc; + } + + return output; + } + } + +} + +export default DetectFileType; diff --git a/src/core/operations/Diff.mjs b/src/core/operations/Diff.mjs new file mode 100644 index 00000000..6627cf6e --- /dev/null +++ b/src/core/operations/Diff.mjs @@ -0,0 +1,124 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import * as JsDiff from "diff"; +import OperationError from "../errors/OperationError"; + +/** + * Diff operation + */ +class Diff extends Operation { + + /** + * Diff constructor + */ + constructor() { + super(); + + this.name = "Diff"; + this.module = "Diff"; + this.description = "Compares two inputs (separated by the specified delimiter) and highlights the differences between them."; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + "name": "Sample delimiter", + "type": "binaryString", + "value": "\\n\\n" + }, + { + "name": "Diff by", + "type": "option", + "value": ["Character", "Word", "Line", "Sentence", "CSS", "JSON"] + }, + { + "name": "Show added", + "type": "boolean", + "value": true + }, + { + "name": "Show removed", + "type": "boolean", + "value": true + }, + { + "name": "Ignore whitespace (relevant for word and line)", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const [ + sampleDelim, + diffBy, + showAdded, + showRemoved, + ignoreWhitespace + ] = args, + samples = input.split(sampleDelim); + let output = "", + diff; + + if (!samples || samples.length !== 2) { + throw new OperationError("Incorrect number of samples, perhaps you need to modify the sample delimiter or add more samples?"); + } + + switch (diffBy) { + case "Character": + diff = JsDiff.diffChars(samples[0], samples[1]); + break; + case "Word": + if (ignoreWhitespace) { + diff = JsDiff.diffWords(samples[0], samples[1]); + } else { + diff = JsDiff.diffWordsWithSpace(samples[0], samples[1]); + } + break; + case "Line": + if (ignoreWhitespace) { + diff = JsDiff.diffTrimmedLines(samples[0], samples[1]); + } else { + diff = JsDiff.diffLines(samples[0], samples[1]); + } + break; + case "Sentence": + diff = JsDiff.diffSentences(samples[0], samples[1]); + break; + case "CSS": + diff = JsDiff.diffCss(samples[0], samples[1]); + break; + case "JSON": + diff = JsDiff.diffJson(samples[0], samples[1]); + break; + default: + throw new OperationError("Invalid 'Diff by' option."); + } + + for (let i = 0; i < diff.length; i++) { + if (diff[i].added) { + if (showAdded) output += "" + Utils.escapeHtml(diff[i].value) + ""; + } else if (diff[i].removed) { + if (showRemoved) output += "" + Utils.escapeHtml(diff[i].value) + ""; + } else { + output += Utils.escapeHtml(diff[i].value); + } + } + + return output; + } + +} + +export default Diff; diff --git a/src/core/operations/DisassembleX86.mjs b/src/core/operations/DisassembleX86.mjs new file mode 100644 index 00000000..c64039bb --- /dev/null +++ b/src/core/operations/DisassembleX86.mjs @@ -0,0 +1,133 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import * as disassemble from "../vendor/DisassembleX86-64"; +import OperationError from "../errors/OperationError"; + +/** + * Disassemble x86 operation + */ +class DisassembleX86 extends Operation { + + /** + * DisassembleX86 constructor + */ + constructor() { + super(); + + this.name = "Disassemble x86"; + this.module = "Shellcode"; + this.description = "Disassembly is the process of translating machine language into assembly language.

This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.

Input should be in hexadecimal."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Bit mode", + "type": "option", + "value": ["64", "32", "16"] + }, + { + "name": "Compatibility", + "type": "option", + "value": [ + "Full x86 architecture", + "Knights Corner", + "Larrabee", + "Cyrix", + "Geode", + "Centaur", + "X86/486" + ] + }, + { + "name": "Code Segment (CS)", + "type": "number", + "value": 16 + }, + { + "name": "Offset (IP)", + "type": "number", + "value": 0 + }, + { + "name": "Show instruction hex", + "type": "boolean", + "value": true + }, + { + "name": "Show instruction position", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if invalid mode value + */ + run(input, args) { + const [ + mode, + compatibility, + codeSegment, + offset, + showInstructionHex, + showInstructionPos + ] = args; + + switch (mode) { + case "64": + disassemble.setBitMode(2); + break; + case "32": + disassemble.setBitMode(1); + break; + case "16": + disassemble.setBitMode(0); + break; + default: + throw new OperationError("Invalid mode value"); + } + + switch (compatibility) { + case "Full x86 architecture": + disassemble.CompatibilityMode(0); + break; + case "Knights Corner": + disassemble.CompatibilityMode(1); + break; + case "Larrabee": + disassemble.CompatibilityMode(2); + break; + case "Cyrix": + disassemble.CompatibilityMode(3); + break; + case "Geode": + disassemble.CompatibilityMode(4); + break; + case "Centaur": + disassemble.CompatibilityMode(5); + break; + case "X86/486": + disassemble.CompatibilityMode(6); + break; + } + + disassemble.SetBasePosition(codeSegment + ":" + offset); + disassemble.setShowInstructionHex(showInstructionHex); + disassemble.setShowInstructionPos(showInstructionPos); + disassemble.LoadBinCode(input.replace(/\s/g, "")); + return disassemble.LDisassemble(); + } + +} + +export default DisassembleX86; diff --git a/src/core/operations/Divide.mjs b/src/core/operations/Divide.mjs new file mode 100644 index 00000000..76f50313 --- /dev/null +++ b/src/core/operations/Divide.mjs @@ -0,0 +1,51 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { div, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + + +/** + * Divide operation + */ +class Divide extends Operation { + + /** + * Divide constructor + */ + constructor() { + super(); + + this.name = "Divide"; + this.module = "Default"; + this.description = "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 2.5"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = div(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Divide; diff --git a/src/core/operations/DropBytes.mjs b/src/core/operations/DropBytes.mjs new file mode 100644 index 00000000..e697f4e9 --- /dev/null +++ b/src/core/operations/DropBytes.mjs @@ -0,0 +1,95 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Drop bytes operation + */ +class DropBytes extends Operation { + + /** + * DropBytes constructor + */ + constructor() { + super(); + + this.name = "Drop bytes"; + this.module = "Default"; + this.description = "Cuts a slice of the specified number of bytes out of the data."; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = [ + { + "name": "Start", + "type": "number", + "value": 0 + }, + { + "name": "Length", + "type": "number", + "value": 5 + }, + { + "name": "Apply to each line", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + * + * @throws {OperationError} if invalid input + */ + run(input, args) { + const start = args[0], + length = args[1], + applyToEachLine = args[2]; + + if (start < 0 || length < 0) + throw new OperationError("Error: Invalid value"); + + if (!applyToEachLine) { + const left = input.slice(0, start), + right = input.slice(start + length, input.byteLength); + const result = new Uint8Array(left.byteLength + right.byteLength); + result.set(new Uint8Array(left), 0); + result.set(new Uint8Array(right), left.byteLength); + return result.buffer; + } + + // Split input into lines + const data = new Uint8Array(input); + const lines = []; + let line = [], + i; + + for (i = 0; i < data.length; i++) { + if (data[i] === 0x0a) { + lines.push(line); + line = []; + } else { + line.push(data[i]); + } + } + lines.push(line); + + let output = []; + for (i = 0; i < lines.length; i++) { + output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length))); + output.push(0x0a); + } + return new Uint8Array(output.slice(0, output.length-1)).buffer; + } + +} + +export default DropBytes; diff --git a/src/core/operations/EncodeNetBIOSName.mjs b/src/core/operations/EncodeNetBIOSName.mjs new file mode 100644 index 00000000..608f4bfd --- /dev/null +++ b/src/core/operations/EncodeNetBIOSName.mjs @@ -0,0 +1,59 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Encode NetBIOS Name operation + */ +class EncodeNetBIOSName extends Operation { + + /** + * EncodeNetBIOSName constructor + */ + constructor() { + super(); + + this.name = "Encode NetBIOS Name"; + this.module = "Default"; + this.description = "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation carries out the first level of encoding. See RFC 1001 for full details."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Offset", + "type": "number", + "value": 65 + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const output = [], + offset = args[0]; + + if (input.length <= 16) { + const len = input.length; + input.length = 16; + input.fill(32, len, 16); + for (let i = 0; i < input.length; i++) { + output.push((input[i] >> 4) + offset); + output.push((input[i] & 0xf) + offset); + } + } + + return output; + + } + +} + +export default EncodeNetBIOSName; diff --git a/src/core/operations/EncodeText.mjs b/src/core/operations/EncodeText.mjs new file mode 100644 index 00000000..6786be56 --- /dev/null +++ b/src/core/operations/EncodeText.mjs @@ -0,0 +1,58 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import cptable from "../vendor/js-codepage/cptable.js"; +import {IO_FORMAT} from "../lib/ChrEnc"; + +/** + * Encode text operation + */ +class EncodeText extends Operation { + + /** + * EncodeText constructor + */ + constructor() { + super(); + + this.name = "Encode text"; + this.module = "CharEnc"; + this.description = [ + "Encodes text into the chosen character encoding.", + "

", + "Supported charsets are:", + "
    ", + Object.keys(IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n"), + "
", + ].join("\n"); + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Encoding", + "type": "option", + "value": Object.keys(IO_FORMAT) + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const format = IO_FORMAT[args[0]]; + let encoded = cptable.utils.encode(format, input); + encoded = Array.from(encoded); + return encoded; + } + +} + + +export default EncodeText; diff --git a/src/core/operations/Entropy.mjs b/src/core/operations/Entropy.mjs new file mode 100644 index 00000000..5accf07a --- /dev/null +++ b/src/core/operations/Entropy.mjs @@ -0,0 +1,96 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Entropy operation + */ +class Entropy extends Operation { + + /** + * Entropy constructor + */ + constructor() { + super(); + + this.name = "Entropy"; + this.module = "Default"; + this.description = "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum."; + this.inputType = "byteArray"; + this.outputType = "number"; + this.presentType = "html"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {number} + */ + run(input, args) { + const prob = [], + uniques = input.unique(), + str = Utils.byteArrayToChars(input); + let i; + + for (i = 0; i < uniques.length; i++) { + prob.push(str.count(Utils.chr(uniques[i])) / input.length); + } + + let entropy = 0, + p; + + for (i = 0; i < prob.length; i++) { + p = prob[i]; + entropy += p * Math.log(p) / Math.log(2); + } + + return -entropy; + } + + /** + * Displays the entropy as a scale bar for web apps. + * + * @param {number} entropy + * @returns {html} + */ + present(entropy) { + return `Shannon entropy: ${entropy} +

+- 0 represents no randomness (i.e. all the bytes in the data have the same value) whereas 8, the maximum, represents a completely random string. +- Standard English text usually falls somewhere between 3.5 and 5. +- Properly encrypted or compressed data of a reasonable length should have an entropy of over 7.5. + +The following results show the entropy of chunks of the input data. Chunks with particularly high entropy could suggest encrypted or compressed sections. + +
`; + } + +} + +export default Entropy; diff --git a/src/core/operations/EscapeString.mjs b/src/core/operations/EscapeString.mjs new file mode 100644 index 00000000..9e0d5172 --- /dev/null +++ b/src/core/operations/EscapeString.mjs @@ -0,0 +1,87 @@ +/** + * @author Vel0x [dalemy@microsoft.com] + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import jsesc from "jsesc"; + +/** + * Escape string operation + */ +class EscapeString extends Operation { + + /** + * EscapeString constructor + */ + constructor() { + super(); + + this.name = "Escape string"; + this.module = "Default"; + this.description = "Escapes special characters in a string so that they do not cause conflicts. For example, Don't stop me now becomes Don\\'t stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Escape level", + "type": "option", + "value": ["Special chars", "Everything", "Minimal"] + }, + { + "name": "Escape quote", + "type": "option", + "value": ["Single", "Double", "Backtick"] + }, + { + "name": "JSON compatible", + "type": "boolean", + "value": false + }, + { + "name": "ES6 compatible", + "type": "boolean", + "value": true + }, + { + "name": "Uppercase hex", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @example + * EscapeString.run("Don't do that", []) + * > "Don\'t do that" + * EscapeString.run(`Hello + * World`, []) + * > "Hello\nWorld" + */ + run(input, args) { + const level = args[0], + quotes = args[1], + jsonCompat = args[2], + es6Compat = args[3], + lowercaseHex = !args[4]; + + return jsesc(input, { + quotes: quotes.toLowerCase(), + es6: es6Compat, + escapeEverything: level === "Everything", + minimal: level === "Minimal", + json: jsonCompat, + lowercaseHex: lowercaseHex, + }); + } + +} + +export default EscapeString; diff --git a/src/core/operations/EscapeUnicodeCharacters.mjs b/src/core/operations/EscapeUnicodeCharacters.mjs new file mode 100644 index 00000000..9bbf4f69 --- /dev/null +++ b/src/core/operations/EscapeUnicodeCharacters.mjs @@ -0,0 +1,96 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Escape Unicode Characters operation + */ +class EscapeUnicodeCharacters extends Operation { + + /** + * EscapeUnicodeCharacters constructor + */ + constructor() { + super(); + + this.name = "Escape Unicode Characters"; + this.module = "Default"; + this.description = "Converts characters to their unicode-escaped notations.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. σου becomes \\u03C3\\u03BF\\u03C5"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Prefix", + "type": "option", + "value": ["\\u", "%u", "U+"] + }, + { + "name": "Encode all chars", + "type": "boolean", + "value": false + }, + { + "name": "Padding", + "type": "number", + "value": 4 + }, + { + "name": "Uppercase hex", + "type": "boolean", + "value": true + } + ]; + this.patterns = [ + { + match: "\\\\u(?:[\\da-f]{4,6})", + flags: "i", + args: ["\\u"] + }, + { + match: "%u(?:[\\da-f]{4,6})", + flags: "i", + args: ["%u"] + }, + { + match: "U\\+(?:[\\da-f]{4,6})", + flags: "i", + args: ["U+"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const regexWhitelist = /[ -~]/i, + [prefix, encodeAll, padding, uppercaseHex] = args; + + let output = "", + character = ""; + + for (let i = 0; i < input.length; i++) { + character = input[i]; + if (!encodeAll && regexWhitelist.test(character)) { + // It’s a printable ASCII character so don’t escape it. + output += character; + continue; + } + + let cp = character.codePointAt(0).toString(16); + if (uppercaseHex) cp = cp.toUpperCase(); + output += prefix + cp.padStart(padding, "0"); + } + + return output; + } + +} + +export default EscapeUnicodeCharacters; diff --git a/src/core/operations/ExpandAlphabetRange.mjs b/src/core/operations/ExpandAlphabetRange.mjs new file mode 100644 index 00000000..761a7a3b --- /dev/null +++ b/src/core/operations/ExpandAlphabetRange.mjs @@ -0,0 +1,46 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Expand alphabet range operation + */ +class ExpandAlphabetRange extends Operation { + + /** + * ExpandAlphabetRange constructor + */ + constructor() { + super(); + + this.name = "Expand alphabet range"; + this.module = "Default"; + this.description = "Expand an alphabet range string into a list of the characters in that range.

e.g. a-z becomes abcdefghijklmnopqrstuvwxyz."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "binaryString", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return Utils.expandAlphRange(input).join(args[0]); + } + +} + +export default ExpandAlphabetRange; diff --git a/src/core/operations/ExtractDates.mjs b/src/core/operations/ExtractDates.mjs new file mode 100644 index 00000000..530db194 --- /dev/null +++ b/src/core/operations/ExtractDates.mjs @@ -0,0 +1,52 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract dates operation + */ +class ExtractDates extends Operation { + + /** + * ExtractDates constructor + */ + constructor() { + super(); + + this.name = "Extract dates"; + this.module = "Regex"; + this.description = "Extracts dates in the following formats
  • yyyy-mm-dd
  • dd/mm/yyyy
  • mm/dd/yyyy
Dividers can be any of /, -, . or space"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const displayTotal = args[0], + date1 = "(?:19|20)\\d\\d[- /.](?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])", // yyyy-mm-dd + date2 = "(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\\d\\d", // dd/mm/yyyy + date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy + regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig"); + + return search(input, regex, null, displayTotal); + } + +} + +export default ExtractDates; diff --git a/src/core/operations/ExtractDomains.mjs b/src/core/operations/ExtractDomains.mjs new file mode 100644 index 00000000..8eae8064 --- /dev/null +++ b/src/core/operations/ExtractDomains.mjs @@ -0,0 +1,49 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract domains operation + */ +class ExtractDomains extends Operation { + + /** + * ExtractDomains constructor + */ + constructor() { + super(); + + this.name = "Extract domains"; + this.module = "Regex"; + this.description = "Extracts domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Display total", + "type": "boolean", + "value": "Extract.DISPLAY_TOTAL" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const displayTotal = args[0], + regex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig; + + return search(input, regex, null, displayTotal); + } + +} + +export default ExtractDomains; diff --git a/src/core/operations/ExtractEmailAddresses.mjs b/src/core/operations/ExtractEmailAddresses.mjs new file mode 100644 index 00000000..6c2dc740 --- /dev/null +++ b/src/core/operations/ExtractEmailAddresses.mjs @@ -0,0 +1,49 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract email addresses operation + */ +class ExtractEmailAddresses extends Operation { + + /** + * ExtractEmailAddresses constructor + */ + constructor() { + super(); + + this.name = "Extract email addresses"; + this.module = "Regex"; + this.description = "Extracts all email addresses from the input."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const displayTotal = args[0], + regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig; + + return search(input, regex, null, displayTotal); + } + +} + +export default ExtractEmailAddresses; diff --git a/src/core/operations/ExtractFilePaths.mjs b/src/core/operations/ExtractFilePaths.mjs new file mode 100644 index 00000000..4b268192 --- /dev/null +++ b/src/core/operations/ExtractFilePaths.mjs @@ -0,0 +1,78 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract file paths operation + */ +class ExtractFilePaths extends Operation { + + /** + * ExtractFilePaths constructor + */ + constructor() { + super(); + + this.name = "Extract file paths"; + this.module = "Regex"; + this.description = "Extracts anything that looks like a Windows or UNIX file path.

Note that if UNIX is selected, there will likely be a lot of false positives."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Windows", + "type": "boolean", + "value": true + }, + { + "name": "UNIX", + "type": "boolean", + "value": true + }, + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [includeWinPath, includeUnixPath, displayTotal] = args, + winDrive = "[A-Z]:\\\\", + winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}", + winExt = "[A-Z\\d]{1,6}", + winPath = winDrive + "(?:" + winName + "\\\\?)*" + winName + + "(?:\\." + winExt + ")?", + unixPath = "(?:/[A-Z\\d.][A-Z\\d\\-.]{0,61})+"; + let filePaths = ""; + + if (includeWinPath && includeUnixPath) { + filePaths = winPath + "|" + unixPath; + } else if (includeWinPath) { + filePaths = winPath; + } else if (includeUnixPath) { + filePaths = unixPath; + } + + if (filePaths) { + const regex = new RegExp(filePaths, "ig"); + return search(input, regex, null, displayTotal); + } else { + return ""; + } + } + +} + +export default ExtractFilePaths; diff --git a/src/core/operations/ExtractIPAddresses.mjs b/src/core/operations/ExtractIPAddresses.mjs new file mode 100644 index 00000000..1cca2098 --- /dev/null +++ b/src/core/operations/ExtractIPAddresses.mjs @@ -0,0 +1,91 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract IP addresses operation + */ +class ExtractIPAddresses extends Operation { + + /** + * ExtractIPAddresses constructor + */ + constructor() { + super(); + + this.name = "Extract IP addresses"; + this.module = "Regex"; + this.description = "Extracts all IPv4 and IPv6 addresses.

Warning: Given a string 710.65.0.456, this will match 10.65.0.45 so always check the original input!"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "IPv4", + "type": "boolean", + "value": true + }, + { + "name": "IPv6", + "type": "boolean", + "value": false + }, + { + "name": "Remove local IPv4 addresses", + "type": "boolean", + "value": false + }, + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [includeIpv4, includeIpv6, removeLocal, displayTotal] = args, + ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?", + ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})"; + let ips = ""; + + if (includeIpv4 && includeIpv6) { + ips = ipv4 + "|" + ipv6; + } else if (includeIpv4) { + ips = ipv4; + } else if (includeIpv6) { + ips = ipv6; + } + + if (ips) { + const regex = new RegExp(ips, "ig"); + + if (removeLocal) { + const ten = "10\\..+", + oneninetwo = "192\\.168\\..+", + oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", + onetwoseven = "127\\..+", + removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + + "|" + oneseventwo + "|" + onetwoseven + ")"); + + return search(input, regex, removeRegex, displayTotal); + } else { + return search(input, regex, null, displayTotal); + } + } else { + return ""; + } + } + +} + +export default ExtractIPAddresses; diff --git a/src/core/operations/ExtractMACAddresses.mjs b/src/core/operations/ExtractMACAddresses.mjs new file mode 100644 index 00000000..9c3c2a5b --- /dev/null +++ b/src/core/operations/ExtractMACAddresses.mjs @@ -0,0 +1,49 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract MAC addresses operation + */ +class ExtractMACAddresses extends Operation { + + /** + * ExtractMACAddresses constructor + */ + constructor() { + super(); + + this.name = "Extract MAC addresses"; + this.module = "Regex"; + this.description = "Extracts all Media Access Control (MAC) addresses from the input."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const displayTotal = args[0], + regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig; + + return search(input, regex, null, displayTotal); + } + +} + +export default ExtractMACAddresses; diff --git a/src/core/operations/ExtractURLs.mjs b/src/core/operations/ExtractURLs.mjs new file mode 100644 index 00000000..ab306d3f --- /dev/null +++ b/src/core/operations/ExtractURLs.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract URLs operation + */ +class ExtractURLs extends Operation { + + /** + * ExtractURLs constructor + */ + constructor() { + super(); + + this.name = "Extract URLs"; + this.module = "Regex"; + this.description = "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const displayTotal = args[0], + protocol = "[A-Z]+://", + hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+", + port = ":\\d+"; + let path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*"; + + path += "(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*"; + const regex = new RegExp(protocol + hostname + "(?:" + port + + ")?(?:" + path + ")?", "ig"); + return search(input, regex, null, displayTotal); + } + +} + +export default ExtractURLs; diff --git a/src/core/operations/Filter.mjs b/src/core/operations/Filter.mjs new file mode 100644 index 00000000..aaf53f0f --- /dev/null +++ b/src/core/operations/Filter.mjs @@ -0,0 +1,72 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; +import OperationError from "../errors/OperationError"; + +/** + * Filter operation + */ +class Filter extends Operation { + + /** + * Filter constructor + */ + constructor() { + super(); + + this.name = "Filter"; + this.module = "Default"; + this.description = "Splits up the input using the specified delimiter and then filters each branch based on a regular expression."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": INPUT_DELIM_OPTIONS + }, + { + "name": "Regex", + "type": "string", + "value": "" + }, + { + "name": "Invert condition", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0]), + reverse = args[2]; + let regex; + + try { + regex = new RegExp(args[1]); + } catch (err) { + throw new OperationError(`Invalid regex. Details: ${err.message}`); + } + + const regexFilter = function(value) { + return reverse ^ regex.test(value); + }; + + return input.split(delim).filter(regexFilter).join(delim); + } + +} + +export default Filter; diff --git a/src/core/operations/Fletcher16Checksum.mjs b/src/core/operations/Fletcher16Checksum.mjs new file mode 100644 index 00000000..ea3fe791 --- /dev/null +++ b/src/core/operations/Fletcher16Checksum.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Fletcher-16 Checksum operation + */ +class Fletcher16Checksum extends Operation { + + /** + * Fletcher16Checksum constructor + */ + constructor() { + super(); + + this.name = "Fletcher-16 Checksum"; + this.module = "Hashing"; + this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let a = 0, + b = 0; + + for (let i = 0; i < input.length; i++) { + a = (a + input[i]) % 0xff; + b = (b + a) % 0xff; + } + + return Utils.hex(((b << 8) | a) >>> 0, 4); + } + +} + +export default Fletcher16Checksum; diff --git a/src/core/operations/Fletcher32Checksum.mjs b/src/core/operations/Fletcher32Checksum.mjs new file mode 100644 index 00000000..21c9449e --- /dev/null +++ b/src/core/operations/Fletcher32Checksum.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Fletcher-32 Checksum operation + */ +class Fletcher32Checksum extends Operation { + + /** + * Fletcher32Checksum constructor + */ + constructor() { + super(); + + this.name = "Fletcher-32 Checksum"; + this.module = "Hashing"; + this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let a = 0, + b = 0; + + for (let i = 0; i < input.length; i++) { + a = (a + input[i]) % 0xffff; + b = (b + a) % 0xffff; + } + + return Utils.hex(((b << 16) | a) >>> 0, 8); + } + +} + +export default Fletcher32Checksum; diff --git a/src/core/operations/Fletcher64Checksum.mjs b/src/core/operations/Fletcher64Checksum.mjs new file mode 100644 index 00000000..ac88a26f --- /dev/null +++ b/src/core/operations/Fletcher64Checksum.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Fletcher-64 Checksum operation + */ +class Fletcher64Checksum extends Operation { + + /** + * Fletcher64Checksum constructor + */ + constructor() { + super(); + + this.name = "Fletcher-64 Checksum"; + this.module = "Hashing"; + this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let a = 0, + b = 0; + + for (let i = 0; i < input.length; i++) { + a = (a + input[i]) % 0xffffffff; + b = (b + a) % 0xffffffff; + } + + return Utils.hex(b >>> 0, 8) + Utils.hex(a >>> 0, 8); + } + +} + +export default Fletcher64Checksum; diff --git a/src/core/operations/Fletcher8Checksum.mjs b/src/core/operations/Fletcher8Checksum.mjs new file mode 100644 index 00000000..99199449 --- /dev/null +++ b/src/core/operations/Fletcher8Checksum.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Fletcher-8 Checksum operation + */ +class Fletcher8Checksum extends Operation { + + /** + * Fletcher8Checksum constructor + */ + constructor() { + super(); + + this.name = "Fletcher-8 Checksum"; + this.module = "Hashing"; + this.description = "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let a = 0, + b = 0; + + for (let i = 0; i < input.length; i++) { + a = (a + input[i]) % 0xf; + b = (b + a) % 0xf; + } + + return Utils.hex(((b << 4) | a) >>> 0, 2); + } + +} + +export default Fletcher8Checksum; diff --git a/src/core/operations/Fork.mjs b/src/core/operations/Fork.mjs new file mode 100644 index 00000000..27a1af96 --- /dev/null +++ b/src/core/operations/Fork.mjs @@ -0,0 +1,117 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Recipe from "../Recipe"; +import Dish from "../Dish"; + +/** + * Fork operation + */ +class Fork extends Operation { + + /** + * Fork constructor + */ + constructor() { + super(); + + this.name = "Fork"; + this.flowControl = true; + this.module = "Default"; + this.description = "Split the input data up based on the specified delimiter and run all subsequent operations on each branch separately.

For example, to decode multiple Base64 strings, enter them all on separate lines then add the 'Fork' and 'From Base64' operations to the recipe. Each string will be decoded separately."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Split delimiter", + "type": "binaryShortString", + "value": "\\n" + }, + { + "name": "Merge delimiter", + "type": "binaryShortString", + "value": "\\n" + }, + { + "name": "Ignore errors", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + async run(state) { + const opList = state.opList, + inputType = opList[state.progress].inputType, + outputType = opList[state.progress].outputType, + input = await state.dish.get(inputType), + ings = opList[state.progress].ingValues, + [splitDelim, mergeDelim, ignoreErrors] = ings, + subOpList = []; + let inputs = [], + i; + + if (input) + inputs = input.split(splitDelim); + + // Create subOpList for each tranche to operate on + // (all remaining operations unless we encounter a Merge) + for (i = state.progress + 1; i < opList.length; i++) { + if (opList[i].name === "Merge" && !opList[i].disabled) { + break; + } else { + subOpList.push(opList[i]); + } + } + + const recipe = new Recipe(); + let output = "", + progress = 0; + + state.forkOffset += state.progress + 1; + + recipe.addOperations(subOpList); + + // Take a deep(ish) copy of the ingredient values + const ingValues = subOpList.map(op => JSON.parse(JSON.stringify(op.ingValues))); + + // Run recipe over each tranche + for (i = 0; i < inputs.length; i++) { + // Baseline ing values for each tranche so that registers are reset + subOpList.forEach((op, i) => { + op.ingValues = JSON.parse(JSON.stringify(ingValues[i])); + }); + + const dish = new Dish(); + dish.set(inputs[i], inputType); + + try { + progress = await recipe.execute(dish, 0, state); + } catch (err) { + if (!ignoreErrors) { + throw err; + } + progress = err.progress + 1; + } + output += await dish.get(outputType) + mergeDelim; + } + + state.dish.set(output, outputType); + state.progress += progress; + return state; + } + +} + +export default Fork; diff --git a/src/core/operations/FormatMACAddresses.mjs b/src/core/operations/FormatMACAddresses.mjs new file mode 100644 index 00000000..b10fc15c --- /dev/null +++ b/src/core/operations/FormatMACAddresses.mjs @@ -0,0 +1,121 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Format MAC addresses operation + */ +class FormatMACAddresses extends Operation { + + /** + * FormatMACAddresses constructor + */ + constructor() { + super(); + + this.name = "Format MAC addresses"; + this.module = "Default"; + this.description = "Displays given MAC addresses in multiple different formats.

Expects addresses in a list separated by newlines, spaces or commas.

WARNING: There are no validity checks."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Output case", + "type": "option", + "value": ["Both", "Upper only", "Lower only"] + }, + { + "name": "No delimiter", + "type": "boolean", + "value": true + }, + { + "name": "Dash delimiter", + "type": "boolean", + "value": true + }, + { + "name": "Colon delimiter", + "type": "boolean", + "value": true + }, + { + "name": "Cisco style", + "type": "boolean", + "value": false + }, + { + "name": "IPv6 interface ID", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (!input) return ""; + + const [ + outputCase, + noDelim, + dashDelim, + colonDelim, + ciscoStyle, + ipv6IntID + ] = args, + outputList = [], + macs = input.toLowerCase().split(/[,\s\r\n]+/); + + macs.forEach(function(mac) { + const cleanMac = mac.replace(/[:.-]+/g, ""), + macHyphen = cleanMac.replace(/(.{2}(?=.))/g, "$1-"), + macColon = cleanMac.replace(/(.{2}(?=.))/g, "$1:"), + macCisco = cleanMac.replace(/(.{4}(?=.))/g, "$1."); + let macIPv6 = cleanMac.slice(0, 6) + "fffe" + cleanMac.slice(6); + + macIPv6 = macIPv6.replace(/(.{4}(?=.))/g, "$1:"); + let bite = parseInt(macIPv6.slice(0, 2), 16) ^ 2; + bite = bite.toString(16).padStart(2, "0"); + macIPv6 = bite + macIPv6.slice(2); + + if (outputCase === "Lower only") { + if (noDelim) outputList.push(cleanMac); + if (dashDelim) outputList.push(macHyphen); + if (colonDelim) outputList.push(macColon); + if (ciscoStyle) outputList.push(macCisco); + if (ipv6IntID) outputList.push(macIPv6); + } else if (outputCase === "Upper only") { + if (noDelim) outputList.push(cleanMac.toUpperCase()); + if (dashDelim) outputList.push(macHyphen.toUpperCase()); + if (colonDelim) outputList.push(macColon.toUpperCase()); + if (ciscoStyle) outputList.push(macCisco.toUpperCase()); + if (ipv6IntID) outputList.push(macIPv6.toUpperCase()); + } else { + if (noDelim) outputList.push(cleanMac, cleanMac.toUpperCase()); + if (dashDelim) outputList.push(macHyphen, macHyphen.toUpperCase()); + if (colonDelim) outputList.push(macColon, macColon.toUpperCase()); + if (ciscoStyle) outputList.push(macCisco, macCisco.toUpperCase()); + if (ipv6IntID) outputList.push(macIPv6, macIPv6.toUpperCase()); + } + + outputList.push( + "" // Empty line to delimit groups + ); + }); + + // Return the data as a string + return outputList.join("\n"); + } + +} + +export default FormatMACAddresses; diff --git a/src/core/operations/FrequencyDistribution.mjs b/src/core/operations/FrequencyDistribution.mjs new file mode 100644 index 00000000..bf82f1d4 --- /dev/null +++ b/src/core/operations/FrequencyDistribution.mjs @@ -0,0 +1,110 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; + +/** + * Frequency distribution operation + */ +class FrequencyDistribution extends Operation { + + /** + * FrequencyDistribution constructor + */ + constructor() { + super(); + + this.name = "Frequency distribution"; + this.module = "Default"; + this.description = "Displays the distribution of bytes in the data as a graph."; + this.inputType = "ArrayBuffer"; + this.outputType = "json"; + this.presentType = "html"; + this.args = [ + { + "name": "Show 0%s", + "type": "boolean", + "value": "Entropy.FREQ_ZEROS" + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {json} + */ + run(input, args) { + const data = new Uint8Array(input); + if (!data.length) throw new OperationError("No data"); + + const distrib = new Array(256).fill(0), + percentages = new Array(256), + len = data.length; + let i; + + // Count bytes + for (i = 0; i < len; i++) { + distrib[data[i]]++; + } + + // Calculate percentages + let repr = 0; + for (i = 0; i < 256; i++) { + if (distrib[i] > 0) repr++; + percentages[i] = distrib[i] / len * 100; + } + + return { + "dataLength": len, + "percentages": percentages, + "distribution": distrib, + "bytesRepresented": repr + }; + } + + /** + * Displays the frequency distribution as a bar chart for web apps. + * + * @param {json} freq + * @returns {html} + */ + present(freq, args) { + const showZeroes = args[0]; + // Print + let output = `
+Total data length: ${freq.dataLength} +Number of bytes represented: ${freq.bytesRepresented} +Number of bytes not represented: ${256 - freq.bytesRepresented} + +Byte Percentage +`; + + for (let i = 0; i < 256; i++) { + if (freq.distribution[i] || showZeroes) { + output += " " + Utils.hex(i, 2) + " (" + + (freq.percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") + + Array(Math.ceil(freq.percentages[i])+1).join("|") + "\n"; + } + } + + return output; + } + +} + +export default FrequencyDistribution; diff --git a/src/core/operations/FromBCD.mjs b/src/core/operations/FromBCD.mjs new file mode 100644 index 00000000..a33d739b --- /dev/null +++ b/src/core/operations/FromBCD.mjs @@ -0,0 +1,122 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; +import {ENCODING_SCHEME, ENCODING_LOOKUP, FORMAT} from "../lib/BCD"; +import BigNumber from "bignumber.js"; + +/** + * From BCD operation + */ +class FromBCD extends Operation { + + /** + * FromBCD constructor + */ + constructor() { + super(); + + this.name = "From BCD"; + this.module = "Default"; + this.description = "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign."; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Scheme", + "type": "option", + "value": ENCODING_SCHEME + }, + { + "name": "Packed", + "type": "boolean", + "value": true + }, + { + "name": "Signed", + "type": "boolean", + "value": false + }, + { + "name": "Input format", + "type": "option", + "value": FORMAT + } + ]; + this.patterns = [ + { + match: "^(?:\\d{4} ){3,}\\d{4}$", + flags: "", + args: ["8 4 2 1", true, false, "Nibbles"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const encoding = ENCODING_LOOKUP[args[0]], + packed = args[1], + signed = args[2], + inputFormat = args[3], + nibbles = []; + + let output = "", + byteArray; + + // Normalise the input + switch (inputFormat) { + case "Nibbles": + case "Bytes": + input = input.replace(/\s/g, ""); + for (let i = 0; i < input.length; i += 4) { + nibbles.push(parseInt(input.substr(i, 4), 2)); + } + break; + case "Raw": + default: + byteArray = Utils.strToByteArray(input); + byteArray.forEach(b => { + nibbles.push(b >>> 4); + nibbles.push(b & 15); + }); + break; + } + + if (!packed) { + // Discard each high nibble + for (let i = 0; i < nibbles.length; i++) { + nibbles.splice(i, 1); + } + } + + if (signed) { + const sign = nibbles.pop(); + if (sign === 13 || + sign === 11) { + // Negative + output += "-"; + } + } + + nibbles.forEach(n => { + if (isNaN(n)) throw new OperationError("Invalid input"); + const val = encoding.indexOf(n); + if (val < 0) throw new OperationError(`Value ${Utils.bin(n, 4)} is not in the encoding scheme`); + output += val.toString(); + }); + + return new BigNumber(output); + } + +} + +export default FromBCD; diff --git a/src/core/operations/FromBase.mjs b/src/core/operations/FromBase.mjs new file mode 100644 index 00000000..4d4ca9ff --- /dev/null +++ b/src/core/operations/FromBase.mjs @@ -0,0 +1,63 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import OperationError from "../errors/OperationError"; + +/** + * From Base operation + */ +class FromBase extends Operation { + + /** + * FromBase constructor + */ + constructor() { + super(); + + this.name = "From Base"; + this.module = "Default"; + this.description = "Converts a number to decimal from a given numerical base."; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Radix", + "type": "number", + "value": 36 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const radix = args[0]; + if (radix < 2 || radix > 36) { + throw new OperationError("Error: Radix argument must be between 2 and 36"); + } + + const number = input.replace(/\s/g, "").split("."); + let result = new BigNumber(number[0], radix) || 0; + + if (number.length === 1) return result; + + // Fractional part + for (let i = 0; i < number[1].length; i++) { + const digit = new BigNumber(number[1][i], radix); + result += digit.div(Math.pow(radix, i+1)); + } + + return result; + } + +} + +export default FromBase; diff --git a/src/core/operations/FromBase32.mjs b/src/core/operations/FromBase32.mjs index 0334ef51..c49d9546 100644 --- a/src/core/operations/FromBase32.mjs +++ b/src/core/operations/FromBase32.mjs @@ -35,6 +35,13 @@ class FromBase32 extends Operation { value: true } ]; + this.patterns = [ + { + match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$", + flags: "", + args: ["A-Z2-7=", false] + }, + ]; } /** diff --git a/src/core/operations/FromBase58.mjs b/src/core/operations/FromBase58.mjs new file mode 100644 index 00000000..58fcab9b --- /dev/null +++ b/src/core/operations/FromBase58.mjs @@ -0,0 +1,105 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; +import {ALPHABET_OPTIONS} from "../lib/Base58"; + +/** + * From Base58 operation + */ +class FromBase58 extends Operation { + + /** + * FromBase58 constructor + */ + constructor() { + super(); + + this.name = "From Base58"; + this.module = "Default"; + this.description = "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation decodes data from an ASCII string (with an alphabet of your choosing, presets included) back into its raw form.

e.g. StV1DL6CwTryKyV becomes hello world

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc)."; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Alphabet", + "type": "editableOption", + "value": ALPHABET_OPTIONS + }, + { + "name": "Remove non-alphabet chars", + "type": "boolean", + "value": true + } + ]; + this.patterns = [ + { + match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false] + }, + { + match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + let alphabet = args[0] || ALPHABET_OPTIONS[0].value; + const removeNonAlphaChars = args[1] === undefined ? true : args[1], + result = [0]; + + alphabet = Utils.expandAlphRange(alphabet).join(""); + + if (alphabet.length !== 58 || + [].unique.call(alphabet).length !== 58) { + throw new OperationError("Alphabet must be of length 58"); + } + + if (input.length === 0) return []; + + [].forEach.call(input, function(c, charIndex) { + const index = alphabet.indexOf(c); + + if (index === -1) { + if (removeNonAlphaChars) { + return; + } else { + throw new OperationError(`Char '${c}' at position ${charIndex} not in alphabet`); + } + } + + let carry = result[0] * 58 + index; + result[0] = carry & 0xFF; + carry = carry >> 8; + + for (let i = 1; i < result.length; i++) { + carry += result[i] * 58; + result[i] = carry & 0xFF; + carry = carry >> 8; + } + + while (carry > 0) { + result.push(carry & 0xFF); + carry = carry >> 8; + } + }); + + return result.reverse(); + } + +} + +export default FromBase58; diff --git a/src/core/operations/FromBase64.mjs b/src/core/operations/FromBase64.mjs index cab86835..34d6c6f6 100644 --- a/src/core/operations/FromBase64.mjs +++ b/src/core/operations/FromBase64.mjs @@ -35,6 +35,73 @@ class FromBase64 extends Operation { value: true } ]; + this.patterns = [ + { + match: "^(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["A-Za-z0-9+/=", false] + }, + { + match: "^[A-Z\\d\\-_]{20,}$", + flags: "i", + args: ["A-Za-z0-9-_", false] + }, + { + match: "^(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?$", + flags: "i", + args: ["A-Za-z0-9+\\-=", false] + }, + { + match: "^(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?$", + flags: "i", + args: ["./0-9A-Za-z=", false] + }, + { + match: "^[A-Z\\d_.]{20,}$", + flags: "i", + args: ["A-Za-z0-9_.", false] + }, + { + match: "^(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?$", + flags: "i", + args: ["A-Za-z0-9._-", false] + }, + { + match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["0-9a-zA-Z+/=", false] + }, + { + match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", + flags: "i", + args: ["0-9A-Za-z+/=", false] + }, + { + match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$", + flags: "", + args: [" -_", false] + }, + { + match: "^[A-Z\\d+\\-]{20,}$", + flags: "i", + args: ["+\\-0-9A-Za-z", false] + }, + { + match: "^[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}$", + flags: "", + args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", false] + }, + { + match: "^(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?$", + flags: "i", + args: ["N-ZA-Mn-za-m0-9+/=", false] + }, + { + match: "^[A-Z\\d./]{20,}$", + flags: "i", + args: ["./0-9A-Za-z", false] + }, + ]; } /** diff --git a/src/core/operations/FromBinary.mjs b/src/core/operations/FromBinary.mjs new file mode 100644 index 00000000..207b5352 --- /dev/null +++ b/src/core/operations/FromBinary.mjs @@ -0,0 +1,124 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {BIN_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * From Binary operation + */ +class FromBinary extends Operation { + + /** + * FromBinary constructor + */ + constructor() { + super(); + + this.name = "From Binary"; + this.module = "Default"; + this.description = "Converts a binary string back into its raw form.

e.g. 01001000 01101001 becomes Hi"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": BIN_DELIM_OPTIONS + } + ]; + this.patterns = [ + { + match: "^(?:[01]{8})+$", + flags: "", + args: ["None"] + }, + { + match: "^(?:[01]{8})(?: [01]{8})*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:[01]{8})(?:,[01]{8})*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:[01]{8})(?:;[01]{8})*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:[01]{8})(?::[01]{8})*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:[01]{8})(?:\\n[01]{8})*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$", + flags: "", + args: ["CRLF"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const delimRegex = Utils.regexRep(args[0] || "Space"); + input = input.replace(delimRegex, ""); + + const output = []; + const byteLen = 8; + for (let i = 0; i < input.length; i += byteLen) { + output.push(parseInt(input.substr(i, byteLen), 2)); + } + return output; + } + + /** + * Highlight From Binary + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + const delim = Utils.charRep(args[0] || "Space"); + pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length)); + pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length)); + return pos; + } + + /** + * Highlight From Binary in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + const delim = Utils.charRep(args[0] || "Space"); + pos[0].start = pos[0].start * (8 + delim.length); + pos[0].end = pos[0].end * (8 + delim.length) - delim.length; + return pos; + } + +} + +export default FromBinary; diff --git a/src/core/operations/FromCharcode.mjs b/src/core/operations/FromCharcode.mjs new file mode 100644 index 00000000..2dee72f2 --- /dev/null +++ b/src/core/operations/FromCharcode.mjs @@ -0,0 +1,83 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; +import OperationError from "../errors/OperationError"; + +/** + * From Charcode operation + */ +class FromCharcode extends Operation { + + /** + * FromCharcode constructor + */ + constructor() { + super(); + + this.name = "From Charcode"; + this.module = "Default"; + this.description = "Converts unicode character codes back into text.

e.g. 0393 03b5 03b9 03ac 20 03c3 03bf 03c5 becomes Γειά σου"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + }, + { + "name": "Base", + "type": "number", + "value": 16 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + * + * @throws {OperationError} if base out of range + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"), + base = args[1]; + let bites = input.split(delim), + i = 0; + + if (base < 2 || base > 36) { + throw new OperationError("Error: Base argument must be between 2 and 36"); + } + + if (input.length === 0) { + return []; + } + + if (base !== 16 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); + + // Split into groups of 2 if the whole string is concatenated and + // too long to be a single character + if (bites.length === 1 && input.length > 17) { + bites = []; + for (i = 0; i < input.length; i += 2) { + bites.push(input.slice(i, i+2)); + } + } + + let latin1 = ""; + for (i = 0; i < bites.length; i++) { + latin1 += Utils.chr(parseInt(bites[i], base)); + } + return Utils.strToByteArray(latin1); + } + +} + +export default FromCharcode; diff --git a/src/core/operations/FromDecimal.mjs b/src/core/operations/FromDecimal.mjs new file mode 100644 index 00000000..48667148 --- /dev/null +++ b/src/core/operations/FromDecimal.mjs @@ -0,0 +1,88 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; + +/** + * From Decimal operation + */ +class FromDecimal extends Operation { + + /** + * FromDecimal constructor + */ + constructor() { + super(); + + this.name = "From Decimal"; + this.module = "Default"; + this.description = "Converts the data from an ordinal integer array back into its raw form.

e.g. 72 101 108 108 111 becomes Hello"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + this.patterns = [ + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", + flags: "", + args: ["CRLF"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const delim = Utils.charRep(args[0]), + output = []; + let byteStr = input.split(delim); + if (byteStr[byteStr.length-1] === "") + byteStr = byteStr.slice(0, byteStr.length-1); + + for (let i = 0; i < byteStr.length; i++) { + output[i] = parseInt(byteStr[i], 10); + } + return output; + } + +} + +export default FromDecimal; diff --git a/src/core/operations/FromHTMLEntity.mjs b/src/core/operations/FromHTMLEntity.mjs new file mode 100644 index 00000000..e9865d95 --- /dev/null +++ b/src/core/operations/FromHTMLEntity.mjs @@ -0,0 +1,342 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * From HTML Entity operation + */ +class FromHTMLEntity extends Operation { + + /** + * FromHTMLEntity constructor + */ + constructor() { + super(); + + this.name = "From HTML Entity"; + this.module = "Default"; + this.description = "Converts HTML entities back to characters

e.g. &amp; becomes &"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + this.patterns = [ + { + match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});", + flags: "i", + args: [] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const regex = /&(#?x?[a-zA-Z0-9]{1,8});/g; + let output = "", + m, + i = 0; + + while ((m = regex.exec(input))) { + // Add up to match + for (; i < m.index;) + output += input[i++]; + + // Add match + const bite = entityToByte[m[1]]; + if (bite) { + output += Utils.chr(bite); + } else if (!bite && m[1][0] === "#" && m[1].length > 1 && /^#\d{1,6}$/.test(m[1])) { + // Numeric entity (e.g. ) + const num = m[1].slice(1, m[1].length); + output += Utils.chr(parseInt(num, 10)); + } else if (!bite && m[1][0] === "#" && m[1].length > 3 && /^#x[\dA-F]{2,8}$/i.test(m[1])) { + // Hex entity (e.g. :) + const hex = m[1].slice(2, m[1].length); + output += Utils.chr(parseInt(hex, 16)); + } else { + // Not a valid entity, print as normal + for (; i < regex.lastIndex;) + output += input[i++]; + } + + i = regex.lastIndex; + } + // Add all after final match + for (; i < input.length;) + output += input[i++]; + + return output; + } + +} + + +/** + * Lookup table to translate HTML entity codes to their byte values. + */ +const entityToByte = { + "quot": 34, + "amp": 38, + "apos": 39, + "lt": 60, + "gt": 62, + "nbsp": 160, + "iexcl": 161, + "cent": 162, + "pound": 163, + "curren": 164, + "yen": 165, + "brvbar": 166, + "sect": 167, + "uml": 168, + "copy": 169, + "ordf": 170, + "laquo": 171, + "not": 172, + "shy": 173, + "reg": 174, + "macr": 175, + "deg": 176, + "plusmn": 177, + "sup2": 178, + "sup3": 179, + "acute": 180, + "micro": 181, + "para": 182, + "middot": 183, + "cedil": 184, + "sup1": 185, + "ordm": 186, + "raquo": 187, + "frac14": 188, + "frac12": 189, + "frac34": 190, + "iquest": 191, + "Agrave": 192, + "Aacute": 193, + "Acirc": 194, + "Atilde": 195, + "Auml": 196, + "Aring": 197, + "AElig": 198, + "Ccedil": 199, + "Egrave": 200, + "Eacute": 201, + "Ecirc": 202, + "Euml": 203, + "Igrave": 204, + "Iacute": 205, + "Icirc": 206, + "Iuml": 207, + "ETH": 208, + "Ntilde": 209, + "Ograve": 210, + "Oacute": 211, + "Ocirc": 212, + "Otilde": 213, + "Ouml": 214, + "times": 215, + "Oslash": 216, + "Ugrave": 217, + "Uacute": 218, + "Ucirc": 219, + "Uuml": 220, + "Yacute": 221, + "THORN": 222, + "szlig": 223, + "agrave": 224, + "aacute": 225, + "acirc": 226, + "atilde": 227, + "auml": 228, + "aring": 229, + "aelig": 230, + "ccedil": 231, + "egrave": 232, + "eacute": 233, + "ecirc": 234, + "euml": 235, + "igrave": 236, + "iacute": 237, + "icirc": 238, + "iuml": 239, + "eth": 240, + "ntilde": 241, + "ograve": 242, + "oacute": 243, + "ocirc": 244, + "otilde": 245, + "ouml": 246, + "divide": 247, + "oslash": 248, + "ugrave": 249, + "uacute": 250, + "ucirc": 251, + "uuml": 252, + "yacute": 253, + "thorn": 254, + "yuml": 255, + "OElig": 338, + "oelig": 339, + "Scaron": 352, + "scaron": 353, + "Yuml": 376, + "fnof": 402, + "circ": 710, + "tilde": 732, + "Alpha": 913, + "Beta": 914, + "Gamma": 915, + "Delta": 916, + "Epsilon": 917, + "Zeta": 918, + "Eta": 919, + "Theta": 920, + "Iota": 921, + "Kappa": 922, + "Lambda": 923, + "Mu": 924, + "Nu": 925, + "Xi": 926, + "Omicron": 927, + "Pi": 928, + "Rho": 929, + "Sigma": 931, + "Tau": 932, + "Upsilon": 933, + "Phi": 934, + "Chi": 935, + "Psi": 936, + "Omega": 937, + "alpha": 945, + "beta": 946, + "gamma": 947, + "delta": 948, + "epsilon": 949, + "zeta": 950, + "eta": 951, + "theta": 952, + "iota": 953, + "kappa": 954, + "lambda": 955, + "mu": 956, + "nu": 957, + "xi": 958, + "omicron": 959, + "pi": 960, + "rho": 961, + "sigmaf": 962, + "sigma": 963, + "tau": 964, + "upsilon": 965, + "phi": 966, + "chi": 967, + "psi": 968, + "omega": 969, + "thetasym": 977, + "upsih": 978, + "piv": 982, + "ensp": 8194, + "emsp": 8195, + "thinsp": 8201, + "zwnj": 8204, + "zwj": 8205, + "lrm": 8206, + "rlm": 8207, + "ndash": 8211, + "mdash": 8212, + "lsquo": 8216, + "rsquo": 8217, + "sbquo": 8218, + "ldquo": 8220, + "rdquo": 8221, + "bdquo": 8222, + "dagger": 8224, + "Dagger": 8225, + "bull": 8226, + "hellip": 8230, + "permil": 8240, + "prime": 8242, + "Prime": 8243, + "lsaquo": 8249, + "rsaquo": 8250, + "oline": 8254, + "frasl": 8260, + "euro": 8364, + "image": 8465, + "weierp": 8472, + "real": 8476, + "trade": 8482, + "alefsym": 8501, + "larr": 8592, + "uarr": 8593, + "rarr": 8594, + "darr": 8595, + "harr": 8596, + "crarr": 8629, + "lArr": 8656, + "uArr": 8657, + "rArr": 8658, + "dArr": 8659, + "hArr": 8660, + "forall": 8704, + "part": 8706, + "exist": 8707, + "empty": 8709, + "nabla": 8711, + "isin": 8712, + "notin": 8713, + "ni": 8715, + "prod": 8719, + "sum": 8721, + "minus": 8722, + "lowast": 8727, + "radic": 8730, + "prop": 8733, + "infin": 8734, + "ang": 8736, + "and": 8743, + "or": 8744, + "cap": 8745, + "cup": 8746, + "int": 8747, + "there4": 8756, + "sim": 8764, + "cong": 8773, + "asymp": 8776, + "ne": 8800, + "equiv": 8801, + "le": 8804, + "ge": 8805, + "sub": 8834, + "sup": 8835, + "nsub": 8836, + "sube": 8838, + "supe": 8839, + "oplus": 8853, + "otimes": 8855, + "perp": 8869, + "sdot": 8901, + "vellip": 8942, + "lceil": 8968, + "rceil": 8969, + "lfloor": 8970, + "rfloor": 8971, + "lang": 9001, + "rang": 9002, + "loz": 9674, + "spades": 9824, + "clubs": 9827, + "hearts": 9829, + "diams": 9830, +}; + +export default FromHTMLEntity; diff --git a/src/core/operations/FromHex.mjs b/src/core/operations/FromHex.mjs index 17557196..45ea9955 100644 --- a/src/core/operations/FromHex.mjs +++ b/src/core/operations/FromHex.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation"; -import {fromHex, HEX_DELIM_OPTIONS} from "../lib/Hex"; +import {fromHex, FROM_HEX_DELIM_OPTIONS} from "../lib/Hex"; import Utils from "../Utils"; /** @@ -28,7 +28,54 @@ class FromHex extends Operation { { name: "Delimiter", type: "option", - value: HEX_DELIM_OPTIONS + value: FROM_HEX_DELIM_OPTIONS + } + ]; + this.patterns = [ + { + match: "^(?:[\\dA-F]{2})+$", + flags: "i", + args: ["None"] + }, + { + match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$", + flags: "i", + args: ["Space"] + }, + { + match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$", + flags: "i", + args: ["Comma"] + }, + { + match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$", + flags: "i", + args: ["Semi-colon"] + }, + { + match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$", + flags: "i", + args: ["Colon"] + }, + { + match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$", + flags: "i", + args: ["Line feed"] + }, + { + match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$", + flags: "i", + args: ["CRLF"] + }, + { + match: "^[\\dA-F]{2}(?:0x[\\dA-F]{2})*$", + flags: "i", + args: ["0x"] + }, + { + match: "^[\\dA-F]{2}(?:\\\\x[\\dA-F]{2})*$", + flags: "i", + args: ["\\x"] } ]; } @@ -53,6 +100,7 @@ class FromHex extends Operation { * @returns {Object[]} pos */ highlight(pos, args) { + if (args[0] === "Auto") return false; const delim = Utils.charRep(args[0] || "Space"), len = delim === "\r\n" ? 1 : delim.length, width = len + 2; diff --git a/src/core/operations/FromHexContent.mjs b/src/core/operations/FromHexContent.mjs new file mode 100644 index 00000000..9de085db --- /dev/null +++ b/src/core/operations/FromHexContent.mjs @@ -0,0 +1,66 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {fromHex} from "../lib/Hex"; + +/** + * From Hex Content operation + */ +class FromHexContent extends Operation { + + /** + * FromHexContent constructor + */ + constructor() { + super(); + + this.name = "From Hex Content"; + this.module = "Default"; + this.description = "Translates hexadecimal bytes in text back to raw bytes.

e.g. foo|3d|bar becomes foo=bar."; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const regex = /\|([a-f\d ]{2,})\|/gi, + output = []; + let m, i = 0; + while ((m = regex.exec(input))) { + // Add up to match + for (; i < m.index;) + output.push(Utils.ord(input[i++])); + + // Add match + const bytes = fromHex(m[1]); + if (bytes) { + for (let a = 0; a < bytes.length;) + output.push(bytes[a++]); + } else { + // Not valid hex, print as normal + for (; i < regex.lastIndex;) + output.push(Utils.ord(input[i++])); + } + + i = regex.lastIndex; + } + // Add all after final match + for (; i < input.length;) + output.push(Utils.ord(input[i++])); + + return output; + } + +} + +export default FromHexContent; diff --git a/src/core/operations/FromHexdump.mjs b/src/core/operations/FromHexdump.mjs new file mode 100644 index 00000000..fc10b7a9 --- /dev/null +++ b/src/core/operations/FromHexdump.mjs @@ -0,0 +1,163 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {fromHex} from "../lib/Hex"; + +/** + * From Hexdump operation + */ +class FromHexdump extends Operation { + + /** + * FromHexdump constructor + */ + constructor() { + super(); + + this.name = "From Hexdump"; + this.module = "Default"; + this.description = "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis."; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = []; + this.patterns = [ + { + match: "^(?:(?:[\\dA-F]{4,16}:?)?\\s*((?:[\\dA-F]{2}\\s){1,8}(?:\\s|[\\dA-F]{2}-)(?:[\\dA-F]{2}\\s){1,8}|(?:[\\dA-F]{2}\\s|[\\dA-F]{4}\\s)+)[^\\n]*\\n?)+$", + flags: "i", + args: [] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const output = [], + regex = /^\s*(?:[\dA-F]{4,16}h?:?)?\s*((?:[\dA-F]{2}\s){1,8}(?:\s|[\dA-F]{2}-)(?:[\dA-F]{2}\s){1,8}|(?:[\dA-F]{2}\s|[\dA-F]{4}\s)+)/igm; + let block, line; + + while ((block = regex.exec(input))) { + line = fromHex(block[1].replace(/-/g, " ")); + for (let i = 0; i < line.length; i++) { + output.push(line[i]); + } + } + // Is this a CyberChef hexdump or is it from a different tool? + const width = input.indexOf("\n"); + const w = (width - 13) / 4; + // w should be the specified width of the hexdump and therefore a round number + if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) { + if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); + } + return output; + } + + /** + * Highlight From Hexdump + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + const w = args[0] || 16; + const width = 14 + (w*4); + + let line = Math.floor(pos[0].start / width); + let offset = pos[0].start % width; + + if (offset < 10) { // In line number section + pos[0].start = line*w; + } else if (offset > 10+(w*3)) { // In ASCII section + pos[0].start = (line+1)*w; + } else { // In byte section + pos[0].start = line*w + Math.floor((offset-10)/3); + } + + line = Math.floor(pos[0].end / width); + offset = pos[0].end % width; + + if (offset < 10) { // In line number section + pos[0].end = line*w; + } else if (offset > 10+(w*3)) { // In ASCII section + pos[0].end = (line+1)*w; + } else { // In byte section + pos[0].end = line*w + Math.ceil((offset-10)/3); + } + + return pos; + } + + /** + * Highlight From Hexdump in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + // Calculate overall selection + const w = args[0] || 16, + width = 14 + (w*4); + let line = Math.floor(pos[0].start / w), + offset = pos[0].start % w, + start = 0, + end = 0; + + pos[0].start = line*width + 10 + offset*3; + + line = Math.floor(pos[0].end / w); + offset = pos[0].end % w; + if (offset === 0) { + line--; + offset = w; + } + pos[0].end = line*width + 10 + offset*3 - 1; + + // Set up multiple selections for bytes + let startLineNum = Math.floor(pos[0].start / width); + const endLineNum = Math.floor(pos[0].end / width); + + if (startLineNum === endLineNum) { + pos.push(pos[0]); + } else { + start = pos[0].start; + end = (startLineNum+1) * width - w - 5; + pos.push({ start: start, end: end }); + while (end < pos[0].end) { + startLineNum++; + start = startLineNum * width + 10; + end = (startLineNum+1) * width - w - 5; + if (end > pos[0].end) end = pos[0].end; + pos.push({ start: start, end: end }); + } + } + + // Set up multiple selections for ASCII + const len = pos.length; + let lineNum = 0; + start = 0; + end = 0; + for (let i = 1; i < len; i++) { + lineNum = Math.floor(pos[i].start / width); + start = (((pos[i].start - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); + end = (((pos[i].end + 1 - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); + pos.push({ start: start, end: end }); + } + return pos; + } + +} + +export default FromHexdump; diff --git a/src/core/operations/FromMorseCode.mjs b/src/core/operations/FromMorseCode.mjs new file mode 100644 index 00000000..ecf20a08 --- /dev/null +++ b/src/core/operations/FromMorseCode.mjs @@ -0,0 +1,152 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {LETTER_DELIM_OPTIONS, WORD_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * From Morse Code operation + */ +class FromMorseCode extends Operation { + + /** + * FromMorseCode constructor + */ + constructor() { + super(); + + this.name = "From Morse Code"; + this.module = "Default"; + this.description = "Translates Morse Code into (upper case) alphanumeric characters."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Letter delimiter", + "type": "option", + "value": LETTER_DELIM_OPTIONS + }, + { + "name": "Word delimiter", + "type": "option", + "value": WORD_DELIM_OPTIONS + } + ]; + this.patterns = [ + { + match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)", + flags: "i", + args: ["Space", "Line feed"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (!this.reversedTable) { + this.reverseTable(); + } + + const letterDelim = Utils.charRep(args[0]); + const wordDelim = Utils.charRep(args[1]); + + input = input.replace(/-|‐|−|_|–|—|dash/ig, ""); //hyphen-minus|hyphen|minus-sign|undersore|en-dash|em-dash + input = input.replace(/\.|·|dot/ig, ""); + + let words = input.split(wordDelim); + const self = this; + words = Array.prototype.map.call(words, function(word) { + const signals = word.split(letterDelim); + + const letters = signals.map(function(signal) { + return self.reversedTable[signal]; + }); + + return letters.join(""); + }); + words = words.join(" "); + + return words; + } + + + /** + * Reverses the Morse Code lookup table + */ + reverseTable() { + this.reversedTable = {}; + + for (const letter in MORSE_TABLE) { + const signal = MORSE_TABLE[letter]; + this.reversedTable[signal] = letter; + } + } + +} + +const MORSE_TABLE = { + "A": "", + "B": "", + "C": "", + "D": "", + "E": "", + "F": "", + "G": "", + "H": "", + "I": "", + "J": "", + "K": "", + "L": "", + "M": "", + "N": "", + "O": "", + "P": "", + "Q": "", + "R": "", + "S": "", + "T": "", + "U": "", + "V": "", + "W": "", + "X": "", + "Y": "", + "Z": "", + "1": "", + "2": "", + "3": "", + "4": "", + "5": "", + "6": "", + "7": "", + "8": "", + "9": "", + "0": "", + ".": "", + ",": "", + ":": "", + ";": "", + "!": "", + "?": "", + "'": "", + "\"": "", + "/": "", + "-": "", + "+": "", + "(": "", + ")": "", + "@": "", + "=": "", + "&": "", + "_": "", + "$": "" +}; + +export default FromMorseCode; diff --git a/src/core/operations/FromOctal.mjs b/src/core/operations/FromOctal.mjs new file mode 100644 index 00000000..efe04050 --- /dev/null +++ b/src/core/operations/FromOctal.mjs @@ -0,0 +1,81 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; + +/** + * From Octal operation + */ +class FromOctal extends Operation { + + /** + * FromOctal constructor + */ + constructor() { + super(); + + this.name = "From Octal"; + this.module = "Default"; + this.description = "Converts an octal byte string back into its raw value.

e.g. 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205 becomes the UTF-8 encoded string Γειά σου"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + this.patterns = [ + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Space"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Comma"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Semi-colon"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Colon"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Line feed"] + }, + { + match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["CRLF"] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"); + if (input.length === 0) return []; + return input.split(delim).map(val => parseInt(val, 8)); + } + +} + +export default FromOctal; diff --git a/src/core/operations/FromPunycode.mjs b/src/core/operations/FromPunycode.mjs new file mode 100644 index 00000000..1a1cebbf --- /dev/null +++ b/src/core/operations/FromPunycode.mjs @@ -0,0 +1,52 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import punycode from "punycode"; + +/** + * From Punycode operation + */ +class FromPunycode extends Operation { + + /** + * FromPunycode constructor + */ + constructor() { + super(); + + this.name = "From Punycode"; + this.module = "Encodings"; + this.description = "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. mnchen-3ya decodes to m\xfcnchen"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Internationalised domain name", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const idn = args[0]; + + if (idn) { + return punycode.toUnicode(input); + } else { + return punycode.decode(input); + } + } + +} + +export default FromPunycode; diff --git a/src/core/operations/FromQuotedPrintable.mjs b/src/core/operations/FromQuotedPrintable.mjs new file mode 100644 index 00000000..06a6432c --- /dev/null +++ b/src/core/operations/FromQuotedPrintable.mjs @@ -0,0 +1,68 @@ +/** + * Some parts taken from mimelib (http://github.com/andris9/mimelib) + * @author Andris Reinman + * @license MIT + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * From Quoted Printable operation + */ +class FromQuotedPrintable extends Operation { + + /** + * FromQuotedPrintable constructor + */ + constructor() { + super(); + + this.name = "From Quoted Printable"; + this.module = "Default"; + this.description = "Converts QP-encoded text back to standard text."; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = []; + this.patterns = [ + { + match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]*(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$", + flags: "i", + args: [] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const str = input.replace(/=(?:\r?\n|$)/g, ""); + + const encodedBytesCount = (str.match(/=[\da-fA-F]{2}/g) || []).length, + bufferLength = str.length - encodedBytesCount * 2, + buffer = new Array(bufferLength); + let chr, hex, + bufferPos = 0; + + for (let i = 0, len = str.length; i < len; i++) { + chr = str.charAt(i); + if (chr === "=" && (hex = str.substr(i + 1, 2)) && /[\da-fA-F]{2}/.test(hex)) { + buffer[bufferPos++] = parseInt(hex, 16); + i += 2; + continue; + } + buffer[bufferPos++] = chr.charCodeAt(0); + } + + return buffer; + } + +} + +export default FromQuotedPrintable; diff --git a/src/core/operations/FromUNIXTimestamp.mjs b/src/core/operations/FromUNIXTimestamp.mjs new file mode 100644 index 00000000..c6d6af43 --- /dev/null +++ b/src/core/operations/FromUNIXTimestamp.mjs @@ -0,0 +1,91 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import moment from "moment-timezone"; +import {UNITS} from "../lib/DateTime"; +import OperationError from "../errors/OperationError"; + +/** + * From UNIX Timestamp operation + */ +class FromUNIXTimestamp extends Operation { + + /** + * FromUNIXTimestamp constructor + */ + constructor() { + super(); + + this.name = "From UNIX Timestamp"; + this.module = "Default"; + this.description = "Converts a UNIX timestamp to a datetime string.

e.g. 978346800 becomes Mon 1 January 2001 11:00:00 UTC

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch)."; + this.inputType = "number"; + this.outputType = "string"; + this.args = [ + { + "name": "Units", + "type": "option", + "value": UNITS + } + ]; + this.patterns = [ + { + match: "^1?\\d{9}$", + flags: "", + args: ["Seconds (s)"] + }, + { + match: "^1?\\d{12}$", + flags: "", + args: ["Milliseconds (ms)"] + }, + { + match: "^1?\\d{15}$", + flags: "", + args: ["Microseconds (μs)"] + }, + { + match: "^1?\\d{18}$", + flags: "", + args: ["Nanoseconds (ns)"] + }, + ]; + } + + /** + * @param {number} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if invalid unit + */ + run(input, args) { + const units = args[0]; + let d; + + input = parseFloat(input); + + if (units === "Seconds (s)") { + d = moment.unix(input); + return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss") + " UTC"; + } else if (units === "Milliseconds (ms)") { + d = moment(input); + return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; + } else if (units === "Microseconds (μs)") { + d = moment(input / 1000); + return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; + } else if (units === "Nanoseconds (ns)") { + d = moment(input / 1000000); + return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; + } else { + throw new OperationError("Unrecognised unit"); + } + } + +} + +export default FromUNIXTimestamp; diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs new file mode 100644 index 00000000..1280249a --- /dev/null +++ b/src/core/operations/GenerateAllHashes.mjs @@ -0,0 +1,104 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import MD2 from "./MD2"; +import MD4 from "./MD4"; +import MD5 from "./MD5"; +import MD6 from "./MD6"; +import SHA0 from "./SHA0"; +import SHA1 from "./SHA1"; +import SHA2 from "./SHA2"; +import SHA3 from "./SHA3"; +import Keccak from "./Keccak"; +import Shake from "./Shake"; +import RIPEMD from "./RIPEMD"; +import HAS160 from "./HAS160"; +import Whirlpool from "./Whirlpool"; +import SSDEEP from "./SSDEEP"; +import CTPH from "./CTPH"; +import Fletcher8Checksum from "./Fletcher8Checksum"; +import Fletcher16Checksum from "./Fletcher16Checksum"; +import Fletcher32Checksum from "./Fletcher32Checksum"; +import Fletcher64Checksum from "./Fletcher64Checksum"; +import Adler32Checksum from "./Adler32Checksum"; +import CRC16Checksum from "./CRC16Checksum"; +import CRC32Checksum from "./CRC32Checksum"; + +/** + * Generate all hashes operation + */ +class GenerateAllHashes extends Operation { + + /** + * GenerateAllHashes constructor + */ + constructor() { + super(); + + this.name = "Generate all hashes"; + this.module = "Hashing"; + this.description = "Generates all available hashes and checksums for the input."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const arrayBuffer = input, + str = Utils.arrayBufferToStr(arrayBuffer, false), + byteArray = new Uint8Array(arrayBuffer), + output = "MD2: " + (new MD2()).run(arrayBuffer, []) + + "\nMD4: " + (new MD4()).run(arrayBuffer, []) + + "\nMD5: " + (new MD5()).run(arrayBuffer, []) + + "\nMD6: " + (new MD6()).run(str, []) + + "\nSHA0: " + (new SHA0()).run(arrayBuffer, []) + + "\nSHA1: " + (new SHA1()).run(arrayBuffer, []) + + "\nSHA2 224: " + (new SHA2()).run(arrayBuffer, ["224"]) + + "\nSHA2 256: " + (new SHA2()).run(arrayBuffer, ["256"]) + + "\nSHA2 384: " + (new SHA2()).run(arrayBuffer, ["384"]) + + "\nSHA2 512: " + (new SHA2()).run(arrayBuffer, ["512"]) + + "\nSHA3 224: " + (new SHA3()).run(arrayBuffer, ["224"]) + + "\nSHA3 256: " + (new SHA3()).run(arrayBuffer, ["256"]) + + "\nSHA3 384: " + (new SHA3()).run(arrayBuffer, ["384"]) + + "\nSHA3 512: " + (new SHA3()).run(arrayBuffer, ["512"]) + + "\nKeccak 224: " + (new Keccak()).run(arrayBuffer, ["224"]) + + "\nKeccak 256: " + (new Keccak()).run(arrayBuffer, ["256"]) + + "\nKeccak 384: " + (new Keccak()).run(arrayBuffer, ["384"]) + + "\nKeccak 512: " + (new Keccak()).run(arrayBuffer, ["512"]) + + "\nShake 128: " + (new Shake()).run(arrayBuffer, ["128", 256]) + + "\nShake 256: " + (new Shake()).run(arrayBuffer, ["256", 512]) + + "\nRIPEMD-128: " + (new RIPEMD()).run(arrayBuffer, ["128"]) + + "\nRIPEMD-160: " + (new RIPEMD()).run(arrayBuffer, ["160"]) + + "\nRIPEMD-256: " + (new RIPEMD()).run(arrayBuffer, ["256"]) + + "\nRIPEMD-320: " + (new RIPEMD()).run(arrayBuffer, ["320"]) + + "\nHAS-160: " + (new HAS160()).run(arrayBuffer, []) + + "\nWhirlpool-0: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-0"]) + + "\nWhirlpool-T: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool-T"]) + + "\nWhirlpool: " + (new Whirlpool()).run(arrayBuffer, ["Whirlpool"]) + + "\nSSDEEP: " + (new SSDEEP()).run(str) + + "\nCTPH: " + (new CTPH()).run(str) + + "\n\nChecksums:" + + "\nFletcher-8: " + (new Fletcher8Checksum).run(byteArray, []) + + "\nFletcher-16: " + (new Fletcher16Checksum).run(byteArray, []) + + "\nFletcher-32: " + (new Fletcher32Checksum).run(byteArray, []) + + "\nFletcher-64: " + (new Fletcher64Checksum).run(byteArray, []) + + "\nAdler-32: " + (new Adler32Checksum).run(byteArray, []) + + "\nCRC-16: " + (new CRC16Checksum).run(str, []) + + "\nCRC-32: " + (new CRC32Checksum).run(str, []); + + return output; + } + +} + +export default GenerateAllHashes; diff --git a/src/core/operations/GenerateHOTP.mjs b/src/core/operations/GenerateHOTP.mjs new file mode 100644 index 00000000..36c115c5 --- /dev/null +++ b/src/core/operations/GenerateHOTP.mjs @@ -0,0 +1,69 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import otp from "otp"; +import ToBase32 from "./ToBase32"; + +/** + * Generate HOTP operation + */ +class GenerateHOTP extends Operation { + + /** + * GenerateHOTP constructor + */ + constructor() { + super(); + + this.name = "Generate HOTP"; + this.module = "Default"; + this.description = "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Name", + "type": "string", + "value": "" + }, + { + "name": "Key size", + "type": "number", + "value": 32 + }, + { + "name": "Code length", + "type": "number", + "value": 6 + }, + { + "name": "Counter", + "type": "number", + "value": 0 + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const otpObj = otp({ + name: args[0], + keySize: args[1], + codeLength: args[2], + secret: (new ToBase32).run(input, []), + }); + const counter = args[3]; + return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`; + } + +} + +export default GenerateHOTP; diff --git a/src/core/operations/GeneratePGPKeyPair.mjs b/src/core/operations/GeneratePGPKeyPair.mjs new file mode 100644 index 00000000..65bfad44 --- /dev/null +++ b/src/core/operations/GeneratePGPKeyPair.mjs @@ -0,0 +1,116 @@ +/** + * @author tlwr [toby@toby.codes] + * @author Matt C [matt@artemisbot.uk] + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import kbpgp from "kbpgp"; +import { getSubkeySize, ASP } from "../lib/PGP"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * Generate PGP Key Pair operation + */ +class GeneratePGPKeyPair extends Operation { + + /** + * GeneratePGPKeyPair constructor + */ + constructor() { + super(); + + this.name = "Generate PGP Key Pair"; + this.module = "PGP"; + this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key type", + "type": "option", + "value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"] + }, + { + "name": "Password (optional)", + "type": "string", + "value": "" + }, + { + "name": "Name (optional)", + "type": "string", + "value": "" + }, + { + "name": "Email (optional)", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [keyType, keySize] = args[0].split("-"), + password = args[1], + name = args[2], + email = args[3]; + let userIdentifier = ""; + + if (name) userIdentifier += name; + if (email) userIdentifier += ` <${email}>`; + + let flags = kbpgp.const.openpgp.certify_keys; + flags |= kbpgp.const.openpgp.sign_data; + flags |= kbpgp.const.openpgp.auth; + flags |= kbpgp.const.openpgp.encrypt_comm; + flags |= kbpgp.const.openpgp.encrypt_storage; + + const keyGenerationOptions = { + userid: userIdentifier, + ecc: keyType === "ecc", + primary: { + "nbits": keySize, + "flags": flags, + "expire_in": 0 + }, + subkeys: [{ + "nbits": getSubkeySize(keySize), + "flags": kbpgp.const.openpgp.sign_data, + "expire_in": 86400 * 365 * 8 + }, { + "nbits": getSubkeySize(keySize), + "flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage, + "expire_in": 86400 * 365 * 2 + }], + asp: ASP + }; + + return new Promise(async (resolve, reject) => { + try { + const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions); + await promisify(unsignedKey.sign.bind(unsignedKey))({}); + + const signedKey = unsignedKey, + privateKeyExportOptions = {}; + + if (password) privateKeyExportOptions.passphrase = password; + const privateKey = await promisify(signedKey.export_pgp_private.bind(signedKey))(privateKeyExportOptions); + const publicKey = await promisify(signedKey.export_pgp_public.bind(signedKey))({}); + resolve(privateKey + "\n" + publicKey.trim()); + } catch (err) { + reject(`Error whilst generating key pair: ${err}`); + } + }); + } + +} + +export default GeneratePGPKeyPair; diff --git a/src/core/operations/GenerateTOTP.mjs b/src/core/operations/GenerateTOTP.mjs new file mode 100644 index 00000000..8d53f1be --- /dev/null +++ b/src/core/operations/GenerateTOTP.mjs @@ -0,0 +1,75 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import otp from "otp"; +import ToBase32 from "./ToBase32"; + +/** + * Generate TOTP operation + */ +class GenerateTOTP extends Operation { + + /** + * GenerateTOTP constructor + */ + constructor() { + super(); + + this.name = "Generate TOTP"; + this.module = "Default"; + this.description = "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Name", + "type": "string", + "value": "" + }, + { + "name": "Key size", + "type": "number", + "value": 32 + }, + { + "name": "Code length", + "type": "number", + "value": 6 + }, + { + "name": "Epoch offset (T0)", + "type": "number", + "value": 0 + }, + { + "name": "Interval (T1)", + "type": "number", + "value": 30 + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const otpObj = otp({ + name: args[0], + keySize: args[1], + codeLength: args[2], + secret: (new ToBase32).run(input, []), + epoch: args[3], + timeSlice: args[4] + }); + return `URI: ${otpObj.totpURL}\n\nPassword: ${otpObj.totp()}`; + } + +} + +export default GenerateTOTP; diff --git a/src/core/operations/GenerateUUID.mjs b/src/core/operations/GenerateUUID.mjs new file mode 100644 index 00000000..59837b26 --- /dev/null +++ b/src/core/operations/GenerateUUID.mjs @@ -0,0 +1,49 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import crypto from "crypto"; + +/** + * Generate UUID operation + */ +class GenerateUUID extends Operation { + + /** + * GenerateUUID constructor + */ + constructor() { + super(); + + this.name = "Generate UUID"; + this.module = "Crypto"; + this.description = "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).

A version 4 UUID relies on random numbers, in this case generated using window.crypto if available and falling back to Math.random if not."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const buf = new Uint32Array(4).map(() => { + return crypto.randomBytes(4).readUInt32BE(0, true); + }); + let i = 0; + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + const r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, + v = c === "x" ? r : (r & 0x3 | 0x8); + i++; + return v.toString(16); + }); + } + +} + +export default GenerateUUID; diff --git a/src/core/operations/Gunzip.mjs b/src/core/operations/Gunzip.mjs index 7e456525..19821de6 100644 --- a/src/core/operations/Gunzip.mjs +++ b/src/core/operations/Gunzip.mjs @@ -26,6 +26,13 @@ class Gunzip extends Operation { this.inputType = "ArrayBuffer"; this.outputType = "ArrayBuffer"; this.args = []; + this.patterns = [ + { + match: "^\\x1f\\x8b\\x08", + flags: "", + args: [] + }, + ]; } /** diff --git a/src/core/operations/HAS160.mjs b/src/core/operations/HAS160.mjs new file mode 100644 index 00000000..1cf1ab6e --- /dev/null +++ b/src/core/operations/HAS160.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * HAS-160 operation + */ +class HAS160 extends Operation { + + /** + * HAS-160 constructor + */ + constructor() { + super(); + + this.name = "HAS-160"; + this.module = "Hashing"; + this.description = "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.

HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.

The message digest algorithm consists of 80 rounds."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("has160", input); + } + +} + +export default HAS160; diff --git a/src/core/operations/HMAC.mjs b/src/core/operations/HMAC.mjs new file mode 100644 index 00000000..e29656ce --- /dev/null +++ b/src/core/operations/HMAC.mjs @@ -0,0 +1,87 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import CryptoApi from "crypto-api/src/crypto-api"; + +/** + * HMAC operation + */ +class HMAC extends Operation { + + /** + * HMAC constructor + */ + constructor() { + super(); + + this.name = "HMAC"; + this.module = "Hashing"; + this.description = "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "binaryString", + "value": "" + }, + { + "name": "Hashing function", + "type": "option", + "value": [ + "MD2", + "MD4", + "MD5", + "SHA0", + "SHA1", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA512/224", + "SHA512/256", + "RIPEMD128", + "RIPEMD160", + "RIPEMD256", + "RIPEMD320", + "HAS160", + "Whirlpool", + "Whirlpool-0", + "Whirlpool-T", + "Snefru" + ] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const key = args[0], + hashFunc = args[1].toLowerCase(), + msg = Utils.arrayBufferToStr(input, false), + hasher = CryptoApi.getHasher(hashFunc); + + // Horrible shim to fix constructor bug. Reported in nf404/crypto-api#8 + hasher.reset = () => { + hasher.state = {}; + const tmp = new hasher.constructor(); + hasher.state = tmp.state; + }; + + const mac = CryptoApi.getHmac(CryptoApi.encoder.fromUtf(key), hasher); + mac.update(msg); + return CryptoApi.encoder.toHex(mac.finalize()); + } + +} + +export default HMAC; diff --git a/src/core/operations/HTTPRequest.mjs b/src/core/operations/HTTPRequest.mjs new file mode 100644 index 00000000..6846f97a --- /dev/null +++ b/src/core/operations/HTTPRequest.mjs @@ -0,0 +1,146 @@ +/** + * @author tlwr [toby@toby.codes] + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * HTTP request operation + */ +class HTTPRequest extends Operation { + + /** + * HTTPRequest constructor + */ + constructor() { + super(); + + this.name = "HTTP request"; + this.module = "Default"; + this.description = [ + "Makes an HTTP request and returns the response.", + "

", + "This operation supports different HTTP verbs like GET, POST, PUT, etc.", + "

", + "You can add headers line by line in the format Key: Value", + "

", + "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.", + ].join("\n"); + this.inputType = "string"; + this.outputType = "string"; + this.manualBake = true; + this.args = [ + { + "name": "Method", + "type": "option", + "value": [ + "GET", "POST", "HEAD", + "PUT", "PATCH", "DELETE", + "CONNECT", "TRACE", "OPTIONS" + ] + }, + { + "name": "URL", + "type": "string", + "value": "" + }, + { + "name": "Headers", + "type": "text", + "value": "" + }, + { + "name": "Mode", + "type": "option", + "value": [ + "Cross-Origin Resource Sharing", + "No CORS (limited to HEAD, GET or POST)", + ] + }, + { + "name": "Show response metadata", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [method, url, headersText, mode, showResponseMetadata] = args; + + if (url.length === 0) return ""; + + const headers = new Headers(); + headersText.split(/\r?\n/).forEach(line => { + line = line.trim(); + + if (line.length === 0) return; + + const split = line.split(":"); + if (split.length !== 2) throw `Could not parse header in line: ${line}`; + + headers.set(split[0].trim(), split[1].trim()); + }); + + const config = { + method: method, + headers: headers, + mode: modeLookup[mode], + cache: "no-cache", + }; + + if (method !== "GET" && method !== "HEAD") { + config.body = input; + } + + return fetch(url, config) + .then(r => { + if (r.status === 0 && r.type === "opaque") { + throw new OperationError("Error: Null response. Try setting the connection mode to CORS."); + } + + if (showResponseMetadata) { + let headers = ""; + for (const pair of r.headers.entries()) { + headers += " " + pair[0] + ": " + pair[1] + "\n"; + } + return r.text().then(b => { + return "####\n Status: " + r.status + " " + r.statusText + + "\n Exposed headers:\n" + headers + "####\n\n" + b; + }); + } + return r.text(); + }) + .catch(e => { + throw new OperationError(e.toString() + + "\n\nThis error could be caused by one of the following:\n" + + " - An invalid URL\n" + + " - Making a request to an insecure resource (HTTP) from a secure source (HTTPS)\n" + + " - Making a cross-origin request to a server which does not support CORS\n"); + }); + } + +} + + +/** + * Lookup table for HTTP modes + * + * @private + */ +const modeLookup = { + "Cross-Origin Resource Sharing": "cors", + "No CORS (limited to HEAD, GET or POST)": "no-cors", +}; + + +export default HTTPRequest; diff --git a/src/core/operations/HammingDistance.mjs b/src/core/operations/HammingDistance.mjs new file mode 100644 index 00000000..173ca3e7 --- /dev/null +++ b/src/core/operations/HammingDistance.mjs @@ -0,0 +1,97 @@ +/** + * @author GCHQ Contributor [2] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {fromHex} from "../lib/Hex"; +import OperationError from "../errors/OperationError"; + +/** + * Hamming Distance operation + */ +class HammingDistance extends Operation { + + /** + * HammingDistance constructor + */ + constructor() { + super(); + + this.name = "Hamming Distance"; + this.module = "Default"; + this.description = "In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other. In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "binaryShortString", + "value": "\\n\\n" + }, + { + "name": "Unit", + "type": "option", + "value": ["Byte", "Bit"] + }, + { + "name": "Input type", + "type": "option", + "value": ["Raw string", "Hex"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = args[0], + byByte = args[1] === "Byte", + inputType = args[2], + samples = input.split(delim); + + if (samples.length !== 2) { + throw new OperationError("Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter."); + } + + if (samples[0].length !== samples[1].length) { + throw new OperationError("Error: Both inputs must be of the same length."); + } + + if (inputType === "Hex") { + samples[0] = fromHex(samples[0]); + samples[1] = fromHex(samples[1]); + } else { + samples[0] = Utils.strToByteArray(samples[0]); + samples[1] = Utils.strToByteArray(samples[1]); + } + + let dist = 0; + + for (let i = 0; i < samples[0].length; i++) { + const lhs = samples[0][i], + rhs = samples[1][i]; + + if (byByte && lhs !== rhs) { + dist++; + } else if (!byByte) { + let xord = lhs ^ rhs; + + while (xord) { + dist++; + xord &= xord - 1; + } + } + } + + return dist.toString(); + } + +} + +export default HammingDistance; diff --git a/src/core/operations/Head.mjs b/src/core/operations/Head.mjs new file mode 100644 index 00000000..76e17c59 --- /dev/null +++ b/src/core/operations/Head.mjs @@ -0,0 +1,68 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * Head operation + */ +class Head extends Operation { + + /** + * Head constructor + */ + constructor() { + super(); + + this.name = "Head"; + this.module = "Default"; + this.description = "Like the UNIX head utility.
Gets the first n lines.
You can select all but the last n lines by entering a negative value for n.
The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": INPUT_DELIM_OPTIONS + }, + { + "name": "Number", + "type": "number", + "value": 10 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let delimiter = args[0]; + const number = args[1]; + + delimiter = Utils.charRep(delimiter); + const splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (number < 0) { + return lineIndex <= splitInput.length + number; + } else { + return lineIndex <= number; + } + }) + .join(delimiter); + } + +} + +export default Head; diff --git a/src/core/operations/Jump.mjs b/src/core/operations/Jump.mjs new file mode 100644 index 00000000..30fca5a0 --- /dev/null +++ b/src/core/operations/Jump.mjs @@ -0,0 +1,65 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { getLabelIndex } from "../lib/FlowControl"; + +/** + * Jump operation + */ +class Jump extends Operation { + + /** + * Jump constructor + */ + constructor() { + super(); + + this.name = "Jump"; + this.flowControl = true; + this.module = "Default"; + this.description = "Jump forwards or backwards to the specified Label"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Label name", + "type": "string", + "value": "" + }, + { + "name": "Maximum jumps (if jumping backwards)", + "type": "number", + "value": 10 + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @param {number} state.numJumps - The number of jumps taken so far. + * @returns {Object} The updated state of the recipe. + */ + run(state) { + const ings = state.opList[state.progress].ingValues; + const [label, maxJumps] = ings; + const jmpIndex = getLabelIndex(label, state); + + if (state.numJumps >= maxJumps || jmpIndex === -1) { + return state; + } + + state.progress = jmpIndex; + state.numJumps++; + return state; + } + +} + +export default Jump; diff --git a/src/core/operations/Keccak.mjs b/src/core/operations/Keccak.mjs new file mode 100644 index 00000000..cfe5dd8a --- /dev/null +++ b/src/core/operations/Keccak.mjs @@ -0,0 +1,67 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import JSSHA3 from "js-sha3"; +import OperationError from "../errors/OperationError"; + +/** + * Keccak operation + */ +class Keccak extends Operation { + + /** + * Keccak constructor + */ + constructor() { + super(); + + this.name = "Keccak"; + this.module = "Hashing"; + this.description = "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Micha\xebl Peeters, and Gilles Van Assche, building upon RadioGat\xfan. It was selected as the winner of the SHA-3 design competition.

This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Size", + "type": "option", + "value": ["512", "384", "256", "224"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const size = parseInt(args[0], 10); + let algo; + + switch (size) { + case 224: + algo = JSSHA3.keccak224; + break; + case 384: + algo = JSSHA3.keccak384; + break; + case 256: + algo = JSSHA3.keccak256; + break; + case 512: + algo = JSSHA3.keccak512; + break; + default: + throw new OperationError("Invalid size"); + } + + return algo(input); + } + +} + +export default Keccak; diff --git a/src/core/operations/Label.mjs b/src/core/operations/Label.mjs new file mode 100644 index 00000000..1444f3ac --- /dev/null +++ b/src/core/operations/Label.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Label operation. For use with Jump and Conditional Jump. + */ +class Label extends Operation { + + /** + * Label constructor + */ + constructor() { + super(); + + this.name = "Label"; + this.flowControl = true; + this.module = "Default"; + this.description = "Provides a location for conditional and fixed jumps to redirect execution to."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Name", + "type": "shortString", + "value": "" + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + run(state) { + return state; + } + +} + +export default Label; diff --git a/src/core/operations/MD2.mjs b/src/core/operations/MD2.mjs new file mode 100644 index 00000000..ab21a397 --- /dev/null +++ b/src/core/operations/MD2.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * MD2 operation + */ +class MD2 extends Operation { + + /** + * MD2 constructor + */ + constructor() { + super(); + + this.name = "MD2"; + this.module = "Hashing"; + this.description = "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.

Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("md2", input); + } + +} + +export default MD2; diff --git a/src/core/operations/MD4.mjs b/src/core/operations/MD4.mjs new file mode 100644 index 00000000..52712580 --- /dev/null +++ b/src/core/operations/MD4.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * MD4 operation + */ +class MD4 extends Operation { + + /** + * MD4 constructor + */ + constructor() { + super(); + + this.name = "MD4"; + this.module = "Hashing"; + this.description = "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.

The security of MD4 has been severely compromised."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("md4", input); + } + +} + +export default MD4; diff --git a/src/core/operations/MD5.mjs b/src/core/operations/MD5.mjs new file mode 100644 index 00000000..692f0f96 --- /dev/null +++ b/src/core/operations/MD5.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * MD5 operation + */ +class MD5 extends Operation { + + /** + * MD5 constructor + */ + constructor() { + super(); + + this.name = "MD5"; + this.module = "Hashing"; + this.description = "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.

However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("md5", input); + } + +} + +export default MD5; diff --git a/src/core/operations/MD6.mjs b/src/core/operations/MD6.mjs new file mode 100644 index 00000000..2d12cc27 --- /dev/null +++ b/src/core/operations/MD6.mjs @@ -0,0 +1,64 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; +import NodeMD6 from "node-md6"; + +/** + * MD6 operation + */ +class MD6 extends Operation { + + /** + * MD6 constructor + */ + constructor() { + super(); + + this.name = "MD6"; + this.module = "Hashing"; + this.description = "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Size", + "type": "number", + "value": 256 + }, + { + "name": "Levels", + "type": "number", + "value": 64 + }, + { + "name": "Key", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [size, levels, key] = args; + + if (size < 0 || size > 512) + throw new OperationError("Size must be between 0 and 512"); + if (levels < 0) + throw new OperationError("Levels must be greater than 0"); + + return NodeMD6.getHashOfText(input, size, key, levels); + } + +} + +export default MD6; diff --git a/src/core/operations/Magic.mjs b/src/core/operations/Magic.mjs new file mode 100644 index 00000000..849fbc8e --- /dev/null +++ b/src/core/operations/Magic.mjs @@ -0,0 +1,140 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import Dish from "../Dish"; +import MagicLib from "../lib/Magic"; + +/** + * Magic operation + */ +class Magic extends Operation { + + /** + * Magic constructor + */ + constructor() { + super(); + + this.name = "Magic"; + this.flowControl = true; + this.module = "Default"; + this.description = "The Magic operation attempts to detect various properties of the input data and suggests which operations could help to make more sense of it.

Options
Depth: If an operation appears to match the data, it will be run and the result will be analysed further. This argument controls the maximum number of levels of recursion.

Intensive mode: When this is turned on, various operations like XOR, bit rotates, and character encodings are brute-forced to attempt to detect valid data underneath. To improve performance, only the first 100 bytes of the data is brute-forced.

Extensive language support: At each stage, the relative byte frequencies of the data will be compared to average frequencies for a number of languages. The default set consists of ~40 of the most commonly used languages on the Internet. The extensive list consists of 284 languages and can result in many languages matching the data if their byte frequencies are similar."; + this.inputType = "ArrayBuffer"; + this.outputType = "html"; + this.args = [ + { + "name": "Depth", + "type": "number", + "value": 3 + }, + { + "name": "Intensive mode", + "type": "boolean", + "value": false + }, + { + "name": "Extensive language support", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + async run(state) { + const ings = state.opList[state.progress].ingValues, + [depth, intensive, extLang] = ings, + dish = state.dish, + currentRecipeConfig = state.opList.map(op => op.config), + magic = new MagicLib(await dish.get(Dish.ARRAY_BUFFER)), + options = await magic.speculativeExecution(depth, extLang, intensive); + + let output = ` + + + + + `; + + /** + * Returns a CSS colour value based on an integer input. + * + * @param {number} val + * @returns {string} + */ + function chooseColour(val) { + if (val < 3) return "green"; + if (val < 5) return "goldenrod"; + return "red"; + } + + options.forEach(option => { + // Construct recipe URL + // Replace this Magic op with the generated recipe + const recipeConfig = currentRecipeConfig.slice(0, state.progress) + .concat(option.recipe) + .concat(currentRecipeConfig.slice(state.progress + 1)), + recipeURL = "recipe=" + Utils.encodeURIFragment(Utils.generatePrettyRecipe(recipeConfig)); + + let language = "", + fileType = "", + matchingOps = "", + useful = ""; + const entropy = `Entropy: ${option.entropy.toFixed(2)}`, + validUTF8 = option.isUTF8 ? "Valid UTF8\n" : ""; + + if (option.languageScores[0].probability > 0) { + let likelyLangs = option.languageScores.filter(l => l.probability > 0); + if (likelyLangs.length < 1) likelyLangs = [option.languageScores[0]]; + language = "" + + "Possible languages:\n " + + likelyLangs.map(lang => { + return MagicLib.codeToLanguage(lang.lang); + }).join("\n ") + + "\n"; + } + + if (option.fileType) { + fileType = `File type: ${option.fileType.mime} (${option.fileType.ext})\n`; + } + + if (option.matchingOps.length) { + matchingOps = `Matching ops: ${[...new Set(option.matchingOps.map(op => op.op))].join(", ")}\n`; + } + + if (option.useful) { + useful = "Useful op detected\n"; + } + + output += ` + + + + `; + }); + + output += "
Recipe (click to load)Result snippetProperties
${Utils.generatePrettyRecipe(option.recipe, true)}${Utils.escapeHtml(Utils.printable(Utils.truncate(option.data, 99)))}${language}${fileType}${matchingOps}${useful}${validUTF8}${entropy}
"; + + if (!options.length) { + output = "Nothing of interest could be detected about the input data.\nHave you tried modifying the operation arguments?"; + } + dish.set(output, Dish.HTML); + return state; + } + +} + +export default Magic; diff --git a/src/core/operations/Mean.mjs b/src/core/operations/Mean.mjs new file mode 100644 index 00000000..16342e7a --- /dev/null +++ b/src/core/operations/Mean.mjs @@ -0,0 +1,50 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { mean, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; +import BigNumber from "bignumber.js"; + +/** + * Mean operation + */ +class Mean extends Operation { + + /** + * Mean constructor + */ + constructor() { + super(); + + this.name = "Mean"; + this.module = "Default"; + this.description = "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 .5 becomes 4.75"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = mean(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Mean; diff --git a/src/core/operations/Median.mjs b/src/core/operations/Median.mjs new file mode 100644 index 00000000..b1936fa8 --- /dev/null +++ b/src/core/operations/Median.mjs @@ -0,0 +1,50 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { median, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + +/** + * Median operation + */ +class Median extends Operation { + + /** + * Median constructor + */ + constructor() { + super(); + + this.name = "Median"; + this.module = "Default"; + this.description = "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 1 .5 becomes 4.5"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = median(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Median; diff --git a/src/core/operations/Merge.mjs b/src/core/operations/Merge.mjs new file mode 100644 index 00000000..462660c4 --- /dev/null +++ b/src/core/operations/Merge.mjs @@ -0,0 +1,44 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Merge operation + */ +class Merge extends Operation { + + /** + * Merge constructor + */ + constructor() { + super(); + + this.name = "Merge"; + this.flowControl = true; + this.module = "Default"; + this.description = "Consolidate all branches back into a single trunk. The opposite of Fork."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + run(state) { + // No need to actually do anything here. The fork operation will + // merge when it sees this operation. + return state; + } + +} + +export default Merge; diff --git a/src/core/operations/MicrosoftScriptDecoder.mjs b/src/core/operations/MicrosoftScriptDecoder.mjs new file mode 100644 index 00000000..cc9d407f --- /dev/null +++ b/src/core/operations/MicrosoftScriptDecoder.mjs @@ -0,0 +1,217 @@ +/** + * @author bmwhitn [brian.m.whitney@outlook.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Microsoft Script Decoder operation + */ +class MicrosoftScriptDecoder extends Operation { + + /** + * MicrosoftScriptDecoder constructor + */ + constructor() { + super(); + + this.name = "Microsoft Script Decoder"; + this.module = "Default"; + this.description = "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.

Sample

Encoded:
#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&@*eEI@#@&@#@&.jm.raY 214Wv:zms/obI0xEAAA==^#~@

Decoded:
var my_msg = "Testing <1><2><3>!";\n\nVScript.Echo(my_msg);"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const matcher = /#@~\^.{6}==(.+).{6}==\^#~@/; + const encodedData = matcher.exec(input); + if (encodedData){ + return MicrosoftScriptDecoder._decode(encodedData[1]); + } else { + return ""; + } + } + + /** + * Decodes Microsoft Encoded Script files that can be read and executed by cscript.exe/wscript.exe. + * This is a conversion of a Python script that was originally created by Didier Stevens + * (https://DidierStevens.com). + * + * @private + * @param {string} data + * @returns {string} + */ + static _decode(data) { + const result = []; + let index = -1; + data = data.replace(/@&/g, String.fromCharCode(10)) + .replace(/@#/g, String.fromCharCode(13)) + .replace(/@\*/g, ">") + .replace(/@!/g, "<") + .replace(/@\$/g, "@"); + + for (let i = 0; i < data.length; i++) { + const byte = data.charCodeAt(i); + let char = data.charAt(i); + if (byte < 128) { + index++; + } + + if ((byte === 9 || byte > 31 && byte < 128) && + byte !== 60 && + byte !== 62 && + byte !== 64) { + char = D_DECODE[byte].charAt(D_COMBINATION[index % 64]); + } + result.push(char); + } + return result.join(""); + } + +} + +const D_DECODE = [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "\x57\x6E\x7B", + "\x4A\x4C\x41", + "\x0B\x0B\x0B", + "\x0C\x0C\x0C", + "\x4A\x4C\x41", + "\x0E\x0E\x0E", + "\x0F\x0F\x0F", + "\x10\x10\x10", + "\x11\x11\x11", + "\x12\x12\x12", + "\x13\x13\x13", + "\x14\x14\x14", + "\x15\x15\x15", + "\x16\x16\x16", + "\x17\x17\x17", + "\x18\x18\x18", + "\x19\x19\x19", + "\x1A\x1A\x1A", + "\x1B\x1B\x1B", + "\x1C\x1C\x1C", + "\x1D\x1D\x1D", + "\x1E\x1E\x1E", + "\x1F\x1F\x1F", + "\x2E\x2D\x32", + "\x47\x75\x30", + "\x7A\x52\x21", + "\x56\x60\x29", + "\x42\x71\x5B", + "\x6A\x5E\x38", + "\x2F\x49\x33", + "\x26\x5C\x3D", + "\x49\x62\x58", + "\x41\x7D\x3A", + "\x34\x29\x35", + "\x32\x36\x65", + "\x5B\x20\x39", + "\x76\x7C\x5C", + "\x72\x7A\x56", + "\x43\x7F\x73", + "\x38\x6B\x66", + "\x39\x63\x4E", + "\x70\x33\x45", + "\x45\x2B\x6B", + "\x68\x68\x62", + "\x71\x51\x59", + "\x4F\x66\x78", + "\x09\x76\x5E", + "\x62\x31\x7D", + "\x44\x64\x4A", + "\x23\x54\x6D", + "\x75\x43\x71", + "\x4A\x4C\x41", + "\x7E\x3A\x60", + "\x4A\x4C\x41", + "\x5E\x7E\x53", + "\x40\x4C\x40", + "\x77\x45\x42", + "\x4A\x2C\x27", + "\x61\x2A\x48", + "\x5D\x74\x72", + "\x22\x27\x75", + "\x4B\x37\x31", + "\x6F\x44\x37", + "\x4E\x79\x4D", + "\x3B\x59\x52", + "\x4C\x2F\x22", + "\x50\x6F\x54", + "\x67\x26\x6A", + "\x2A\x72\x47", + "\x7D\x6A\x64", + "\x74\x39\x2D", + "\x54\x7B\x20", + "\x2B\x3F\x7F", + "\x2D\x38\x2E", + "\x2C\x77\x4C", + "\x30\x67\x5D", + "\x6E\x53\x7E", + "\x6B\x47\x6C", + "\x66\x34\x6F", + "\x35\x78\x79", + "\x25\x5D\x74", + "\x21\x30\x43", + "\x64\x23\x26", + "\x4D\x5A\x76", + "\x52\x5B\x25", + "\x63\x6C\x24", + "\x3F\x48\x2B", + "\x7B\x55\x28", + "\x78\x70\x23", + "\x29\x69\x41", + "\x28\x2E\x34", + "\x73\x4C\x09", + "\x59\x21\x2A", + "\x33\x24\x44", + "\x7F\x4E\x3F", + "\x6D\x50\x77", + "\x55\x09\x3B", + "\x53\x56\x55", + "\x7C\x73\x69", + "\x3A\x35\x61", + "\x5F\x61\x63", + "\x65\x4B\x50", + "\x46\x58\x67", + "\x58\x3B\x51", + "\x31\x57\x49", + "\x69\x22\x4F", + "\x6C\x6D\x46", + "\x5A\x4D\x68", + "\x48\x25\x7C", + "\x27\x28\x36", + "\x5C\x46\x70", + "\x3D\x4A\x6E", + "\x24\x32\x7A", + "\x79\x41\x2F", + "\x37\x3D\x5F", + "\x60\x5F\x4B", + "\x51\x4F\x5A", + "\x20\x42\x2C", + "\x36\x65\x57" +]; + +const D_COMBINATION = [ + 0, 1, 2, 0, 1, 2, 1, 2, 2, 1, 2, 1, 0, 2, 1, 2, 0, 2, 1, 2, 0, 0, 1, 2, 2, 1, 0, 2, 1, 2, 2, 1, + 0, 0, 2, 1, 2, 1, 2, 0, 2, 0, 0, 1, 2, 0, 2, 1, 0, 2, 1, 2, 0, 0, 1, 2, 2, 0, 0, 1, 2, 0, 2, 1 +]; + +export default MicrosoftScriptDecoder; diff --git a/src/core/operations/Multiply.mjs b/src/core/operations/Multiply.mjs new file mode 100644 index 00000000..3f78daa4 --- /dev/null +++ b/src/core/operations/Multiply.mjs @@ -0,0 +1,51 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { multi, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + + +/** + * Multiply operation + */ +class Multiply extends Operation { + + /** + * Multiply constructor + */ + constructor() { + super(); + + this.name = "Multiply"; + this.module = "Default"; + this.description = "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 40"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = multi(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Multiply; diff --git a/src/core/operations/Numberwang.mjs b/src/core/operations/Numberwang.mjs new file mode 100644 index 00000000..202e4dc7 --- /dev/null +++ b/src/core/operations/Numberwang.mjs @@ -0,0 +1,100 @@ +/** + * @author Unknown Male 282 + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Numberwang operation. Remain indoors. + */ +class Numberwang extends Operation { + + /** + * Numberwang constructor + */ + constructor() { + super(); + + this.name = "Numberwang"; + this.module = "Default"; + this.description = "Based on the popular gameshow by Mitchell and Webb."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let output; + if (!input) { + output = "Let's play Wangernumb!"; + } else { + const match = input.match(/(f0rty-s1x|shinty-six|filth-hundred and neeb|-?√?\d+(\.\d+)?i?([a-z]?)%?)/i); + if (match) { + if (match[3]) output = match[0] + "! That's AlphaNumericWang!"; + else output = match[0] + "! That's Numberwang!"; + } else { + // That's a bad miss! + output = "Sorry, that's not Numberwang. Let's rotate the board!"; + } + } + + const rand = Math.floor(Math.random() * didYouKnow.length); + return output + "\n\nDid you know: " + didYouKnow[rand]; + } + +} + +/** + * Taken from http://numberwang.wikia.com/wiki/Numberwang_Wikia + * + * @constant + */ +const didYouKnow = [ + "Numberwang, contrary to popular belief, is a fruit and not a vegetable.", + "Robert Webb once got WordWang while presenting an episode of Numberwang.", + "The 6705th digit of pi is Numberwang.", + "Numberwang was invented on a Sevenday.", + "Contrary to popular belief, Albert Einstein always got good grades in Numberwang at school. He once scored ^4$ on a test.", + "680 asteroids have been named after Numberwang.", + "Archimedes is most famous for proclaiming \"That's Numberwang!\" during an epiphany about water displacement he had while taking a bath.", + "Numberwang Day is celebrated in Japan on every day of the year apart from June 6.", + "Biologists recently discovered Numberwang within a strand of human DNA.", + "Numbernot is a special type of non-Numberwang number. It is divisible by 3 and the letter \"y\".", + "Julie once got 612.04 Numberwangs in a single episode of Emmerdale.", + "In India, it is traditional to shout out \"Numberwang!\" instead of checkmate during games of chess.", + "There is a rule on Countdown which states that if you get Numberwang in the numbers round, you automatically win. It has only ever been invoked twice.", + "\"Numberwang\" was the third-most common baby name for a brief period in 1722.", + "\"The Lion King\" was loosely based on Numberwang.", + "\"A Numberwang a day keeps the doctor away\" is how Donny Cosy, the oldest man in the world, explained how he was in such good health at the age of 136.", + "The \"number lock\" button on a keyboard is based on the popular round of the same name in \"Numberwang\".", + "Cambridge became the first university to offer a course in Numberwang in 1567.", + "Schrödinger's Numberwang is a number that has been confusing dentists for centuries.", + "\"Harry Potter and the Numberwang of Numberwang\" was rejected by publishers -41 times before it became a bestseller.", + "\"Numberwang\" is the longest-running British game show in history; it has aired 226 seasons, each containing 19 episodes, which makes a grand total of 132 episodes.", + "The triple Numberwang bonus was discovered by archaeologist Thomas Jefferson in Somerset.", + "Numberwang is illegal in parts of Czechoslovakia.", + "Numberwang was discovered in India in the 12th century.", + "Numberwang has the chemical formula Zn4SO2(HgEs)3.", + "The first pack of cards ever created featured two \"Numberwang\" cards instead of jokers.", + "Julius Caesar was killed by an overdose of Numberwang.", + "The most Numberwang musical note is G#.", + "In 1934, the forty-third Google Doodle promoted the upcoming television show \"Numberwang on Ice\".", + "A recent psychology study found that toddlers were 17% faster at identifying numbers which were Numberwang.", + "There are 700 ways to commit a foul in the television show \"Numberwang\". All 700 of these fouls were committed by Julie in one single episode in 1473.", + "Astronomers suspect God is Numberwang.", + "Numberwang is the official beverage of Canada.", + "In the pilot episode of \"The Price is Right\", if a contestant got the value of an item exactly right they were told \"That's Numberwang!\" and immediately won ₹5.7032.", + "The first person to get three Numberwangs in a row was Madonna.", + "\"Numberwang\" has the code U+46402 in Unicode.", + "The musical note \"Numberwang\" is between D# and E♮.", + "Numberwang was first played on the moon in 1834.", +]; + +export default Numberwang; diff --git a/src/core/operations/OffsetChecker.mjs b/src/core/operations/OffsetChecker.mjs new file mode 100644 index 00000000..07b15d2f --- /dev/null +++ b/src/core/operations/OffsetChecker.mjs @@ -0,0 +1,107 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; + +/** + * Offset checker operation + */ +class OffsetChecker extends Operation { + + /** + * OffsetChecker constructor + */ + constructor() { + super(); + + this.name = "Offset checker"; + this.module = "Default"; + this.description = "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples."; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + "name": "Sample delimiter", + "type": "binaryString", + "value": "\\n\\n" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const sampleDelim = args[0], + samples = input.split(sampleDelim), + outputs = new Array(samples.length); + let i = 0, + s = 0, + match = false, + inMatch = false, + chr; + + if (!samples || samples.length < 2) { + throw new OperationError("Not enough samples, perhaps you need to modify the sample delimiter or add more data?"); + } + + // Initialise output strings + outputs.fill("", 0, samples.length); + + // Loop through each character in the first sample + for (i = 0; i < samples[0].length; i++) { + chr = samples[0][i]; + match = false; + + // Loop through each sample to see if the chars are the same + for (s = 1; s < samples.length; s++) { + if (samples[s][i] !== chr) { + match = false; + break; + } + match = true; + } + + // Write output for each sample + for (s = 0; s < samples.length; s++) { + if (samples[s].length <= i) { + if (inMatch) outputs[s] += "
"; + if (s === samples.length - 1) inMatch = false; + continue; + } + + if (match && !inMatch) { + outputs[s] += "" + Utils.escapeHtml(samples[s][i]); + if (samples[s].length === i + 1) outputs[s] += ""; + if (s === samples.length - 1) inMatch = true; + } else if (!match && inMatch) { + outputs[s] += "
" + Utils.escapeHtml(samples[s][i]); + if (s === samples.length - 1) inMatch = false; + } else { + outputs[s] += Utils.escapeHtml(samples[s][i]); + if (inMatch && samples[s].length === i + 1) { + outputs[s] += "
"; + if (samples[s].length - 1 !== i) inMatch = false; + } + } + + if (samples[0].length - 1 === i) { + if (inMatch) outputs[s] += "
"; + outputs[s] += Utils.escapeHtml(samples[s].substring(i + 1)); + } + } + } + + return outputs.join(sampleDelim); + } + +} + +export default OffsetChecker; diff --git a/src/core/operations/PGPDecrypt.mjs b/src/core/operations/PGPDecrypt.mjs new file mode 100644 index 00000000..4385028d --- /dev/null +++ b/src/core/operations/PGPDecrypt.mjs @@ -0,0 +1,86 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import kbpgp from "kbpgp"; +import { ASP, importPrivateKey } from "../lib/PGP"; +import OperationError from "../errors/OperationError"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * PGP Decrypt operation + */ +class PGPDecrypt extends Operation { + + /** + * PGPDecrypt constructor + */ + constructor() { + super(); + + this.name = "PGP Decrypt"; + this.module = "PGP"; + this.description = [ + "Input: the ASCII-armoured PGP message you want to decrypt.", + "

", + "Arguments: the ASCII-armoured PGP private key of the recipient, ", + "(and the private key password if necessary).", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"); + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Private key of recipient", + "type": "text", + "value": "" + }, + { + "name": "Private key passphrase", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if invalid private key + */ + async run(input, args) { + const encryptedMessage = input, + [privateKey, passphrase] = args, + keyring = new kbpgp.keyring.KeyRing(); + let plaintextMessage; + + if (!privateKey) throw new OperationError("Enter the private key of the recipient."); + + const key = await importPrivateKey(privateKey, passphrase); + keyring.add_key_manager(key); + + try { + plaintextMessage = await promisify(kbpgp.unbox)({ + armored: encryptedMessage, + keyfetch: keyring, + asp: ASP + }); + } catch (err) { + throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`); + } + + return plaintextMessage.toString(); + } + +} + +export default PGPDecrypt; diff --git a/src/core/operations/PGPDecryptAndVerify.mjs b/src/core/operations/PGPDecryptAndVerify.mjs new file mode 100644 index 00000000..cac43f58 --- /dev/null +++ b/src/core/operations/PGPDecryptAndVerify.mjs @@ -0,0 +1,122 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import kbpgp from "kbpgp"; +import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP"; +import OperationError from "../errors/OperationError"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * PGP Decrypt and Verify operation + */ +class PGPDecryptAndVerify extends Operation { + + /** + * PGPDecryptAndVerify constructor + */ + constructor() { + super(); + + this.name = "PGP Decrypt and Verify"; + this.module = "PGP"; + this.description = [ + "Input: the ASCII-armoured encrypted PGP message you want to verify.", + "

", + "Arguments: the ASCII-armoured PGP public key of the signer, ", + "the ASCII-armoured private key of the recipient (and the private key password if necessary).", + "

", + "This operation uses PGP to decrypt and verify an encrypted digital signature.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"); + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Public key of signer", + "type": "text", + "value": "" + }, + { + "name": "Private key of recipient", + "type": "text", + "value": "" + }, + { + "name": "Private key password", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + async run(input, args) { + const signedMessage = input, + [publicKey, privateKey, passphrase] = args, + keyring = new kbpgp.keyring.KeyRing(); + let unboxedLiterals; + + if (!publicKey) throw new OperationError("Enter the public key of the signer."); + if (!privateKey) throw new OperationError("Enter the private key of the recipient."); + const privKey = await importPrivateKey(privateKey, passphrase); + const pubKey = await importPublicKey(publicKey); + keyring.add_key_manager(privKey); + keyring.add_key_manager(pubKey); + + try { + unboxedLiterals = await promisify(kbpgp.unbox)({ + armored: signedMessage, + keyfetch: keyring, + asp: ASP + }); + const ds = unboxedLiterals[0].get_data_signer(); + if (ds) { + const km = ds.get_key_manager(); + if (km) { + const signer = km.get_userids_mark_primary()[0].components; + let text = "Signed by "; + if (signer.email || signer.username || signer.comment) { + if (signer.username) { + text += `${signer.username} `; + } + if (signer.comment) { + text += `${signer.comment} `; + } + if (signer.email) { + text += `<${signer.email}>`; + } + text += "\n"; + } + text += [ + `PGP fingerprint: ${km.get_pgp_fingerprint().toString("hex")}`, + `Signed on ${new Date(ds.sig.hashed_subpackets[0].time * 1000).toUTCString()}`, + "----------------------------------\n" + ].join("\n"); + text += unboxedLiterals.toString(); + return text.trim(); + } else { + throw new OperationError("Could not identify a key manager."); + } + } else { + throw new OperationError("The data does not appear to be signed."); + } + } catch (err) { + throw new OperationError(`Couldn't verify message: ${err}`); + } + } + +} + +export default PGPDecryptAndVerify; diff --git a/src/core/operations/PGPEncrypt.mjs b/src/core/operations/PGPEncrypt.mjs new file mode 100644 index 00000000..dd1f5ff4 --- /dev/null +++ b/src/core/operations/PGPEncrypt.mjs @@ -0,0 +1,85 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import kbpgp from "kbpgp"; +import { ASP } from "../lib/PGP"; +import OperationError from "../errors/OperationError"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * PGP Encrypt operation + */ +class PGPEncrypt extends Operation { + + /** + * PGPEncrypt constructor + */ + constructor() { + super(); + + this.name = "PGP Encrypt"; + this.module = "PGP"; + this.description = [ + "Input: the message you want to encrypt.", + "

", + "Arguments: the ASCII-armoured PGP public key of the recipient.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"); + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Public key of recipient", + "type": "text", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if failed private key import or failed encryption + */ + async run(input, args) { + const plaintextMessage = input, + plainPubKey = args[0]; + let key, + encryptedMessage; + + if (!plainPubKey) throw new OperationError("Enter the public key of the recipient."); + + try { + key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({ + armored: plainPubKey, + }); + } catch (err) { + throw new OperationError(`Could not import public key: ${err}`); + } + + try { + encryptedMessage = await promisify(kbpgp.box)({ + "msg": plaintextMessage, + "encrypt_for": key, + "asp": ASP + }); + } catch (err) { + throw new OperationError(`Couldn't encrypt message with provided public key: ${err}`); + } + + return encryptedMessage.toString(); + } + +} + +export default PGPEncrypt; diff --git a/src/core/operations/PGPEncryptAndSign.mjs b/src/core/operations/PGPEncryptAndSign.mjs new file mode 100644 index 00000000..40c0b211 --- /dev/null +++ b/src/core/operations/PGPEncryptAndSign.mjs @@ -0,0 +1,93 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import kbpgp from "kbpgp"; +import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP"; +import OperationError from "../errors/OperationError"; +import promisifyDefault from "es6-promisify"; +const promisify = promisifyDefault.promisify; + +/** + * PGP Encrypt and Sign operation + */ +class PGPEncryptAndSign extends Operation { + + /** + * PGPEncryptAndSign constructor + */ + constructor() { + super(); + + this.name = "PGP Encrypt and Sign"; + this.module = "PGP"; + this.description = [ + "Input: the cleartext you want to sign.", + "

", + "Arguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)", + "and the ASCII-armoured PGP public key of the recipient.", + "

", + "This operation uses PGP to produce an encrypted digital signature.", + "

", + "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", + "

", + "This function uses the Keybase implementation of PGP.", + ].join("\n"); + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Private key of signer", + "type": "text", + "value": "" + }, + { + "name": "Private key passphrase", + "type": "string", + "value": "" + }, + { + "name": "Public key of recipient", + "type": "text", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if failure to sign message + */ + async run(input, args) { + const message = input, + [privateKey, passphrase, publicKey] = args; + let signedMessage; + + if (!privateKey) throw new OperationError("Enter the private key of the signer."); + if (!publicKey) throw new OperationError("Enter the public key of the recipient."); + const privKey = await importPrivateKey(privateKey, passphrase); + const pubKey = await importPublicKey(publicKey); + + try { + signedMessage = await promisify(kbpgp.box)({ + "msg": message, + "encrypt_for": pubKey, + "sign_with": privKey, + "asp": ASP + }); + } catch (err) { + throw new OperationError(`Couldn't sign message: ${err}`); + } + + return signedMessage; + } + +} + +export default PGPEncryptAndSign; diff --git a/src/core/operations/PHPDeserialize.mjs b/src/core/operations/PHPDeserialize.mjs new file mode 100644 index 00000000..a54c04d2 --- /dev/null +++ b/src/core/operations/PHPDeserialize.mjs @@ -0,0 +1,171 @@ +/** + * @author Jarmo van Lenthe [github.com/jarmovanlenthe] + * @copyright Jarmo van Lenthe + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * PHP Deserialize operation + */ +class PHPDeserialize extends Operation { + + /** + * PHPDeserialize constructor + */ + constructor() { + super(); + + this.name = "PHP Deserialize"; + this.module = "Default"; + this.description = "Deserializes PHP serialized data, outputting keyed arrays as JSON.

This function does not support object tags.

Example:
a:2:{s:1:"a";i:10;i:0;a:1:{s:2:"ab";b:1;}}
becomes
{"a": 10,0: {"ab": true}}

Output valid JSON: JSON doesn't support integers as keys, whereas PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Output valid JSON", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + /** + * Recursive method for deserializing. + * @returns {*} + */ + function handleInput() { + /** + * Read `length` characters from the input, shifting them out the input. + * @param length + * @returns {string} + */ + function read(length) { + let result = ""; + for (let idx = 0; idx < length; idx++) { + const char = inputPart.shift(); + if (char === undefined) { + throw new OperationError("End of input reached before end of script"); + } + result += char; + } + return result; + } + + /** + * Read characters from the input until `until` is found. + * @param until + * @returns {string} + */ + function readUntil(until) { + let result = ""; + for (;;) { + const char = read(1); + if (char === until) { + break; + } else { + result += char; + } + } + return result; + + } + + /** + * Read characters from the input that must be equal to `expect` + * @param expect + * @returns {string} + */ + function expect(expect) { + const result = read(expect.length); + if (result !== expect) { + throw new OperationError("Unexpected input found"); + } + return result; + } + + /** + * Helper function to handle deserialized arrays. + * @returns {Array} + */ + function handleArray() { + const items = parseInt(readUntil(":"), 10) * 2; + expect("{"); + const result = []; + let isKey = true; + let lastItem = null; + for (let idx = 0; idx < items; idx++) { + const item = handleInput(); + if (isKey) { + lastItem = item; + isKey = false; + } else { + const numberCheck = lastItem.match(/[0-9]+/); + if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) { + result.push("\"" + lastItem + "\": " + item); + } else { + result.push(lastItem + ": " + item); + } + isKey = true; + } + } + expect("}"); + return result; + } + + + const kind = read(1).toLowerCase(); + + switch (kind) { + case "n": + expect(";"); + return ""; + + case "i": + case "d": + case "b": { + expect(":"); + const data = readUntil(";"); + if (kind === "b") { + return (parseInt(data, 10) !== 0); + } + return data; + } + + case "a": + expect(":"); + return "{" + handleArray() + "}"; + + case "s": { + expect(":"); + const length = readUntil(":"); + expect("\""); + const value = read(length); + expect("\";"); + if (args[0]) { + return "\"" + value.replace(/"/g, "\\\"") + "\""; + } else { + return "\"" + value + "\""; + } + } + + default: + throw new OperationError("Unknown type: " + kind); + } + } + + const inputPart = input.split(""); + return handleInput(); + } + +} + +export default PHPDeserialize; diff --git a/src/core/operations/PadLines.mjs b/src/core/operations/PadLines.mjs new file mode 100644 index 00000000..e9e2b45a --- /dev/null +++ b/src/core/operations/PadLines.mjs @@ -0,0 +1,70 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Pad lines operation + */ +class PadLines extends Operation { + + /** + * PadLines constructor + */ + constructor() { + super(); + + this.name = "Pad lines"; + this.module = "Default"; + this.description = "Add the specified number of the specified character to the beginning or end of each line"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Position", + "type": "option", + "value": ["Start", "End"] + }, + { + "name": "Length", + "type": "number", + "value": 5 + }, + { + "name": "Character", + "type": "binaryShortString", + "value": " " + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [position, len, chr] = args, + lines = input.split("\n"); + let output = "", + i = 0; + + if (position === "Start") { + for (i = 0; i < lines.length; i++) { + output += lines[i].padStart(lines[i].length+len, chr) + "\n"; + } + } else if (position === "End") { + for (i = 0; i < lines.length; i++) { + output += lines[i].padEnd(lines[i].length+len, chr) + "\n"; + } + } + + return output.slice(0, output.length-1); + } + +} + +export default PadLines; diff --git a/src/core/operations/ParseColourCode.mjs b/src/core/operations/ParseColourCode.mjs new file mode 100644 index 00000000..a80e3b3a --- /dev/null +++ b/src/core/operations/ParseColourCode.mjs @@ -0,0 +1,195 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Parse colour code operation + */ +class ParseColourCode extends Operation { + + /** + * ParseColourCode constructor + */ + constructor() { + super(); + + this.name = "Parse colour code"; + this.module = "Default"; + this.description = "Converts a colour code in a standard format to other standard formats and displays the colour itself.

Example inputs"; + this.inputType = "string"; + this.outputType = "html"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + let m = null, + r = 0, g = 0, b = 0, a = 1; + + // Read in the input + if ((m = input.match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i))) { + // Hex - #d9edf7 + r = parseInt(m[1], 16); + g = parseInt(m[2], 16); + b = parseInt(m[3], 16); + } else if ((m = input.match(/rgba?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)(?:,\s?(\d(?:\.\d+)?))?\)/i))) { + // RGB or RGBA - rgb(217,237,247) or rgba(217,237,247,1) + r = parseFloat(m[1]); + g = parseFloat(m[2]); + b = parseFloat(m[3]); + a = m[4] ? parseFloat(m[4]) : 1; + } else if ((m = input.match(/hsla?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)%,\s?(\d{1,3}(?:\.\d+)?)%(?:,\s?(\d(?:\.\d+)?))?\)/i))) { + // HSL or HSLA - hsl(200, 65%, 91%) or hsla(200, 65%, 91%, 1) + const h_ = parseFloat(m[1]) / 360, + s_ = parseFloat(m[2]) / 100, + l_ = parseFloat(m[3]) / 100, + rgb_ = ParseColourCode._hslToRgb(h_, s_, l_); + + r = rgb_[0]; + g = rgb_[1]; + b = rgb_[2]; + a = m[4] ? parseFloat(m[4]) : 1; + } else if ((m = input.match(/cmyk\((\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?)\)/i))) { + // CMYK - cmyk(0.12, 0.04, 0.00, 0.03) + const c_ = parseFloat(m[1]), + m_ = parseFloat(m[2]), + y_ = parseFloat(m[3]), + k_ = parseFloat(m[4]); + + r = Math.round(255 * (1 - c_) * (1 - k_)); + g = Math.round(255 * (1 - m_) * (1 - k_)); + b = Math.round(255 * (1 - y_) * (1 - k_)); + } + + const hsl_ = ParseColourCode._rgbToHsl(r, g, b), + h = Math.round(hsl_[0] * 360), + s = Math.round(hsl_[1] * 100), + l = Math.round(hsl_[2] * 100); + let k = 1 - Math.max(r/255, g/255, b/255), + c = (1 - r/255 - k) / (1 - k), + y = (1 - b/255 - k) / (1 - k); + + m = (1 - g/255 - k) / (1 - k); + + c = isNaN(c) ? "0" : c.toFixed(2); + m = isNaN(m) ? "0" : m.toFixed(2); + y = isNaN(y) ? "0" : y.toFixed(2); + k = k.toFixed(2); + + const hex = "#" + + Math.round(r).toString(16).padStart(2, "0") + + Math.round(g).toString(16).padStart(2, "0") + + Math.round(b).toString(16).padStart(2, "0"), + rgb = "rgb(" + r + ", " + g + ", " + b + ")", + rgba = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")", + hsl = "hsl(" + h + ", " + s + "%, " + l + "%)", + hsla = "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")", + cmyk = "cmyk(" + c + ", " + m + ", " + y + ", " + k + ")"; + + // Generate output + return `
+Hex: ${hex} +RGB: ${rgb} +RGBA: ${rgba} +HSL: ${hsl} +HSLA: ${hsla} +CMYK: ${cmyk} +`; + } + + /** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_colorSpace. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @author Mohsen (http://stackoverflow.com/a/9493060) + * + * @param {number} h - The hue + * @param {number} s - The saturation + * @param {number} l - The lightness + * @return {Array} The RGB representation + */ + static _hslToRgb(h, s, l) { + let r, g, b; + + if (s === 0){ + r = g = b = l; // achromatic + } else { + const hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1/6) return p + (q - p) * 6 * t; + if (t < 1/2) return q; + if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + }; + + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + } + + /** + * Converts an RGB color value to HSL. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_colorSpace. + * Assumes r, g, and b are contained in the set [0, 255] and + * returns h, s, and l in the set [0, 1]. + * + * @author Mohsen (http://stackoverflow.com/a/9493060) + * + * @param {number} r - The red color value + * @param {number} g - The green color value + * @param {number} b - The blue color value + * @return {Array} The HSL representation + */ + static _rgbToHsl(r, g, b) { + r /= 255; g /= 255; b /= 255; + const max = Math.max(r, g, b), + min = Math.min(r, g, b), + l = (max + min) / 2; + let h, s; + + if (max === min) { + h = s = 0; // achromatic + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return [h, s, l]; + } +} + +export default ParseColourCode; diff --git a/src/core/operations/ParseDateTime.mjs b/src/core/operations/ParseDateTime.mjs new file mode 100644 index 00000000..bb88c95d --- /dev/null +++ b/src/core/operations/ParseDateTime.mjs @@ -0,0 +1,83 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import moment from "moment-timezone"; +import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime"; +import OperationError from "../errors/OperationError"; + +/** + * Parse DateTime operation + */ +class ParseDateTime extends Operation { + + /** + * ParseDateTime constructor + */ + constructor() { + super(); + + this.name = "Parse DateTime"; + this.module = "Default"; + this.description = "Parses a DateTime string in your specified format and displays it in whichever timezone you choose with the following information:Run with no input to see format string examples if required."; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + "name": "Built in formats", + "type": "populateOption", + "value": DATETIME_FORMATS, + "target": 1 + }, + { + "name": "Input format string", + "type": "binaryString", + "value": "DD/MM/YYYY HH:mm:ss" + }, + { + "name": "Input timezone", + "type": "option", + "value": ["UTC"].concat(moment.tz.names()) + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const inputFormat = args[1], + inputTimezone = args[2]; + let date, + output = ""; + + try { + date = moment.tz(input, inputFormat, inputTimezone); + if (!date || date.format() === "Invalid date") throw Error; + } catch (err) { + throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`); + } + + output += "Date: " + date.format("dddd Do MMMM YYYY") + + "\nTime: " + date.format("HH:mm:ss") + + "\nPeriod: " + date.format("A") + + "\nTimezone: " + date.format("z") + + "\nUTC offset: " + date.format("ZZ") + + "\n\nDaylight Saving Time: " + date.isDST() + + "\nLeap year: " + date.isLeapYear() + + "\nDays in this month: " + date.daysInMonth() + + "\n\nDay of year: " + date.dayOfYear() + + "\nWeek number: " + date.weekYear() + + "\nQuarter: " + date.quarter(); + + return output; + } + +} + +export default ParseDateTime; diff --git a/src/core/operations/ParseUNIXFilePermissions.mjs b/src/core/operations/ParseUNIXFilePermissions.mjs new file mode 100644 index 00000000..a86ed9ce --- /dev/null +++ b/src/core/operations/ParseUNIXFilePermissions.mjs @@ -0,0 +1,324 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Parse UNIX file permissions operation + */ +class ParseUNIXFilePermissions extends Operation { + + /** + * ParseUNIXFilePermissions constructor + */ + constructor() { + super(); + + this.name = "Parse UNIX file permissions"; + this.module = "Default"; + this.description = "Given a UNIX/Linux file permission string in octal or textual format, this operation explains which permissions are granted to which user groups.

Input should be in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const perms = { + d: false, // directory + sl: false, // symbolic link + np: false, // named pipe + s: false, // socket + cd: false, // character device + bd: false, // block device + dr: false, // door + sb: false, // sticky bit + su: false, // setuid + sg: false, // setgid + ru: false, // read user + wu: false, // write user + eu: false, // execute user + rg: false, // read group + wg: false, // write group + eg: false, // execute group + ro: false, // read other + wo: false, // write other + eo: false // execute other + }; + let d = 0, + u = 0, + g = 0, + o = 0, + output = "", + octal = null, + textual = null; + + if (input.search(/\s*[0-7]{1,4}\s*/i) === 0) { + // Input is octal + octal = input.match(/\s*([0-7]{1,4})\s*/i)[1]; + + if (octal.length === 4) { + d = parseInt(octal[0], 8); + u = parseInt(octal[1], 8); + g = parseInt(octal[2], 8); + o = parseInt(octal[3], 8); + } else { + if (octal.length > 0) u = parseInt(octal[0], 8); + if (octal.length > 1) g = parseInt(octal[1], 8); + if (octal.length > 2) o = parseInt(octal[2], 8); + } + + perms.su = d >> 2 & 0x1; + perms.sg = d >> 1 & 0x1; + perms.sb = d & 0x1; + + perms.ru = u >> 2 & 0x1; + perms.wu = u >> 1 & 0x1; + perms.eu = u & 0x1; + + perms.rg = g >> 2 & 0x1; + perms.wg = g >> 1 & 0x1; + perms.eg = g & 0x1; + + perms.ro = o >> 2 & 0x1; + perms.wo = o >> 1 & 0x1; + perms.eo = o & 0x1; + } else if (input.search(/\s*[dlpcbDrwxsStT-]{1,10}\s*/) === 0) { + // Input is textual + textual = input.match(/\s*([dlpcbDrwxsStT-]{1,10})\s*/)[1]; + + switch (textual[0]) { + case "d": + perms.d = true; + break; + case "l": + perms.sl = true; + break; + case "p": + perms.np = true; + break; + case "s": + perms.s = true; + break; + case "c": + perms.cd = true; + break; + case "b": + perms.bd = true; + break; + case "D": + perms.dr = true; + break; + } + + if (textual.length > 1) perms.ru = textual[1] === "r"; + if (textual.length > 2) perms.wu = textual[2] === "w"; + if (textual.length > 3) { + switch (textual[3]) { + case "x": + perms.eu = true; + break; + case "s": + perms.eu = true; + perms.su = true; + break; + case "S": + perms.su = true; + break; + } + } + + if (textual.length > 4) perms.rg = textual[4] === "r"; + if (textual.length > 5) perms.wg = textual[5] === "w"; + if (textual.length > 6) { + switch (textual[6]) { + case "x": + perms.eg = true; + break; + case "s": + perms.eg = true; + perms.sg = true; + break; + case "S": + perms.sg = true; + break; + } + } + + if (textual.length > 7) perms.ro = textual[7] === "r"; + if (textual.length > 8) perms.wo = textual[8] === "w"; + if (textual.length > 9) { + switch (textual[9]) { + case "x": + perms.eo = true; + break; + case "t": + perms.eo = true; + perms.sb = true; + break; + case "T": + perms.sb = true; + break; + } + } + } else { + throw new OperationError("Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format."); + } + + output += "Textual representation: " + permsToStr(perms); + output += "\nOctal representation: " + permsToOctal(perms); + + // File type + if (textual) { + output += "\nFile type: " + ftFromPerms(perms); + } + + // setuid, setgid + if (perms.su) { + output += "\nThe setuid flag is set"; + } + if (perms.sg) { + output += "\nThe setgid flag is set"; + } + + // sticky bit + if (perms.sb) { + output += "\nThe sticky bit is set"; + } + + // Permission matrix + output += ` + + +---------+-------+-------+-------+ + | | User | Group | Other | + +---------+-------+-------+-------+ + | Read | ${perms.ru ? "X" : " "} | ${perms.rg ? "X" : " "} | ${perms.ro ? "X" : " "} | + +---------+-------+-------+-------+ + | Write | ${perms.wu ? "X" : " "} | ${perms.wg ? "X" : " "} | ${perms.wo ? "X" : " "} | + +---------+-------+-------+-------+ + | Execute | ${perms.eu ? "X" : " "} | ${perms.eg ? "X" : " "} | ${perms.eo ? "X" : " "} | + +---------+-------+-------+-------+`; + + return output; + } + +} + + +/** + * Given a permissions object dictionary, generates a textual permissions string. + * + * @param {Object} perms + * @returns {string} + */ +function permsToStr(perms) { + let str = "", + type = "-"; + + if (perms.d) type = "d"; + if (perms.sl) type = "l"; + if (perms.np) type = "p"; + if (perms.s) type = "s"; + if (perms.cd) type = "c"; + if (perms.bd) type = "b"; + if (perms.dr) type = "D"; + + str = type; + + str += perms.ru ? "r" : "-"; + str += perms.wu ? "w" : "-"; + if (perms.eu && perms.su) { + str += "s"; + } else if (perms.su) { + str += "S"; + } else if (perms.eu) { + str += "x"; + } else { + str += "-"; + } + + str += perms.rg ? "r" : "-"; + str += perms.wg ? "w" : "-"; + if (perms.eg && perms.sg) { + str += "s"; + } else if (perms.sg) { + str += "S"; + } else if (perms.eg) { + str += "x"; + } else { + str += "-"; + } + + str += perms.ro ? "r" : "-"; + str += perms.wo ? "w" : "-"; + if (perms.eo && perms.sb) { + str += "t"; + } else if (perms.sb) { + str += "T"; + } else if (perms.eo) { + str += "x"; + } else { + str += "-"; + } + + return str; +} + +/** + * Given a permissions object dictionary, generates an octal permissions string. + * + * @param {Object} perms + * @returns {string} + */ +function permsToOctal(perms) { + let d = 0, + u = 0, + g = 0, + o = 0; + + if (perms.su) d += 4; + if (perms.sg) d += 2; + if (perms.sb) d += 1; + + if (perms.ru) u += 4; + if (perms.wu) u += 2; + if (perms.eu) u += 1; + + if (perms.rg) g += 4; + if (perms.wg) g += 2; + if (perms.eg) g += 1; + + if (perms.ro) o += 4; + if (perms.wo) o += 2; + if (perms.eo) o += 1; + + return d.toString() + u.toString() + g.toString() + o.toString(); +} + + +/** + * Given a permissions object dictionary, returns the file type. + * + * @param {Object} perms + * @returns {string} + */ +function ftFromPerms(perms) { + if (perms.d) return "Directory"; + if (perms.sl) return "Symbolic link"; + if (perms.np) return "Named pipe"; + if (perms.s) return "Socket"; + if (perms.cd) return "Character device"; + if (perms.bd) return "Block device"; + if (perms.dr) return "Door"; + return "Regular file"; +} + +export default ParseUNIXFilePermissions; diff --git a/src/core/operations/ParseURI.mjs b/src/core/operations/ParseURI.mjs new file mode 100644 index 00000000..a272ef53 --- /dev/null +++ b/src/core/operations/ParseURI.mjs @@ -0,0 +1,69 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import url from "url"; + +/** + * Parse URI operation + */ +class ParseURI extends Operation { + + /** + * ParseURI constructor + */ + constructor() { + super(); + + this.name = "Parse URI"; + this.module = "URL"; + this.description = "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const uri = url.parse(input, true); + + let output = ""; + + if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n"; + if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n"; + if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n"; + if (uri.port) output += "Port:\t\t" + uri.port + "\n"; + if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n"; + if (uri.query) { + const keys = Object.keys(uri.query); + let padding = 0; + + keys.forEach(k => { + padding = (k.length > padding) ? k.length : padding; + }); + + output += "Arguments:\n"; + for (const key in uri.query) { + output += "\t" + key.padEnd(padding, " "); + if (uri.query[key].length) { + output += " = " + uri.query[key] + "\n"; + } else { + output += "\n"; + } + } + } + if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n"; + + return output; + } + +} + +export default ParseURI; diff --git a/src/core/operations/ParseUserAgent.mjs b/src/core/operations/ParseUserAgent.mjs new file mode 100644 index 00000000..c1dda3cf --- /dev/null +++ b/src/core/operations/ParseUserAgent.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import UAParser from "ua-parser-js"; + +/** + * Parse User Agent operation + */ +class ParseUserAgent extends Operation { + + /** + * ParseUserAgent constructor + */ + constructor() { + super(); + + this.name = "Parse User Agent"; + this.module = "UserAgent"; + this.description = "Attempts to identify and categorise information contained in a user-agent string."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const ua = UAParser(input); + return `Browser + Name: ${ua.browser.name || "unknown"} + Version: ${ua.browser.version || "unknown"} +Device + Model: ${ua.device.model || "unknown"} + Type: ${ua.device.type || "unknown"} + Vendor: ${ua.device.vendor || "unknown"} +Engine + Name: ${ua.engine.name || "unknown"} + Version: ${ua.engine.version || "unknown"} +OS + Name: ${ua.os.name || "unknown"} + Version: ${ua.os.version || "unknown"} +CPU + Architecture: ${ua.cpu.architecture || "unknown"}`; + } + +} + +export default ParseUserAgent; diff --git a/src/core/operations/PseudoRandomNumberGenerator.mjs b/src/core/operations/PseudoRandomNumberGenerator.mjs new file mode 100644 index 00000000..0b5e45be --- /dev/null +++ b/src/core/operations/PseudoRandomNumberGenerator.mjs @@ -0,0 +1,80 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import forge from "node-forge/dist/forge.min.js"; +import BigNumber from "bignumber.js"; + +/** + * Pseudo-Random Number Generator operation + */ +class PseudoRandomNumberGenerator extends Operation { + + /** + * PseudoRandomNumberGenerator constructor + */ + constructor() { + super(); + + this.name = "Pseudo-Random Number Generator"; + this.module = "Ciphers"; + this.description = "A cryptographically-secure pseudo-random number generator (PRNG).

This operation uses the browser's built-in crypto.getRandomValues() method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Number of bytes", + "type": "number", + "value": 32 + }, + { + "name": "Output as", + "type": "option", + "value": ["Hex", "Integer", "Byte array", "Raw"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [numBytes, outputAs] = args; + + let bytes; + + if (ENVIRONMENT_IS_WORKER() && self.crypto) { + bytes = self.crypto.getRandomValues(new Uint8Array(numBytes)); + bytes = Utils.arrayBufferToStr(bytes.buffer); + } else { + bytes = forge.random.getBytesSync(numBytes); + } + + let value = new BigNumber(0), + i; + + switch (outputAs) { + case "Hex": + return forge.util.bytesToHex(bytes); + case "Integer": + for (i = bytes.length - 1; i >= 0; i--) { + value = value.times(256).plus(bytes.charCodeAt(i)); + } + return value.toFixed(); + case "Byte array": + return JSON.stringify(Utils.strToCharcode(bytes)); + case "Raw": + default: + return bytes; + } + } + +} + +export default PseudoRandomNumberGenerator; diff --git a/src/core/operations/RC4.mjs b/src/core/operations/RC4.mjs new file mode 100644 index 00000000..28968a0a --- /dev/null +++ b/src/core/operations/RC4.mjs @@ -0,0 +1,88 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import CryptoJS from "crypto-js"; +import { format } from "../lib/Ciphers"; + +/** + * RC4 operation + */ +class RC4 extends Operation { + + /** + * RC4 constructor + */ + constructor() { + super(); + + this.name = "RC4"; + this.module = "Ciphers"; + this.description = "RC4 (also known as ARC4) is a widely-used stream cipher designed by Ron Rivest. It is used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Passphrase", + "type": "toggleString", + "value": "", + "toggleValues": ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Hex", "Base64"] + }, + { + "name": "Input format", + "type": "option", + "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] + }, + { + "name": "Output format", + "type": "option", + "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const message = format[args[1]].parse(input), + passphrase = format[args[0].option].parse(args[0].string), + encrypted = CryptoJS.RC4.encrypt(message, passphrase); + + return encrypted.ciphertext.toString(format[args[2]]); + } + + /** + * Highlight RC4 + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight RC4 in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default RC4; diff --git a/src/core/operations/RC4Drop.mjs b/src/core/operations/RC4Drop.mjs new file mode 100644 index 00000000..05f8aca9 --- /dev/null +++ b/src/core/operations/RC4Drop.mjs @@ -0,0 +1,94 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { format } from "../lib/Ciphers"; +import CryptoJS from "crypto-js"; + +/** + * RC4 Drop operation + */ +class RC4Drop extends Operation { + + /** + * RC4Drop constructor + */ + constructor() { + super(); + + this.name = "RC4 Drop"; + this.module = "Ciphers"; + this.description = "It was discovered that the first few bytes of the RC4 keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Passphrase", + "type": "toggleString", + "value": "", + "toggleValues": ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Hex", "Base64"] + }, + { + "name": "Input format", + "type": "option", + "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] + }, + { + "name": "Output format", + "type": "option", + "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] + }, + { + "name": "Number of bytes to drop", + "type": "number", + "value": 768 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const message = format[args[1]].parse(input), + passphrase = format[args[0].option].parse(args[0].string), + drop = args[3], + encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop }); + + return encrypted.ciphertext.toString(format[args[2]]); + } + + /** + * Highlight RC4 Drop + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight RC4 Drop in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default RC4Drop; diff --git a/src/core/operations/RIPEMD.mjs b/src/core/operations/RIPEMD.mjs new file mode 100644 index 00000000..07cfe4b4 --- /dev/null +++ b/src/core/operations/RIPEMD.mjs @@ -0,0 +1,47 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * RIPEMD operation + */ +class RIPEMD extends Operation { + + /** + * RIPEMD constructor + */ + constructor() { + super(); + + this.name = "RIPEMD"; + this.module = "Hashing"; + this.description = "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.

RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.

"; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Size", + "type": "option", + "value": ["320", "256", "160", "128"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const size = args[0]; + return runHash("ripemd" + size, input); + } + +} + +export default RIPEMD; diff --git a/src/core/operations/RawInflate.mjs b/src/core/operations/RawInflate.mjs index 93a7b91f..f1a5341b 100644 --- a/src/core/operations/RawInflate.mjs +++ b/src/core/operations/RawInflate.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation"; import {INFLATE_BUFFER_TYPE} from "../lib/Zlib"; import rawinflate from "zlibjs/bin/rawinflate.min"; +import OperationError from "../errors/OperationError"; const Zlib = rawinflate.Zlib; @@ -90,7 +91,7 @@ class RawInflate extends Operation { } if (!valid) { - throw "Error: Unable to inflate data"; + throw new OperationError("Error: Unable to inflate data"); } } // This seems to be the easiest way... diff --git a/src/core/operations/Register.mjs b/src/core/operations/Register.mjs new file mode 100644 index 00000000..b3a5397f --- /dev/null +++ b/src/core/operations/Register.mjs @@ -0,0 +1,111 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Dish from "../Dish"; + +/** + * Register operation + */ +class Register extends Operation { + + /** + * Register constructor + */ + constructor() { + super(); + + this.name = "Register"; + this.flowControl = true; + this.module = "Default"; + this.description = "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.

To use registers in arguments, refer to them using the notation $Rn where n is the register number, starting at 0.

For example:
Input: Test
Extractor: (.*)
Argument: $R0 becomes Test

Registers can be escaped in arguments using a backslash. e.g. \\$R0 would become $R0 rather than Test."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Extractor", + "type": "binaryString", + "value": "([\\s\\S]*)" + }, + { + "name": "Case insensitive", + "type": "boolean", + "value": true + }, + { + "name": "Multiline matching", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + async run(state) { + const ings = state.opList[state.progress].ingValues; + const [extractorStr, i, m] = ings; + + let modifiers = ""; + if (i) modifiers += "i"; + if (m) modifiers += "m"; + + const extractor = new RegExp(extractorStr, modifiers), + input = await state.dish.get(Dish.STRING), + registers = input.match(extractor); + + if (!registers) return state; + + if (ENVIRONMENT_IS_WORKER()) { + self.setRegisters(state.forkOffset + state.progress, state.numRegisters, registers.slice(1)); + } + + /** + * Replaces references to registers (e.g. $R0) with the contents of those registers. + * + * @param {string} str + * @returns {string} + */ + function replaceRegister(str) { + // Replace references to registers ($Rn) with contents of registers + return str.replace(/(\\*)\$R(\d{1,2})/g, (match, slashes, regNum) => { + const index = parseInt(regNum, 10) + 1; + if (index <= state.numRegisters || index >= state.numRegisters + registers.length) + return match; + if (slashes.length % 2 !== 0) return match.slice(1); // Remove escape + return slashes + registers[index - state.numRegisters]; + }); + } + + // Step through all subsequent ops and replace registers in args with extracted content + for (let i = state.progress + 1; i < state.opList.length; i++) { + if (state.opList[i].disabled) continue; + + let args = state.opList[i].ingValues; + args = args.map(arg => { + if (typeof arg !== "string" && typeof arg !== "object") return arg; + + if (typeof arg === "object" && arg.hasOwnProperty("string")) { + arg.string = replaceRegister(arg.string); + return arg; + } + return replaceRegister(arg); + }); + state.opList[i].ingValues = args; + } + + state.numRegisters += registers.length - 1; + return state; + } + +} + +export default Register; diff --git a/src/core/operations/RemoveLineNumbers.mjs b/src/core/operations/RemoveLineNumbers.mjs new file mode 100644 index 00000000..d7c615f7 --- /dev/null +++ b/src/core/operations/RemoveLineNumbers.mjs @@ -0,0 +1,39 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Remove line numbers operation + */ +class RemoveLineNumbers extends Operation { + + /** + * RemoveLineNumbers constructor + */ + constructor() { + super(); + + this.name = "Remove line numbers"; + this.module = "Default"; + this.description = "Removes line numbers from the output if they can be trivially detected."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return input.replace(/^[ \t]{0,5}\d+[\s:|\-,.)\]]/gm, ""); + } + +} + +export default RemoveLineNumbers; diff --git a/src/core/operations/RemoveNullBytes.mjs b/src/core/operations/RemoveNullBytes.mjs new file mode 100644 index 00000000..dcbf9251 --- /dev/null +++ b/src/core/operations/RemoveNullBytes.mjs @@ -0,0 +1,43 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Remove null bytes operation + */ +class RemoveNullBytes extends Operation { + + /** + * RemoveNullBytes constructor + */ + constructor() { + super(); + + this.name = "Remove null bytes"; + this.module = "Default"; + this.description = "Removes all null bytes (0x00) from the input."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const output = []; + for (let i = 0; i < input.length; i++) { + if (input[i] !== 0) output.push(input[i]); + } + return output; + } + +} + +export default RemoveNullBytes; diff --git a/src/core/operations/RemoveWhitespace.mjs b/src/core/operations/RemoveWhitespace.mjs new file mode 100644 index 00000000..a6564809 --- /dev/null +++ b/src/core/operations/RemoveWhitespace.mjs @@ -0,0 +1,86 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Remove whitespace operation + */ +class RemoveWhitespace extends Operation { + + /** + * RemoveWhitespace constructor + */ + constructor() { + super(); + + this.name = "Remove whitespace"; + this.module = "Default"; + this.description = "Optionally removes all spaces, carriage returns, line feeds, tabs and form feeds from the input data.

This operation also supports the removal of full stops which are sometimes used to represent non-printable bytes in ASCII output."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Spaces", + "type": "boolean", + "value": true + }, + { + "name": "Carriage returns (\\r)", + "type": "boolean", + "value": true + }, + { + "name": "Line feeds (\\n)", + "type": "boolean", + "value": true + }, + { + "name": "Tabs", + "type": "boolean", + "value": true + }, + { + "name": "Form feeds (\\f)", + "type": "boolean", + "value": true + }, + { + "name": "Full stops", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [ + removeSpaces, + removeCariageReturns, + removeLineFeeds, + removeTabs, + removeFormFeeds, + removeFullStops + ] = args; + let data = input; + + if (removeSpaces) data = data.replace(/ /g, ""); + if (removeCariageReturns) data = data.replace(/\r/g, ""); + if (removeLineFeeds) data = data.replace(/\n/g, ""); + if (removeTabs) data = data.replace(/\t/g, ""); + if (removeFormFeeds) data = data.replace(/\f/g, ""); + if (removeFullStops) data = data.replace(/\./g, ""); + return data; + } + +} + +export default RemoveWhitespace; diff --git a/src/core/operations/Return.mjs b/src/core/operations/Return.mjs new file mode 100644 index 00000000..cc83bff8 --- /dev/null +++ b/src/core/operations/Return.mjs @@ -0,0 +1,43 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Return operation + */ +class Return extends Operation { + + /** + * Return constructor + */ + constructor() { + super(); + + this.name = "Return"; + this.flowControl = true; + this.module = "Default"; + this.description = "End execution of operations at this point in the recipe."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {Object} state - The current state of the recipe. + * @param {number} state.progress - The current position in the recipe. + * @param {Dish} state.dish - The Dish being operated on. + * @param {Operation[]} state.opList - The list of operations in the recipe. + * @returns {Object} The updated state of the recipe. + */ + run(state) { + state.progress = state.opList.length; + return state; + } + +} + +export default Return; diff --git a/src/core/operations/Reverse.mjs b/src/core/operations/Reverse.mjs new file mode 100644 index 00000000..c88bb275 --- /dev/null +++ b/src/core/operations/Reverse.mjs @@ -0,0 +1,67 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Reverse operation + */ +class Reverse extends Operation { + + /** + * Reverse constructor + */ + constructor() { + super(); + + this.name = "Reverse"; + this.module = "Default"; + this.description = "Reverses the input string."; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "By", + "type": "option", + "value": ["Character", "Line"] + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + let i; + if (args[0] === "Line") { + const lines = []; + let line = [], + result = []; + for (i = 0; i < input.length; i++) { + if (input[i] === 0x0a) { + lines.push(line); + line = []; + } else { + line.push(input[i]); + } + } + lines.push(line); + lines.reverse(); + for (i = 0; i < lines.length; i++) { + result = result.concat(lines[i]); + result.push(0x0a); + } + return result.slice(0, input.length); + } else { + return input.reverse(); + } + } + +} + +export default Reverse; diff --git a/src/core/operations/SHA0.mjs b/src/core/operations/SHA0.mjs new file mode 100644 index 00000000..292c63ce --- /dev/null +++ b/src/core/operations/SHA0.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * SHA0 operation + */ +class SHA0 extends Operation { + + /** + * SHA0 constructor + */ + constructor() { + super(); + + this.name = "SHA0"; + this.module = "Hashing"; + this.description = "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("sha0", input); + } + +} + +export default SHA0; diff --git a/src/core/operations/SHA1.mjs b/src/core/operations/SHA1.mjs new file mode 100644 index 00000000..904c55f0 --- /dev/null +++ b/src/core/operations/SHA1.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * SHA1 operation + */ +class SHA1 extends Operation { + + /** + * SHA1 constructor + */ + constructor() { + super(); + + this.name = "SHA1"; + this.module = "Hashing"; + this.description = "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.

However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("sha1", input); + } + +} + +export default SHA1; diff --git a/src/core/operations/SHA2.mjs b/src/core/operations/SHA2.mjs new file mode 100644 index 00000000..c5480727 --- /dev/null +++ b/src/core/operations/SHA2.mjs @@ -0,0 +1,47 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * SHA2 operation + */ +class SHA2 extends Operation { + + /** + * SHA2 constructor + */ + constructor() { + super(); + + this.name = "SHA2"; + this.module = "Hashing"; + this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.

"; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Size", + "type": "option", + "value": ["512", "256", "384", "224", "512/256", "512/224"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const size = args[0]; + return runHash("sha" + size, input); + } + +} + +export default SHA2; diff --git a/src/core/operations/SHA3.mjs b/src/core/operations/SHA3.mjs new file mode 100644 index 00000000..9e6b2828 --- /dev/null +++ b/src/core/operations/SHA3.mjs @@ -0,0 +1,67 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import JSSHA3 from "js-sha3"; +import OperationError from "../errors/OperationError"; + +/** + * SHA3 operation + */ +class SHA3 extends Operation { + + /** + * SHA3 constructor + */ + constructor() { + super(); + + this.name = "SHA3"; + this.module = "Hashing"; + this.description = "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.

SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Micha\xebl Peeters, and Gilles Van Assche, building upon RadioGat\xfan."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Size", + "type": "option", + "value": ["512", "384", "256", "224"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const size = parseInt(args[0], 10); + let algo; + + switch (size) { + case 224: + algo = JSSHA3.sha3_224; + break; + case 384: + algo = JSSHA3.sha3_384; + break; + case 256: + algo = JSSHA3.sha3_256; + break; + case 512: + algo = JSSHA3.sha3_512; + break; + default: + throw new OperationError("Invalid size"); + } + + return algo(input); + } + +} + +export default SHA3; diff --git a/src/core/operations/SSDEEP.mjs b/src/core/operations/SSDEEP.mjs new file mode 100644 index 00000000..02d23eba --- /dev/null +++ b/src/core/operations/SSDEEP.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import ssdeepjs from "ssdeep.js"; + +/** + * SSDEEP operation + */ +class SSDEEP extends Operation { + + /** + * SSDEEP constructor + */ + constructor() { + super(); + + this.name = "SSDEEP"; + this.module = "Hashing"; + this.description = "SSDEEP is a program for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

SSDEEP hashes are now widely used for simple identification purposes (e.g. the 'Basic Properties' section in VirusTotal). Although 'better' fuzzy hashes are available, SSDEEP is still one of the primary choices because of its speed and being a de facto standard.

This operation is fundamentally the same as the CTPH operation, however their outputs differ in format."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return ssdeepjs.digest(input); + } + +} + +export default SSDEEP; diff --git a/src/core/operations/ScanForEmbeddedFiles.mjs b/src/core/operations/ScanForEmbeddedFiles.mjs new file mode 100644 index 00000000..abbe7c09 --- /dev/null +++ b/src/core/operations/ScanForEmbeddedFiles.mjs @@ -0,0 +1,85 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import Magic from "../lib/Magic"; + +/** + * Scan for Embedded Files operation + */ +class ScanForEmbeddedFiles extends Operation { + + /** + * ScanForEmbeddedFiles constructor + */ + constructor() { + super(); + + this.name = "Scan for Embedded Files"; + this.module = "Default"; + this.description = "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.

WARNING: Files over about 100KB in size will take a VERY long time to process."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Ignore common byte sequences", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n", + type, + numFound = 0, + numCommonFound = 0; + const ignoreCommon = args[0], + commonExts = ["ico", "ttf", ""], + data = new Uint8Array(input); + + for (let i = 0; i < data.length; i++) { + type = Magic.magicFileType(data.slice(i)); + if (type) { + if (ignoreCommon && commonExts.indexOf(type.ext) > -1) { + numCommonFound++; + continue; + } + numFound++; + output += "\nOffset " + i + " (0x" + Utils.hex(i) + "):\n" + + " File extension: " + type.ext + "\n" + + " MIME type: " + type.mime + "\n"; + + if (type.desc && type.desc.length) { + output += " Description: " + type.desc + "\n"; + } + } + } + + if (numFound === 0) { + output += "\nNo embedded files were found."; + } + + if (numCommonFound > 0) { + output += "\n\n" + numCommonFound; + output += numCommonFound === 1 ? + " file type was detected that has a common byte sequence. This is likely to be a false positive." : + " file types were detected that have common byte sequences. These are likely to be false positives."; + output += " Run this operation with the 'Ignore common byte sequences' option unchecked to see details."; + } + + return output; + } + +} + +export default ScanForEmbeddedFiles; diff --git a/src/core/operations/Scrypt.mjs b/src/core/operations/Scrypt.mjs new file mode 100644 index 00000000..c7624e3c --- /dev/null +++ b/src/core/operations/Scrypt.mjs @@ -0,0 +1,88 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; +import scryptsy from "scryptsy"; + +/** + * Scrypt operation + */ +class Scrypt extends Operation { + + /** + * Scrypt constructor + */ + constructor() { + super(); + + this.name = "Scrypt"; + this.module = "Hashing"; + this.description = "scrypt is a password-based key derivation function (PBKDF) created by Colin Percival. The algorithm was specifically designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory. In 2016, the scrypt algorithm was published by IETF as RFC 7914.

Enter the password in the input to generate its hash."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Salt", + "type": "toggleString", + "value": "", + "toggleValues": ["Hex", "Base64", "UTF8", "Latin1"] + }, + { + "name": "Iterations (N)", + "type": "number", + "value": 16384 + }, + { + "name": "Memory factor (r)", + "type": "number", + "value": 8 + }, + { + "name": "Parallelization factor (p)", + "type": "number", + "value": 1 + }, + { + "name": "Key length", + "type": "number", + "value": 64 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const salt = Utils.convertToByteString(args[0].string || "", args[0].option), + iterations = args[1], + memFactor = args[2], + parallelFactor = args[3], + keyLength = args[4]; + + try { + const data = scryptsy( + input, salt, iterations, memFactor, parallelFactor, keyLength, + p => { + // Progress callback + if (ENVIRONMENT_IS_WORKER()) + self.sendStatusMessage(`Progress: ${p.percent.toFixed(0)}%`); + } + ); + + return data.toString("hex"); + } catch (err) { + throw new OperationError("Error: " + err.toString()); + } + } + +} + +export default Scrypt; diff --git a/src/core/operations/Shake.mjs b/src/core/operations/Shake.mjs new file mode 100644 index 00000000..06914211 --- /dev/null +++ b/src/core/operations/Shake.mjs @@ -0,0 +1,70 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; +import JSSHA3 from "js-sha3"; + +/** + * Shake operation + */ +class Shake extends Operation { + + /** + * Shake constructor + */ + constructor() { + super(); + + this.name = "Shake"; + this.module = "Hashing"; + this.description = "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Capacity", + "type": "option", + "value": ["256", "128"] + }, + { + "name": "Size", + "type": "number", + "value": 512 + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const capacity = parseInt(args[0], 10), + size = args[1]; + let algo; + + if (size < 0) + throw new OperationError("Size must be greater than 0"); + + switch (capacity) { + case 128: + algo = JSSHA3.shake128; + break; + case 256: + algo = JSSHA3.shake256; + break; + default: + throw new OperationError("Invalid size"); + } + + return algo(input, size); + } + +} + +export default Shake; diff --git a/src/core/operations/ShowBase64Offsets.mjs b/src/core/operations/ShowBase64Offsets.mjs index 2f44296f..43bcbbba 100644 --- a/src/core/operations/ShowBase64Offsets.mjs +++ b/src/core/operations/ShowBase64Offsets.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation"; import Utils from "../Utils"; import {fromBase64, toBase64} from "../lib/Base64"; +import OperationError from "../errors/OperationError"; /** * Show Base64 offsets operation @@ -58,7 +59,7 @@ class ShowBase64Offsets extends Operation { script = ""; if (input.length < 1) { - return "Please enter a string."; + throw new OperationError("Please enter a string."); } // Highlight offset 0 diff --git a/src/core/operations/Sleep.mjs b/src/core/operations/Sleep.mjs new file mode 100644 index 00000000..4cd71bfe --- /dev/null +++ b/src/core/operations/Sleep.mjs @@ -0,0 +1,47 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Sleep operation + */ +class Sleep extends Operation { + + /** + * Sleep constructor + */ + constructor() { + super(); + + this.name = "Sleep"; + this.module = "Default"; + this.description = "Sleep causes the recipe to wait for a specified number of milliseconds before continuing execution."; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = [ + { + "name": "Time (ms)", + "type": "number", + "value": 1000 + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + async run(input, args) { + const ms = args[0]; + await new Promise(r => setTimeout(r, ms)); + return input; + } + +} + +export default Sleep; diff --git a/src/core/operations/Snefru.mjs b/src/core/operations/Snefru.mjs new file mode 100644 index 00000000..7f1bbda7 --- /dev/null +++ b/src/core/operations/Snefru.mjs @@ -0,0 +1,54 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * Snefru operation + */ +class Snefru extends Operation { + + /** + * Snefru constructor + */ + constructor() { + super(); + + this.name = "Snefru"; + this.module = "Hashing"; + this.description = "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.

The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Rounds", + "type": "option", + "value": ["8", "4", "2"] + }, + { + "name": "Size", + "type": "option", + "value": ["256", "128"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return runHash("snefru", input, { + rounds: args[0], + length: args[1] + }); + } + +} + +export default Snefru; diff --git a/src/core/operations/Sort.mjs b/src/core/operations/Sort.mjs new file mode 100644 index 00000000..400d2cca --- /dev/null +++ b/src/core/operations/Sort.mjs @@ -0,0 +1,136 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * Sort operation + */ +class Sort extends Operation { + + /** + * Sort constructor + */ + constructor() { + super(); + + this.name = "Sort"; + this.module = "Default"; + this.description = "Alphabetically sorts strings separated by the specified delimiter.

The IP address option supports IPv4 only."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": INPUT_DELIM_OPTIONS + }, + { + "name": "Reverse", + "type": "boolean", + "value": false + }, + { + "name": "Order", + "type": "option", + "value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0]), + sortReverse = args[1], + order = args[2]; + let sorted = input.split(delim); + + if (order === "Alphabetical (case sensitive)") { + sorted = sorted.sort(); + } else if (order === "Alphabetical (case insensitive)") { + sorted = sorted.sort(Sort._caseInsensitiveSort); + } else if (order === "IP address") { + sorted = sorted.sort(Sort._ipSort); + } else if (order === "Numeric") { + sorted = sorted.sort(Sort._numericSort); + } + + if (sortReverse) sorted.reverse(); + return sorted.join(delim); + } + + /** + * Comparison operation for sorting of strings ignoring case. + * + * @private + * @param {string} a + * @param {string} b + * @returns {number} + */ + static _caseInsensitiveSort(a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + } + + + /** + * Comparison operation for sorting of IPv4 addresses. + * + * @private + * @param {string} a + * @param {string} b + * @returns {number} + */ + static _ipSort(a, b) { + let a_ = a.split("."), + b_ = b.split("."); + + a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1; + b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1; + + if (isNaN(a_) && !isNaN(b_)) return 1; + if (!isNaN(a_) && isNaN(b_)) return -1; + if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b); + + return a_ - b_; + } + + /** + * Comparison operation for sorting of numeric values. + * + * @author Chris van Marle + * @private + * @param {string} a + * @param {string} b + * @returns {number} + */ + static _numericSort(a, b) { + const a_ = a.split(/([^\d]+)/), + b_ = b.split(/([^\d]+)/); + + for (let i = 0; i < a_.length && i < b.length; ++i) { + if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers + if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; + if (isNaN(a_[i]) && isNaN(b_[i])) { + const ret = a_[i].localeCompare(b_[i]); // Compare strings + if (ret !== 0) return ret; + } + if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers + if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; + } + } + + return a.localeCompare(b); + } + +} + +export default Sort; diff --git a/src/core/operations/Split.mjs b/src/core/operations/Split.mjs new file mode 100644 index 00000000..88bf8aec --- /dev/null +++ b/src/core/operations/Split.mjs @@ -0,0 +1,55 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {SPLIT_DELIM_OPTIONS, JOIN_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * Split operation + */ +class Split extends Operation { + + /** + * Split constructor + */ + constructor() { + super(); + + this.name = "Split"; + this.module = "Default"; + this.description = "Splits a string into sections around a given delimiter."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Split delimiter", + "type": "editableOption", + "value": SPLIT_DELIM_OPTIONS + }, + { + "name": "Join delimiter", + "type": "editableOption", + "value": JOIN_DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const splitDelim = args[0], + joinDelim = args[1], + sections = input.split(splitDelim); + + return sections.join(joinDelim); + } + +} + +export default Split; diff --git a/src/core/operations/StandardDeviation.mjs b/src/core/operations/StandardDeviation.mjs new file mode 100644 index 00000000..d2da24f8 --- /dev/null +++ b/src/core/operations/StandardDeviation.mjs @@ -0,0 +1,52 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { stdDev, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + + +/** + * Standard Deviation operation + */ +class StandardDeviation extends Operation { + + /** + * StandardDeviation constructor + */ + constructor() { + super(); + + this.name = "Standard Deviation"; + this.module = "Default"; + this.description = "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 4.089281382128433"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = stdDev(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + + } + +} + +export default StandardDeviation; diff --git a/src/core/operations/Strings.mjs b/src/core/operations/Strings.mjs new file mode 100644 index 00000000..d3f110f9 --- /dev/null +++ b/src/core/operations/Strings.mjs @@ -0,0 +1,116 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import XRegExp from "xregexp"; +import { search } from "../lib/Extract"; + +/** + * Strings operation + */ +class Strings extends Operation { + + /** + * Strings constructor + */ + constructor() { + super(); + + this.name = "Strings"; + this.module = "Regex"; + this.description = "Extracts all strings from the input."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Encoding", + "type": "option", + "value": ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"] + }, + { + "name": "Minimum length", + "type": "number", + "value": 4 + }, + { + "name": "Match", + "type": "option", + "value": [ + "[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)", + "[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)" + ] + }, + { + "name": "Display total", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [encoding, minLen, matchType, displayTotal] = args, + alphanumeric = "A-Z\\d", + punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@", + printable = "\x20-\x7e", + uniAlphanumeric = "\\pL\\pN", + uniPunctuation = "\\pP\\pZ", + uniPrintable = "\\pL\\pM\\pZ\\pS\\pN\\pP"; + + let strings = ""; + + switch (matchType) { + case "Alphanumeric + punctuation (A)": + strings = `[${alphanumeric + punctuation}]`; + break; + case "All printable chars (A)": + case "Null-terminated strings (A)": + strings = `[${printable}]`; + break; + case "Alphanumeric + punctuation (U)": + strings = `[${uniAlphanumeric + uniPunctuation}]`; + break; + case "All printable chars (U)": + case "Null-terminated strings (U)": + strings = `[${uniPrintable}]`; + break; + } + + // UTF-16 support is hacked in by allowing null bytes on either side of the matched chars + switch (encoding) { + case "All": + strings = `(\x00?${strings}\x00?)`; + break; + case "16-bit littleendian": + strings = `(${strings}\x00)`; + break; + case "16-bit bigendian": + strings = `(\x00${strings})`; + break; + case "Single byte": + default: + break; + } + + strings = `${strings}{${minLen},}`; + + if (matchType.includes("Null-terminated")) { + strings += "\x00"; + } + + const regex = new XRegExp(strings, "ig"); + + return search(input, regex, null, displayTotal); + } + +} + +export default Strings; diff --git a/src/core/operations/StripHTMLTags.mjs b/src/core/operations/StripHTMLTags.mjs new file mode 100644 index 00000000..f1b7b08e --- /dev/null +++ b/src/core/operations/StripHTMLTags.mjs @@ -0,0 +1,65 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Strip HTML tags operation + */ +class StripHTMLTags extends Operation { + + /** + * StripHTMLTags constructor + */ + constructor() { + super(); + + this.name = "Strip HTML tags"; + this.module = "Default"; + this.description = "Removes all HTML tags from the input."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Remove indentation", + "type": "boolean", + "value": true + }, + { + "name": "Remove excess line breaks", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [removeIndentation, removeLineBreaks] = args; + + input = Utils.stripHtmlTags(input); + + if (removeIndentation) { + input = input.replace(/\n[ \f\t]+/g, "\n"); + } + + if (removeLineBreaks) { + input = input + .replace(/^\s*\n/, "") // first line + .replace(/(\n\s*){2,}/g, "\n"); // all others + } + + return input; + } + +} + +export default StripHTMLTags; diff --git a/src/core/operations/StripHTTPHeaders.mjs b/src/core/operations/StripHTTPHeaders.mjs new file mode 100644 index 00000000..a46e675c --- /dev/null +++ b/src/core/operations/StripHTTPHeaders.mjs @@ -0,0 +1,42 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * Strip HTTP headers operation + */ +class StripHTTPHeaders extends Operation { + + /** + * StripHTTPHeaders constructor + */ + constructor() { + super(); + + this.name = "Strip HTTP headers"; + this.module = "Default"; + this.description = "Removes HTTP headers from a request or response by looking for the first instance of a double newline."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let headerEnd = input.indexOf("\r\n\r\n"); + headerEnd = (headerEnd < 0) ? input.indexOf("\n\n") + 2 : headerEnd + 4; + + return (headerEnd < 2) ? input : input.slice(headerEnd, input.length); + } + +} + +export default StripHTTPHeaders; diff --git a/src/core/operations/Substitute.mjs b/src/core/operations/Substitute.mjs new file mode 100644 index 00000000..c2d114a2 --- /dev/null +++ b/src/core/operations/Substitute.mjs @@ -0,0 +1,65 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Substitute operation + */ +class Substitute extends Operation { + + /** + * Substitute constructor + */ + constructor() { + super(); + + this.name = "Substitute"; + this.module = "Ciphers"; + this.description = "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.

Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.

Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either \n or \x0a.

Byte ranges can be specified using a hyphen. For example, the sequence 0123456789 can be written as 0-9."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Plaintext", + "type": "binaryString", + "value": "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + }, + { + "name": "Ciphertext", + "type": "binaryString", + "value": "XYZABCDEFGHIJKLMNOPQRSTUVW" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const plaintext = Utils.expandAlphRange(args[0]).join(""), + ciphertext = Utils.expandAlphRange(args[1]).join(""); + let output = "", + index = -1; + + if (plaintext.length !== ciphertext.length) { + output = "Warning: Plaintext and Ciphertext lengths differ\n\n"; + } + + for (let i = 0; i < input.length; i++) { + index = plaintext.indexOf(input[i]); + output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]; + } + + return output; + } + +} + +export default Substitute; diff --git a/src/core/operations/Subtract.mjs b/src/core/operations/Subtract.mjs new file mode 100644 index 00000000..ac00156c --- /dev/null +++ b/src/core/operations/Subtract.mjs @@ -0,0 +1,51 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { sub, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + + +/** + * Subtract operation + */ +class Subtract extends Operation { + + /** + * Subtract constructor + */ + constructor() { + super(); + + this.name = "Subtract"; + this.module = "Default"; + this.description = "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 1.5"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = sub(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Subtract; diff --git a/src/core/operations/Sum.mjs b/src/core/operations/Sum.mjs new file mode 100644 index 00000000..97214cda --- /dev/null +++ b/src/core/operations/Sum.mjs @@ -0,0 +1,51 @@ +/** + * @author bwhitn [brian.m.whitney@outlook.com] + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import Operation from "../Operation"; +import { sum, createNumArray } from "../lib/Arithmetic"; +import { ARITHMETIC_DELIM_OPTIONS } from "../lib/Delim"; + + +/** + * Sum operation + */ +class Sum extends Operation { + + /** + * Sum constructor + */ + constructor() { + super(); + + this.name = "Sum"; + this.module = "Default"; + this.description = "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 18.5"; + this.inputType = "string"; + this.outputType = "BigNumber"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": ARITHMETIC_DELIM_OPTIONS, + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {BigNumber} + */ + run(input, args) { + const val = sum(createNumArray(input, args[0])); + return val instanceof BigNumber ? val : new BigNumber(NaN); + } + +} + +export default Sum; diff --git a/src/core/operations/SwapEndianness.mjs b/src/core/operations/SwapEndianness.mjs new file mode 100644 index 00000000..21cd4e9c --- /dev/null +++ b/src/core/operations/SwapEndianness.mjs @@ -0,0 +1,137 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {toHex, fromHex} from "../lib/Hex"; +import OperationError from "../errors/OperationError"; + +/** + * Swap endianness operation + */ +class SwapEndianness extends Operation { + + /** + * SwapEndianness constructor + */ + constructor() { + super(); + + this.name = "Swap endianness"; + this.module = "Default"; + this.description = "Switches the data from big-endian to little-endian or vice-versa. Data can be read in as hexadecimal or raw bytes. It will be returned in the same format as it is entered."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Data format", + "type": "option", + "value": ["Hex", "Raw"] + }, + { + "name": "Word length (bytes)", + "type": "number", + "value": 4 + }, + { + "name": "Pad incomplete words", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [dataFormat, wordLength, padIncompleteWords] = args, + result = [], + words = []; + let i = 0, + j = 0, + data = []; + + if (wordLength <= 0) { + throw new OperationError("Word length must be greater than 0"); + } + + // Convert input to raw data based on specified data format + switch (dataFormat) { + case "Hex": + data = fromHex(input); + break; + case "Raw": + data = Utils.strToByteArray(input); + break; + default: + data = input; + } + + // Split up into words + for (i = 0; i < data.length; i += wordLength) { + const word = data.slice(i, i + wordLength); + + // Pad word if too short + if (padIncompleteWords && word.length < wordLength){ + for (j = word.length; j < wordLength; j++) { + word.push(0); + } + } + + words.push(word); + } + + // Swap endianness and flatten + for (i = 0; i < words.length; i++) { + j = words[i].length; + while (j--) { + result.push(words[i][j]); + } + } + + // Convert data back to specified data format + switch (dataFormat) { + case "Hex": + return toHex(result); + case "Raw": + return Utils.byteArrayToUtf8(result); + default: + return result; + } + } + + /** + * Highlight Swap endianness + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Swap endianness in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default SwapEndianness; diff --git a/src/core/operations/TCPIPChecksum.mjs b/src/core/operations/TCPIPChecksum.mjs new file mode 100644 index 00000000..6eac366d --- /dev/null +++ b/src/core/operations/TCPIPChecksum.mjs @@ -0,0 +1,52 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * TCP/IP Checksum operation + */ +class TCPIPChecksum extends Operation { + + /** + * TCPIPChecksum constructor + */ + constructor() { + super(); + + this.name = "TCP/IP Checksum"; + this.module = "Hashing"; + this.description = "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let csum = 0; + + for (let i = 0; i < input.length; i++) { + if (i % 2 === 0) { + csum += (input[i] << 8); + } else { + csum += input[i]; + } + } + + csum = (csum >> 16) + (csum & 0xffff); + + return Utils.hex(0xffff - csum); + } + +} + +export default TCPIPChecksum; diff --git a/src/core/operations/Tail.mjs b/src/core/operations/Tail.mjs new file mode 100644 index 00000000..c9e0d726 --- /dev/null +++ b/src/core/operations/Tail.mjs @@ -0,0 +1,69 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * Tail operation + */ +class Tail extends Operation { + + /** + * Tail constructor + */ + constructor() { + super(); + + this.name = "Tail"; + this.module = "Default"; + this.description = "Like the UNIX tail utility.
Gets the last n lines.
Optionally you can select all lines after line n by entering a negative value for n.
The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": INPUT_DELIM_OPTIONS + }, + { + "name": "Number", + "type": "number", + "value": 10 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let delimiter = args[0]; + const number = args[1]; + + delimiter = Utils.charRep(delimiter); + const splitInput = input.split(delimiter); + + return splitInput + .filter((line, lineIndex) => { + lineIndex += 1; + + if (number < 0) { + return lineIndex > -number; + } else { + return lineIndex > splitInput.length - number; + } + }) + .join(delimiter); + + } + +} + +export default Tail; diff --git a/src/core/operations/TakeBytes.mjs b/src/core/operations/TakeBytes.mjs new file mode 100644 index 00000000..5806ee87 --- /dev/null +++ b/src/core/operations/TakeBytes.mjs @@ -0,0 +1,89 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Take bytes operation + */ +class TakeBytes extends Operation { + + /** + * TakeBytes constructor + */ + constructor() { + super(); + + this.name = "Take bytes"; + this.module = "Default"; + this.description = "Takes a slice of the specified number of bytes from the data."; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = [ + { + "name": "Start", + "type": "number", + "value": 0 + }, + { + "name": "Length", + "type": "number", + "value": 5 + }, + { + "name": "Apply to each line", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + * + * @throws {OperationError} if invalid value + */ + run(input, args) { + const start = args[0], + length = args[1], + applyToEachLine = args[2]; + + if (start < 0 || length < 0) + throw new OperationError("Error: Invalid value"); + + if (!applyToEachLine) + return input.slice(start, start+length); + + // Split input into lines + const data = new Uint8Array(input); + const lines = []; + let line = [], + i; + + for (i = 0; i < data.length; i++) { + if (data[i] === 0x0a) { + lines.push(line); + line = []; + } else { + line.push(data[i]); + } + } + lines.push(line); + + let output = []; + for (i = 0; i < lines.length; i++) { + output = output.concat(lines[i].slice(start, start+length)); + output.push(0x0a); + } + return new Uint8Array(output.slice(0, output.length-1)).buffer; + } + +} + +export default TakeBytes; diff --git a/src/core/operations/Tar.mjs b/src/core/operations/Tar.mjs new file mode 100644 index 00000000..a2e8eb70 --- /dev/null +++ b/src/core/operations/Tar.mjs @@ -0,0 +1,139 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Tar operation + */ +class Tar extends Operation { + + /** + * Tar constructor + */ + constructor() { + super(); + + this.name = "Tar"; + this.module = "Compression"; + this.description = "Packs the input into a tarball.

No support for multiple files at this time."; + this.inputType = "byteArray"; + this.outputType = "File"; + this.args = [ + { + "name": "Filename", + "type": "string", + "value": "file.txt" + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + const Tarball = function() { + this.bytes = new Array(512); + this.position = 0; + }; + + Tarball.prototype.addEmptyBlock = function() { + const filler = new Array(512); + filler.fill(0); + this.bytes = this.bytes.concat(filler); + }; + + Tarball.prototype.writeBytes = function(bytes) { + const self = this; + + if (this.position + bytes.length > this.bytes.length) { + this.addEmptyBlock(); + } + + Array.prototype.forEach.call(bytes, function(b, i) { + if (typeof b.charCodeAt !== "undefined") { + b = b.charCodeAt(); + } + + self.bytes[self.position] = b; + self.position += 1; + }); + }; + + Tarball.prototype.writeEndBlocks = function() { + const numEmptyBlocks = 2; + for (let i = 0; i < numEmptyBlocks; i++) { + this.addEmptyBlock(); + } + }; + + const fileSize = input.length.toString(8).padStart(11, "0"); + const currentUnixTimestamp = Math.floor(Date.now() / 1000); + const lastModTime = currentUnixTimestamp.toString(8).padStart(11, "0"); + + const file = { + fileName: Utils.padBytesRight(args[0], 100), + fileMode: Utils.padBytesRight("0000664", 8), + ownerUID: Utils.padBytesRight("0", 8), + ownerGID: Utils.padBytesRight("0", 8), + size: Utils.padBytesRight(fileSize, 12), + lastModTime: Utils.padBytesRight(lastModTime, 12), + checksum: " ", + type: "0", + linkedFileName: Utils.padBytesRight("", 100), + USTARFormat: Utils.padBytesRight("ustar", 6), + version: "00", + ownerUserName: Utils.padBytesRight("", 32), + ownerGroupName: Utils.padBytesRight("", 32), + deviceMajor: Utils.padBytesRight("", 8), + deviceMinor: Utils.padBytesRight("", 8), + fileNamePrefix: Utils.padBytesRight("", 155), + }; + + let checksum = 0; + for (const key in file) { + const bytes = file[key]; + Array.prototype.forEach.call(bytes, function(b) { + if (typeof b.charCodeAt !== "undefined") { + checksum += b.charCodeAt(); + } else { + checksum += b; + } + }); + } + checksum = Utils.padBytesRight(checksum.toString(8).padStart(7, "0"), 8); + file.checksum = checksum; + + const tarball = new Tarball(); + tarball.writeBytes(file.fileName); + tarball.writeBytes(file.fileMode); + tarball.writeBytes(file.ownerUID); + tarball.writeBytes(file.ownerGID); + tarball.writeBytes(file.size); + tarball.writeBytes(file.lastModTime); + tarball.writeBytes(file.checksum); + tarball.writeBytes(file.type); + tarball.writeBytes(file.linkedFileName); + tarball.writeBytes(file.USTARFormat); + tarball.writeBytes(file.version); + tarball.writeBytes(file.ownerUserName); + tarball.writeBytes(file.ownerGroupName); + tarball.writeBytes(file.deviceMajor); + tarball.writeBytes(file.deviceMinor); + tarball.writeBytes(file.fileNamePrefix); + tarball.writeBytes(Utils.padBytesRight("", 12)); + tarball.writeBytes(input); + tarball.writeEndBlocks(); + + return new File([new Uint8Array(tarball.bytes)], args[0]); + } + +} + +export default Tar; diff --git a/src/core/operations/ToBCD.mjs b/src/core/operations/ToBCD.mjs new file mode 100644 index 00000000..43de14b6 --- /dev/null +++ b/src/core/operations/ToBCD.mjs @@ -0,0 +1,141 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; +import {ENCODING_SCHEME, ENCODING_LOOKUP, FORMAT} from "../lib/BCD"; +import BigNumber from "bignumber.js"; + +/** + * To BCD operation + */ +class ToBCD extends Operation { + + /** + * ToBCD constructor + */ + constructor() { + super(); + + this.name = "To BCD"; + this.module = "Default"; + this.description = "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign"; + this.inputType = "BigNumber"; + this.outputType = "string"; + this.args = [ + { + "name": "Scheme", + "type": "option", + "value": ENCODING_SCHEME + }, + { + "name": "Packed", + "type": "boolean", + "value": true + }, + { + "name": "Signed", + "type": "boolean", + "value": false + }, + { + "name": "Output format", + "type": "option", + "value": FORMAT + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (input.isNaN()) + throw new OperationError("Invalid input"); + if (!input.integerValue(BigNumber.ROUND_DOWN).isEqualTo(input)) + throw new OperationError("Fractional values are not supported by BCD"); + + const encoding = ENCODING_LOOKUP[args[0]], + packed = args[1], + signed = args[2], + outputFormat = args[3]; + + // Split input number up into separate digits + const digits = input.toFixed().split(""); + + if (digits[0] === "-" || digits[0] === "+") { + digits.shift(); + } + + let nibbles = []; + + digits.forEach(d => { + const n = parseInt(d, 10); + nibbles.push(encoding[n]); + }); + + if (signed) { + if (packed && digits.length % 2 === 0) { + // If there are an even number of digits, we add a leading 0 so + // that the sign nibble doesn't sit in its own byte, leading to + // ambiguity around whether the number ends with a 0 or not. + nibbles.unshift(encoding[0]); + } + + nibbles.push(input > 0 ? 12 : 13); + // 12 ("C") for + (credit) + // 13 ("D") for - (debit) + } + + let bytes = []; + + if (packed) { + let encoded = 0, + little = false; + + nibbles.forEach(n => { + encoded ^= little ? n : (n << 4); + if (little) { + bytes.push(encoded); + encoded = 0; + } + little = !little; + }); + + if (little) bytes.push(encoded); + } else { + bytes = nibbles; + + // Add null high nibbles + nibbles = nibbles.map(n => { + return [0, n]; + }).reduce((a, b) => { + return a.concat(b); + }); + } + + // Output + switch (outputFormat) { + case "Nibbles": + return nibbles.map(n => { + return n.toString(2).padStart(4, "0"); + }).join(" "); + case "Bytes": + return bytes.map(b => { + return b.toString(2).padStart(8, "0"); + }).join(" "); + case "Raw": + default: + return Utils.byteArrayToChars(bytes); + } + } + +} + +export default ToBCD; diff --git a/src/core/operations/ToBase.mjs b/src/core/operations/ToBase.mjs new file mode 100644 index 00000000..e37431e2 --- /dev/null +++ b/src/core/operations/ToBase.mjs @@ -0,0 +1,53 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * To Base operation + */ +class ToBase extends Operation { + + /** + * ToBase constructor + */ + constructor() { + super(); + + this.name = "To Base"; + this.module = "Default"; + this.description = "Converts a decimal number to a given numerical base."; + this.inputType = "BigNumber"; + this.outputType = "string"; + this.args = [ + { + "name": "Radix", + "type": "number", + "value": 36 + } + ]; + } + + /** + * @param {BigNumber} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (!input) { + throw new OperationError("Error: Input must be a number"); + } + const radix = args[0]; + if (radix < 2 || radix > 36) { + throw new OperationError("Error: Radix argument must be between 2 and 36"); + } + return input.toString(radix); + } + +} + +export default ToBase; diff --git a/src/core/operations/ToBase58.mjs b/src/core/operations/ToBase58.mjs new file mode 100644 index 00000000..47e0096f --- /dev/null +++ b/src/core/operations/ToBase58.mjs @@ -0,0 +1,85 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import OperationError from "../errors/OperationError"; +import {ALPHABET_OPTIONS} from "../lib/Base58"; + +/** + * To Base58 operation + */ +class ToBase58 extends Operation { + + /** + * ToBase58 constructor + */ + constructor() { + super(); + + this.name = "To Base58"; + this.module = "Default"; + this.description = "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.

This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).

e.g. hello world becomes StV1DL6CwTryKyV

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc)."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Alphabet", + "type": "editableOption", + "value": ALPHABET_OPTIONS + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let alphabet = args[0] || ALPHABET_OPTIONS[0].value, + result = [0]; + + alphabet = Utils.expandAlphRange(alphabet).join(""); + + if (alphabet.length !== 58 || + [].unique.call(alphabet).length !== 58) { + throw new OperationError("Error: alphabet must be of length 58"); + } + + if (input.length === 0) return ""; + + input.forEach(function(b) { + let carry = (result[0] << 8) + b; + result[0] = carry % 58; + carry = (carry / 58) | 0; + + for (let i = 1; i < result.length; i++) { + carry += result[i] << 8; + result[i] = carry % 58; + carry = (carry / 58) | 0; + } + + while (carry > 0) { + result.push(carry % 58); + carry = (carry / 58) | 0; + } + }); + + result = result.map(function(b) { + return alphabet[b]; + }).reverse().join(""); + + while (result.length < input.length) { + result = alphabet[0] + result; + } + + return result; + } + +} + +export default ToBase58; diff --git a/src/core/operations/ToBinary.mjs b/src/core/operations/ToBinary.mjs new file mode 100644 index 00000000..f10f66a7 --- /dev/null +++ b/src/core/operations/ToBinary.mjs @@ -0,0 +1,91 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {BIN_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * To Binary operation + */ +class ToBinary extends Operation { + + /** + * ToBinary constructor + */ + constructor() { + super(); + + this.name = "To Binary"; + this.module = "Default"; + this.description = "Displays the input data as a binary string.

e.g. Hi becomes 01001000 01101001"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": BIN_DELIM_OPTIONS + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"), + padding = 8; + let output = ""; + + for (let i = 0; i < input.length; i++) { + output += input[i].toString(2).padStart(padding, "0") + delim; + } + + if (delim.length) { + return output.slice(0, -delim.length); + } else { + return output; + } + } + + /** + * Highlight To Binary + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + const delim = Utils.charRep(args[0] || "Space"); + pos[0].start = pos[0].start * (8 + delim.length); + pos[0].end = pos[0].end * (8 + delim.length) - delim.length; + return pos; + } + + /** + * Highlight To Binary in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + const delim = Utils.charRep(args[0] || "Space"); + pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length)); + pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length)); + return pos; + } + +} + +export default ToBinary; diff --git a/src/core/operations/ToCharcode.mjs b/src/core/operations/ToCharcode.mjs new file mode 100644 index 00000000..db043d79 --- /dev/null +++ b/src/core/operations/ToCharcode.mjs @@ -0,0 +1,85 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; +import OperationError from "../errors/OperationError"; + +/** + * To Charcode operation + */ +class ToCharcode extends Operation { + + /** + * ToCharcode constructor + */ + constructor() { + super(); + + this.name = "To Charcode"; + this.module = "Default"; + this.description = "Converts text to its unicode character code equivalent.

e.g. Γειά σου becomes 0393 03b5 03b9 03ac 20 03c3 03bf 03c5"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + }, + { + "name": "Base", + "type": "number", + "value": 16 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if base argument out of range + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"), + base = args[1]; + let output = "", + padding = 2, + ordinal; + + if (base < 2 || base > 36) { + throw new OperationError("Error: Base argument must be between 2 and 36"); + } + + const charcode = Utils.strToCharcode(input); + for (let i = 0; i < charcode.length; i++) { + ordinal = charcode[i]; + + if (base === 16) { + if (ordinal < 256) padding = 2; + else if (ordinal < 65536) padding = 4; + else if (ordinal < 16777216) padding = 6; + else if (ordinal < 4294967296) padding = 8; + else padding = 2; + + if (padding > 2 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); + + output += Utils.hex(ordinal, padding) + delim; + } else { + if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); + output += ordinal.toString(base) + delim; + } + } + + return output.slice(0, -delim.length); + } + +} + +export default ToCharcode; diff --git a/src/core/operations/ToDecimal.mjs b/src/core/operations/ToDecimal.mjs new file mode 100644 index 00000000..cad8dc18 --- /dev/null +++ b/src/core/operations/ToDecimal.mjs @@ -0,0 +1,49 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; + + +/** + * To Decimal operation + */ +class ToDecimal extends Operation { + + /** + * ToDecimal constructor + */ + constructor() { + super(); + + this.name = "To Decimal"; + this.module = "Default"; + this.description = "Converts the input data to an ordinal integer array.

e.g. Hello becomes 72 101 108 108 111"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0]); + return input.join(delim); + } + +} + +export default ToDecimal; diff --git a/src/core/operations/ToHTMLEntity.mjs b/src/core/operations/ToHTMLEntity.mjs new file mode 100644 index 00000000..06b5ff25 --- /dev/null +++ b/src/core/operations/ToHTMLEntity.mjs @@ -0,0 +1,345 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * To HTML Entity operation + */ +class ToHTMLEntity extends Operation { + + /** + * ToHTMLEntity constructor + */ + constructor() { + super(); + + this.name = "To HTML Entity"; + this.module = "Default"; + this.description = "Converts characters to HTML entities

e.g. & becomes &amp;"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Convert all characters", + "type": "boolean", + "value": false + }, + { + "name": "Convert to", + "type": "option", + "value": ["Named entities where possible", "Numeric entities", "Hex entities"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const convertAll = args[0], + numeric = args[1] === "Numeric entities", + hexa = args[1] === "Hex entities"; + + const charcodes = Utils.strToCharcode(input); + let output = ""; + + for (let i = 0; i < charcodes.length; i++) { + if (convertAll && numeric) { + output += "&#" + charcodes[i] + ";"; + } else if (convertAll && hexa) { + output += "&#x" + Utils.hex(charcodes[i]) + ";"; + } else if (convertAll) { + output += byteToEntity[charcodes[i]] || "&#" + charcodes[i] + ";"; + } else if (numeric) { + if (charcodes[i] > 255 || byteToEntity.hasOwnProperty(charcodes[i])) { + output += "&#" + charcodes[i] + ";"; + } else { + output += Utils.chr(charcodes[i]); + } + } else if (hexa) { + if (charcodes[i] > 255 || byteToEntity.hasOwnProperty(charcodes[i])) { + output += "&#x" + Utils.hex(charcodes[i]) + ";"; + } else { + output += Utils.chr(charcodes[i]); + } + } else { + output += byteToEntity[charcodes[i]] || ( + charcodes[i] > 255 ? + "&#" + charcodes[i] + ";" : + Utils.chr(charcodes[i]) + ); + } + } + return output; + } + +} + +/** + * Lookup table to translate byte values to their HTML entity codes. + */ +const byteToEntity = { + 34: """, + 38: "&", + 39: "'", + 60: "<", + 62: ">", + 160: " ", + 161: "¡", + 162: "¢", + 163: "£", + 164: "¤", + 165: "¥", + 166: "¦", + 167: "§", + 168: "¨", + 169: "©", + 170: "ª", + 171: "«", + 172: "¬", + 173: "­", + 174: "®", + 175: "¯", + 176: "°", + 177: "±", + 178: "²", + 179: "³", + 180: "´", + 181: "µ", + 182: "¶", + 183: "·", + 184: "¸", + 185: "¹", + 186: "º", + 187: "»", + 188: "¼", + 189: "½", + 190: "¾", + 191: "¿", + 192: "À", + 193: "Á", + 194: "Â", + 195: "Ã", + 196: "Ä", + 197: "Å", + 198: "Æ", + 199: "Ç", + 200: "È", + 201: "É", + 202: "Ê", + 203: "Ë", + 204: "Ì", + 205: "Í", + 206: "Î", + 207: "Ï", + 208: "Ð", + 209: "Ñ", + 210: "Ò", + 211: "Ó", + 212: "Ô", + 213: "Õ", + 214: "Ö", + 215: "×", + 216: "Ø", + 217: "Ù", + 218: "Ú", + 219: "Û", + 220: "Ü", + 221: "Ý", + 222: "Þ", + 223: "ß", + 224: "à", + 225: "á", + 226: "â", + 227: "ã", + 228: "ä", + 229: "å", + 230: "æ", + 231: "ç", + 232: "è", + 233: "é", + 234: "ê", + 235: "ë", + 236: "ì", + 237: "í", + 238: "î", + 239: "ï", + 240: "ð", + 241: "ñ", + 242: "ò", + 243: "ó", + 244: "ô", + 245: "õ", + 246: "ö", + 247: "÷", + 248: "ø", + 249: "ù", + 250: "ú", + 251: "û", + 252: "ü", + 253: "ý", + 254: "þ", + 255: "ÿ", + 338: "Œ", + 339: "œ", + 352: "Š", + 353: "š", + 376: "Ÿ", + 402: "ƒ", + 710: "ˆ", + 732: "˜", + 913: "Α", + 914: "Β", + 915: "Γ", + 916: "Δ", + 917: "Ε", + 918: "Ζ", + 919: "Η", + 920: "Θ", + 921: "Ι", + 922: "Κ", + 923: "Λ", + 924: "Μ", + 925: "Ν", + 926: "Ξ", + 927: "Ο", + 928: "Π", + 929: "Ρ", + 931: "Σ", + 932: "Τ", + 933: "Υ", + 934: "Φ", + 935: "Χ", + 936: "Ψ", + 937: "Ω", + 945: "α", + 946: "β", + 947: "γ", + 948: "δ", + 949: "ε", + 950: "ζ", + 951: "η", + 952: "θ", + 953: "ι", + 954: "κ", + 955: "λ", + 956: "μ", + 957: "ν", + 958: "ξ", + 959: "ο", + 960: "π", + 961: "ρ", + 962: "ς", + 963: "σ", + 964: "τ", + 965: "υ", + 966: "φ", + 967: "χ", + 968: "ψ", + 969: "ω", + 977: "ϑ", + 978: "ϒ", + 982: "ϖ", + 8194: " ", + 8195: " ", + 8201: " ", + 8204: "‌", + 8205: "‍", + 8206: "‎", + 8207: "‏", + 8211: "–", + 8212: "—", + 8216: "‘", + 8217: "’", + 8218: "‚", + 8220: "“", + 8221: "”", + 8222: "„", + 8224: "†", + 8225: "‡", + 8226: "•", + 8230: "…", + 8240: "‰", + 8242: "′", + 8243: "″", + 8249: "‹", + 8250: "›", + 8254: "‾", + 8260: "⁄", + 8364: "€", + 8465: "ℑ", + 8472: "℘", + 8476: "ℜ", + 8482: "™", + 8501: "ℵ", + 8592: "←", + 8593: "↑", + 8594: "→", + 8595: "↓", + 8596: "↔", + 8629: "↵", + 8656: "⇐", + 8657: "⇑", + 8658: "⇒", + 8659: "⇓", + 8660: "⇔", + 8704: "∀", + 8706: "∂", + 8707: "∃", + 8709: "∅", + 8711: "∇", + 8712: "∈", + 8713: "∉", + 8715: "∋", + 8719: "∏", + 8721: "∑", + 8722: "−", + 8727: "∗", + 8730: "√", + 8733: "∝", + 8734: "∞", + 8736: "∠", + 8743: "∧", + 8744: "∨", + 8745: "∩", + 8746: "∪", + 8747: "∫", + 8756: "∴", + 8764: "∼", + 8773: "≅", + 8776: "≈", + 8800: "≠", + 8801: "≡", + 8804: "≤", + 8805: "≥", + 8834: "⊂", + 8835: "⊃", + 8836: "⊄", + 8838: "⊆", + 8839: "⊇", + 8853: "⊕", + 8855: "⊗", + 8869: "⊥", + 8901: "⋅", + 8942: "⋮", + 8968: "⌈", + 8969: "⌉", + 8970: "⌊", + 8971: "⌋", + 9001: "⟨", + 9002: "⟩", + 9674: "◊", + 9824: "♠", + 9827: "♣", + 9829: "♥", + 9830: "♦", +}; + +export default ToHTMLEntity; diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index d9b89b11..9b1ccade 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation"; -import {toHex, HEX_DELIM_OPTIONS} from "../lib/Hex"; +import {toHex, TO_HEX_DELIM_OPTIONS} from "../lib/Hex"; import Utils from "../Utils"; /** @@ -28,7 +28,7 @@ class ToHex extends Operation { { name: "Delimiter", type: "option", - value: HEX_DELIM_OPTIONS + value: TO_HEX_DELIM_OPTIONS } ]; } diff --git a/src/core/operations/ToHexContent.mjs b/src/core/operations/ToHexContent.mjs new file mode 100644 index 00000000..af9ae22c --- /dev/null +++ b/src/core/operations/ToHexContent.mjs @@ -0,0 +1,81 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {toHex} from "../lib/Hex"; + +/** + * To Hex Content operation + */ +class ToHexContent extends Operation { + + /** + * ToHexContent constructor + */ + constructor() { + super(); + + this.name = "To Hex Content"; + this.module = "Default"; + this.description = "Converts special characters in a string to hexadecimal.

e.g. foo=bar becomes foo|3d|bar."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Convert", + "type": "option", + "value": ["Only special chars", "Only special chars including spaces", "All chars"] + }, + { + "name": "Print spaces between bytes", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const convert = args[0]; + const spaces = args[1]; + if (convert === "All chars") { + let result = "|" + toHex(input) + "|"; + if (!spaces) result = result.replace(/ /g, ""); + return result; + } + + let output = "", + inHex = false, + b; + const convertSpaces = convert === "Only special chars including spaces"; + for (let i = 0; i < input.length; i++) { + b = input[i]; + if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) { + if (!inHex) { + output += "|"; + inHex = true; + } else if (spaces) output += " "; + output += toHex([b]); + } else { + if (inHex) { + output += "|"; + inHex = false; + } + output += Utils.chr(input[i]); + } + } + if (inHex) output += "|"; + return output; + } + +} + +export default ToHexContent; diff --git a/src/core/operations/ToHexdump.mjs b/src/core/operations/ToHexdump.mjs new file mode 100644 index 00000000..89ebdc33 --- /dev/null +++ b/src/core/operations/ToHexdump.mjs @@ -0,0 +1,183 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * To Hexdump operation + */ +class ToHexdump extends Operation { + + /** + * ToHexdump constructor + */ + constructor() { + super(); + + this.name = "To Hexdump"; + this.module = "Default"; + this.description = "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside."; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Width", + "type": "number", + "value": 16 + }, + { + "name": "Upper case hex", + "type": "boolean", + "value": false + }, + { + "name": "Include final length", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const data = new Uint8Array(input); + const [length, upperCase, includeFinalLength] = args; + const padding = 2; + + let output = ""; + for (let i = 0; i < data.length; i += length) { + const buff = data.slice(i, i+length); + let hexa = ""; + for (let j = 0; j < buff.length; j++) { + hexa += Utils.hex(buff[j], padding) + " "; + } + + let lineNo = Utils.hex(i, 8); + + if (upperCase) { + hexa = hexa.toUpperCase(); + lineNo = lineNo.toUpperCase(); + } + + output += lineNo + " " + + hexa.padEnd(length*(padding+1), " ") + + " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n"; + + if (includeFinalLength && i+buff.length === data.length) { + output += Utils.hex(i+buff.length, 8) + "\n"; + } + } + + return output.slice(0, -1); + } + + /** + * Highlight To Hexdump + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + // Calculate overall selection + const w = args[0] || 16, + width = 14 + (w*4); + let line = Math.floor(pos[0].start / w), + offset = pos[0].start % w, + start = 0, + end = 0; + + pos[0].start = line*width + 10 + offset*3; + + line = Math.floor(pos[0].end / w); + offset = pos[0].end % w; + if (offset === 0) { + line--; + offset = w; + } + pos[0].end = line*width + 10 + offset*3 - 1; + + // Set up multiple selections for bytes + let startLineNum = Math.floor(pos[0].start / width); + const endLineNum = Math.floor(pos[0].end / width); + + if (startLineNum === endLineNum) { + pos.push(pos[0]); + } else { + start = pos[0].start; + end = (startLineNum+1) * width - w - 5; + pos.push({ start: start, end: end }); + while (end < pos[0].end) { + startLineNum++; + start = startLineNum * width + 10; + end = (startLineNum+1) * width - w - 5; + if (end > pos[0].end) end = pos[0].end; + pos.push({ start: start, end: end }); + } + } + + // Set up multiple selections for ASCII + const len = pos.length; + let lineNum = 0; + start = 0; + end = 0; + for (let i = 1; i < len; i++) { + lineNum = Math.floor(pos[i].start / width); + start = (((pos[i].start - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); + end = (((pos[i].end + 1 - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); + pos.push({ start: start, end: end }); + } + return pos; + } + + /** + * Highlight To Hexdump in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + const w = args[0] || 16; + const width = 14 + (w*4); + + let line = Math.floor(pos[0].start / width); + let offset = pos[0].start % width; + + if (offset < 10) { // In line number section + pos[0].start = line*w; + } else if (offset > 10+(w*3)) { // In ASCII section + pos[0].start = (line+1)*w; + } else { // In byte section + pos[0].start = line*w + Math.floor((offset-10)/3); + } + + line = Math.floor(pos[0].end / width); + offset = pos[0].end % width; + + if (offset < 10) { // In line number section + pos[0].end = line*w; + } else if (offset > 10+(w*3)) { // In ASCII section + pos[0].end = (line+1)*w; + } else { // In byte section + pos[0].end = line*w + Math.ceil((offset-10)/3); + } + + return pos; + } + +} + +export default ToHexdump; diff --git a/src/core/operations/ToLowerCase.mjs b/src/core/operations/ToLowerCase.mjs new file mode 100644 index 00000000..f28380bc --- /dev/null +++ b/src/core/operations/ToLowerCase.mjs @@ -0,0 +1,65 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * To Lower case operation + */ +class ToLowerCase extends Operation { + + /** + * ToLowerCase constructor + */ + constructor() { + super(); + + this.name = "To Lower case"; + this.module = "Default"; + this.description = "Converts every character in the input to lower case."; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return input.toLowerCase(); + } + + /** + * Highlight To Lower case + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight To Lower case in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default ToLowerCase; diff --git a/src/core/operations/ToMorseCode.mjs b/src/core/operations/ToMorseCode.mjs new file mode 100644 index 00000000..3146a114 --- /dev/null +++ b/src/core/operations/ToMorseCode.mjs @@ -0,0 +1,153 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {LETTER_DELIM_OPTIONS, WORD_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * To Morse Code operation + */ +class ToMorseCode extends Operation { + + /** + * ToMorseCode constructor + */ + constructor() { + super(); + + this.name = "To Morse Code"; + this.module = "Default"; + this.description = "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ..."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Format options", + "type": "option", + "value": ["-/.", "_/.", "Dash/Dot", "DASH/DOT", "dash/dot"] + }, + { + "name": "Letter delimiter", + "type": "option", + "value": LETTER_DELIM_OPTIONS + }, + { + "name": "Word delimiter", + "type": "option", + "value": WORD_DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const format = args[0].split("/"); + const dash = format[0]; + const dot = format[1]; + + const letterDelim = Utils.charRep(args[1]); + const wordDelim = Utils.charRep(args[2]); + + input = input.split(/\r?\n/); + input = Array.prototype.map.call(input, function(line) { + let words = line.split(/ +/); + words = Array.prototype.map.call(words, function(word) { + const letters = Array.prototype.map.call(word, function(character) { + const letter = character.toUpperCase(); + if (typeof MORSE_TABLE[letter] == "undefined") { + return ""; + } + + return MORSE_TABLE[letter]; + }); + + return letters.join(""); + }); + line = words.join(""); + return line; + }); + input = input.join("\n"); + + input = input.replace( + /|||/g, + function(match) { + switch (match) { + case "": return dash; + case "": return dot; + case "": return letterDelim; + case "": return wordDelim; + } + } + ); + + return input; + } + +} + +const MORSE_TABLE = { + "A": "", + "B": "", + "C": "", + "D": "", + "E": "", + "F": "", + "G": "", + "H": "", + "I": "", + "J": "", + "K": "", + "L": "", + "M": "", + "N": "", + "O": "", + "P": "", + "Q": "", + "R": "", + "S": "", + "T": "", + "U": "", + "V": "", + "W": "", + "X": "", + "Y": "", + "Z": "", + "1": "", + "2": "", + "3": "", + "4": "", + "5": "", + "6": "", + "7": "", + "8": "", + "9": "", + "0": "", + ".": "", + ",": "", + ":": "", + ";": "", + "!": "", + "?": "", + "'": "", + "\"": "", + "/": "", + "-": "", + "+": "", + "(": "", + ")": "", + "@": "", + "=": "", + "&": "", + "_": "", + "$": "" +}; + +export default ToMorseCode; diff --git a/src/core/operations/ToOctal.mjs b/src/core/operations/ToOctal.mjs new file mode 100644 index 00000000..7cfb4736 --- /dev/null +++ b/src/core/operations/ToOctal.mjs @@ -0,0 +1,49 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {DELIM_OPTIONS} from "../lib/Delim"; + + +/** + * To Octal operation + */ +class ToOctal extends Operation { + + /** + * ToOctal constructor + */ + constructor() { + super(); + + this.name = "To Octal"; + this.module = "Default"; + this.description = "Converts the input string to octal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0] || "Space"); + return input.map(val => val.toString(8)).join(delim); + } + +} + +export default ToOctal; diff --git a/src/core/operations/ToPunycode.mjs b/src/core/operations/ToPunycode.mjs new file mode 100644 index 00000000..8951cb5f --- /dev/null +++ b/src/core/operations/ToPunycode.mjs @@ -0,0 +1,52 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import punycode from "punycode"; + +/** + * To Punycode operation + */ +class ToPunycode extends Operation { + + /** + * ToPunycode constructor + */ + constructor() { + super(); + + this.name = "To Punycode"; + this.module = "Encodings"; + this.description = "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. m\xfcnchen encodes to mnchen-3ya"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Internationalised domain name", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const idn = args[0]; + + if (idn) { + return punycode.toASCII(input); + } else { + return punycode.encode(input); + } + } + +} + +export default ToPunycode; diff --git a/src/core/operations/ToQuotedPrintable.mjs b/src/core/operations/ToQuotedPrintable.mjs new file mode 100644 index 00000000..aa1025d7 --- /dev/null +++ b/src/core/operations/ToQuotedPrintable.mjs @@ -0,0 +1,244 @@ +/** + * Some parts taken from mimelib (http://github.com/andris9/mimelib) + * @author Andris Reinman + * @license MIT + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * To Quoted Printable operation + */ +class ToQuotedPrintable extends Operation { + + /** + * ToQuotedPrintable constructor + */ + constructor() { + super(); + + this.name = "To Quoted Printable"; + this.module = "Default"; + this.description = "Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign '=') to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean. It is defined as a MIME content transfer encoding for use in e-mail.

QP works by using the equals sign '=' as an escape character. It also limits line length to 76, as some software has limits on line length."; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let mimeEncodedStr = this.mimeEncode(input); + + // fix line breaks + mimeEncodedStr = mimeEncodedStr.replace(/\r?\n|\r/g, function() { + return "\r\n"; + }).replace(/[\t ]+$/gm, function(spaces) { + return spaces.replace(/ /g, "=20").replace(/\t/g, "=09"); + }); + + return this._addSoftLinebreaks(mimeEncodedStr, "qp"); + } + + + /** @license + ======================================================================== + mimelib: http://github.com/andris9/mimelib + Copyright (c) 2011-2012 Andris Reinman + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + + /** + * Encodes mime data. + * + * @param {byteArray} buffer + * @returns {string} + */ + mimeEncode(buffer) { + const ranges = [ + [0x09], + [0x0A], + [0x0D], + [0x20], + [0x21], + [0x23, 0x3C], + [0x3E], + [0x40, 0x5E], + [0x60, 0x7E] + ]; + let result = ""; + + for (let i = 0, len = buffer.length; i < len; i++) { + if (this._checkRanges(buffer[i], ranges)) { + result += String.fromCharCode(buffer[i]); + continue; + } + result += "=" + (buffer[i] < 0x10 ? "0" : "") + buffer[i].toString(16).toUpperCase(); + } + + return result; + } + + /** + * Checks if a given number falls within a given set of ranges. + * + * @private + * @param {number} nr + * @param {byteArray[]} ranges + * @returns {bolean} + */ + _checkRanges(nr, ranges) { + for (let i = ranges.length - 1; i >= 0; i--) { + if (!ranges[i].length) + continue; + if (ranges[i].length === 1 && nr === ranges[i][0]) + return true; + if (ranges[i].length === 2 && nr >= ranges[i][0] && nr <= ranges[i][1]) + return true; + } + return false; + } + + /** + * Adds soft line breaks to a string. + * Lines can't be longer that 76 + = 78 bytes + * http://tools.ietf.org/html/rfc2045#section-6.7 + * + * @private + * @param {string} str + * @param {string} encoding + * @returns {string} + */ + _addSoftLinebreaks(str, encoding) { + const lineLengthMax = 76; + + encoding = (encoding || "base64").toString().toLowerCase().trim(); + + if (encoding === "qp") { + return this._addQPSoftLinebreaks(str, lineLengthMax); + } else { + return this._addBase64SoftLinebreaks(str, lineLengthMax); + } + } + + /** + * Adds soft line breaks to a base64 string. + * + * @private + * @param {string} base64EncodedStr + * @param {number} lineLengthMax + * @returns {string} + */ + _addBase64SoftLinebreaks(base64EncodedStr, lineLengthMax) { + base64EncodedStr = (base64EncodedStr || "").toString().trim(); + return base64EncodedStr.replace(new RegExp(".{" + lineLengthMax + "}", "g"), "$&\r\n").trim(); + } + + /** + * Adds soft line breaks to a quoted printable string. + * + * @private + * @param {string} mimeEncodedStr + * @param {number} lineLengthMax + * @returns {string} + */ + _addQPSoftLinebreaks(mimeEncodedStr, lineLengthMax) { + const len = mimeEncodedStr.length, + lineMargin = Math.floor(lineLengthMax / 3); + let pos = 0, + match, code, line, + result = ""; + + // insert soft linebreaks where needed + while (pos < len) { + line = mimeEncodedStr.substr(pos, lineLengthMax); + if ((match = line.match(/\r\n/))) { + line = line.substr(0, match.index + match[0].length); + result += line; + pos += line.length; + continue; + } + + if (line.substr(-1) === "\n") { + // nothing to change here + result += line; + pos += line.length; + continue; + } else if ((match = line.substr(-lineMargin).match(/\n.*?$/))) { + // truncate to nearest line break + line = line.substr(0, line.length - (match[0].length - 1)); + result += line; + pos += line.length; + continue; + } else if (line.length > lineLengthMax - lineMargin && (match = line.substr(-lineMargin).match(/[ \t.,!?][^ \t.,!?]*$/))) { + // truncate to nearest space + line = line.substr(0, line.length - (match[0].length - 1)); + } else if (line.substr(-1) === "\r") { + line = line.substr(0, line.length - 1); + } else { + if (line.match(/=[\da-f]{0,2}$/i)) { + + // push incomplete encoding sequences to the next line + if ((match = line.match(/=[\da-f]{0,1}$/i))) { + line = line.substr(0, line.length - match[0].length); + } + + // ensure that utf-8 sequences are not split + while (line.length > 3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/=[\da-f]{2}$/ig))) { + code = parseInt(match[0].substr(1, 2), 16); + if (code < 128) { + break; + } + + line = line.substr(0, line.length - 3); + + if (code >= 0xC0) { + break; + } + } + + } + } + + if (pos + line.length < len && line.substr(-1) !== "\n") { + if (line.length === 76 && line.match(/=[\da-f]{2}$/i)) { + line = line.substr(0, line.length - 3); + } else if (line.length === 76) { + line = line.substr(0, line.length - 1); + } + pos += line.length; + line += "=\r\n"; + } else { + pos += line.length; + } + + result += line; + } + + return result; + } + +} + +export default ToQuotedPrintable; diff --git a/src/core/operations/ToTable.mjs b/src/core/operations/ToTable.mjs new file mode 100644 index 00000000..944904e6 --- /dev/null +++ b/src/core/operations/ToTable.mjs @@ -0,0 +1,189 @@ +/** + * @author Mark Jones [github.com/justanothermark] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * To Table operation + */ +class ToTable extends Operation { + + /** + * ToTable constructor + */ + constructor() { + super(); + + this.name = "To Table"; + this.module = "Default"; + this.description = "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.

Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to \\t to support TSV (Tab Separated Values) or | for PSV (Pipe Separated Values).

You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter."; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + "name": "Cell delimiters", + "type": "binaryShortString", + "value": "," + }, + { + "name": "Row delimiters", + "type": "binaryShortString", + "value": "\\n\\r" + }, + { + "name": "Make first row header", + "type": "boolean", + "value": false + }, + { + "name": "Format", + "type": "option", + "value": ["ASCII", "HTML"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const [cellDelims, rowDelims, firstRowHeader, format] = args; + + // Process the input into a nested array of elements. + const tableData = Utils.parseCSV(input, cellDelims.split(""), rowDelims.split("")); + + if (!tableData.length) return ""; + + // Render the data in the requested format. + switch (format) { + case "ASCII": + return asciiOutput(tableData); + case "HTML": + default: + return htmlOutput(tableData); + } + + /** + * Outputs an array of data as an ASCII table. + * + * @param {string[][]} tableData + * @returns {string} + */ + function asciiOutput(tableData) { + const horizontalBorder = "-"; + const verticalBorder = "|"; + const crossBorder = "+"; + + let output = ""; + const longestCells = []; + + // Find longestCells value per column to pad cells equally. + tableData.forEach(function(row, index) { + row.forEach(function(cell, cellIndex) { + if (longestCells[cellIndex] === undefined || cell.length > longestCells[cellIndex]) { + longestCells[cellIndex] = cell.length; + } + }); + }); + + // Add the top border of the table to the output. + output += outputHorizontalBorder(longestCells); + + // If the first row is a header, remove the row from the data and + // add it to the output with another horizontal border. + if (firstRowHeader) { + const row = tableData.shift(); + output += outputRow(row, longestCells); + output += outputHorizontalBorder(longestCells); + } + + // Add the rest of the table rows. + tableData.forEach(function(row, index) { + output += outputRow(row, longestCells); + }); + + // Close the table with a final horizontal border. + output += outputHorizontalBorder(longestCells); + + return output; + + /** + * Outputs a row of correctly padded cells. + */ + function outputRow(row, longestCells) { + let rowOutput = verticalBorder; + row.forEach(function(cell, index) { + rowOutput += " " + cell + " ".repeat(longestCells[index] - cell.length) + " " + verticalBorder; + }); + rowOutput += "\n"; + return rowOutput; + } + + /** + * Outputs a horizontal border with a different character where + * the horizontal border meets a vertical border. + */ + function outputHorizontalBorder(longestCells) { + let rowOutput = crossBorder; + longestCells.forEach(function(cellLength) { + rowOutput += horizontalBorder.repeat(cellLength + 2) + crossBorder; + }); + rowOutput += "\n"; + return rowOutput; + } + } + + /** + * Outputs a table of data as a HTML table. + * + * @param {string[][]} tableData + * @returns {string} + */ + function htmlOutput(tableData) { + // Start the HTML output with suitable classes for styling. + let output = ""; + + // If the first row is a header then put it in with "; + output += outputRow(row, "th"); + output += ""; + } + + // Output the rest of the rows in the . + output += ""; + tableData.forEach(function(row, index) { + output += outputRow(row, "td"); + }); + + // Close the body and table elements. + output += "
cells. + if (firstRowHeader) { + const row = tableData.shift(); + output += "
"; + return output; + + /** + * Outputs a table row. + * + * @param {string[]} row + * @param {string} cellType + */ + function outputRow(row, cellType) { + let output = ""; + row.forEach(function(cell) { + output += "<" + cellType + ">" + cell + ""; + }); + output += ""; + return output; + } + } + } + +} + +export default ToTable; diff --git a/src/core/operations/ToUNIXTimestamp.mjs b/src/core/operations/ToUNIXTimestamp.mjs new file mode 100644 index 00000000..6983d617 --- /dev/null +++ b/src/core/operations/ToUNIXTimestamp.mjs @@ -0,0 +1,77 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import moment from "moment-timezone"; +import {UNITS} from "../lib/DateTime"; +import OperationError from "../errors/OperationError"; + +/** + * To UNIX Timestamp operation + */ +class ToUNIXTimestamp extends Operation { + + /** + * ToUNIXTimestamp constructor + */ + constructor() { + super(); + + this.name = "To UNIX Timestamp"; + this.module = "Default"; + this.description = "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.

e.g. Mon 1 January 2001 11:00:00 becomes 978346800

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch)."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Units", + "type": "option", + "value": UNITS + }, + { + "name": "Treat as UTC", + "type": "boolean", + "value": true + }, + { + "name": "Show parsed datetime", + "type": "boolean", + "value": true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + * + * @throws {OperationError} if unit unrecognised + */ + run(input, args) { + const [units, treatAsUTC, showDateTime] = args, + d = treatAsUTC ? moment.utc(input) : moment(input); + + let result = ""; + + if (units === "Seconds (s)") { + result = d.unix(); + } else if (units === "Milliseconds (ms)") { + result = d.valueOf(); + } else if (units === "Microseconds (μs)") { + result = d.valueOf() * 1000; + } else if (units === "Nanoseconds (ns)") { + result = d.valueOf() * 1000000; + } else { + throw new OperationError("Unrecognised unit"); + } + + return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString(); + } + +} + +export default ToUNIXTimestamp; diff --git a/src/core/operations/ToUpperCase.mjs b/src/core/operations/ToUpperCase.mjs new file mode 100644 index 00000000..d56aacff --- /dev/null +++ b/src/core/operations/ToUpperCase.mjs @@ -0,0 +1,89 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * To Upper case operation + */ +class ToUpperCase extends Operation { + + /** + * ToUpperCase constructor + */ + constructor() { + super(); + + this.name = "To Upper case"; + this.module = "Default"; + this.description = "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Scope", + "type": "option", + "value": ["All", "Word", "Sentence", "Paragraph"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const scope = args[0]; + + switch (scope) { + case "Word": + return input.replace(/(\b\w)/gi, function(m) { + return m.toUpperCase(); + }); + case "Sentence": + return input.replace(/(?:\.|^)\s*(\b\w)/gi, function(m) { + return m.toUpperCase(); + }); + case "Paragraph": + return input.replace(/(?:\n|^)\s*(\b\w)/gi, function(m) { + return m.toUpperCase(); + }); + case "All": /* falls through */ + default: + return input.toUpperCase(); + } + } + + /** + * Highlight To Upper case + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight To Upper case in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default ToUpperCase; diff --git a/src/core/operations/TranslateDateTimeFormat.mjs b/src/core/operations/TranslateDateTimeFormat.mjs new file mode 100644 index 00000000..6ed72d9f --- /dev/null +++ b/src/core/operations/TranslateDateTimeFormat.mjs @@ -0,0 +1,79 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import moment from "moment-timezone"; +import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime"; +import OperationError from "../errors/OperationError"; + +/** + * Translate DateTime Format operation + */ +class TranslateDateTimeFormat extends Operation { + + /** + * TranslateDateTimeFormat constructor + */ + constructor() { + super(); + + this.name = "Translate DateTime Format"; + this.module = "Default"; + this.description = "Parses a datetime string in one format and re-writes it in another.

Run with no input to see the relevant format string examples."; + this.inputType = "string"; + this.outputType = "html"; + this.args = [ + { + "name": "Built in formats", + "type": "populateOption", + "value": DATETIME_FORMATS, + "target": 1 + }, + { + "name": "Input format string", + "type": "binaryString", + "value": "DD/MM/YYYY HH:mm:ss" + }, + { + "name": "Input timezone", + "type": "option", + "value": ["UTC"].concat(moment.tz.names()) + }, + { + "name": "Output format string", + "type": "binaryString", + "value": "dddd Do MMMM YYYY HH:mm:ss Z z" + }, + { + "name": "Output timezone", + "type": "option", + "value": ["UTC"].concat(moment.tz.names()) + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const [inputFormat, inputTimezone, outputFormat, outputTimezone] = args; + let date; + + try { + date = moment.tz(input, inputFormat, inputTimezone); + if (!date || date.format() === "Invalid date") throw Error; + } catch (err) { + throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`); + } + + return date.tz(outputTimezone).format(outputFormat); + } + +} + +export default TranslateDateTimeFormat; diff --git a/src/core/operations/UNIXTimestampToWindowsFiletime.mjs b/src/core/operations/UNIXTimestampToWindowsFiletime.mjs new file mode 100644 index 00000000..551b4273 --- /dev/null +++ b/src/core/operations/UNIXTimestampToWindowsFiletime.mjs @@ -0,0 +1,76 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import OperationError from "../errors/OperationError"; + +/** + * UNIX Timestamp to Windows Filetime operation + */ +class UNIXTimestampToWindowsFiletime extends Operation { + + /** + * UNIXTimestampToWindowsFiletime constructor + */ + constructor() { + super(); + + this.name = "UNIX Timestamp to Windows Filetime"; + this.module = "Default"; + this.description = "Converts a UNIX timestamp to a Windows Filetime value.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Input units", + "type": "option", + "value": ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"] + }, + { + "name": "Output format", + "type": "option", + "value": ["Decimal", "Hex"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [units, format] = args; + + if (!input) return ""; + + input = new BigNumber(input); + + if (units === "Seconds (s)"){ + input = input.multipliedBy(new BigNumber("10000000")); + } else if (units === "Milliseconds (ms)") { + input = input.multipliedBy(new BigNumber("10000")); + } else if (units === "Microseconds (μs)") { + input = input.multiplyiedBy(new BigNumber("10")); + } else if (units === "Nanoseconds (ns)") { + input = input.dividedBy(new BigNumber("100")); + } else { + throw new OperationError("Unrecognised unit"); + } + + input = input.plus(new BigNumber("116444736000000000")); + + if (format === "Hex"){ + return input.toString(16); + } else { + return input.toFixed(); + } + } + +} + +export default UNIXTimestampToWindowsFiletime; diff --git a/src/core/operations/URLDecode.mjs b/src/core/operations/URLDecode.mjs new file mode 100644 index 00000000..552dfe84 --- /dev/null +++ b/src/core/operations/URLDecode.mjs @@ -0,0 +1,51 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * URL Decode operation + */ +class URLDecode extends Operation { + + /** + * URLDecode constructor + */ + constructor() { + super(); + + this.name = "URL Decode"; + this.module = "URL"; + this.description = "Converts URI/URL percent-encoded characters back to their raw values.

e.g. %3d becomes ="; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + this.patterns = [ + { + match: ".*(?:%[\\da-f]{2}.*){4}", + flags: "i", + args: [] + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const data = input.replace(/\+/g, "%20"); + try { + return decodeURIComponent(data); + } catch (err) { + return unescape(data); + } + } + +} + +export default URLDecode; diff --git a/src/core/operations/URLEncode.mjs b/src/core/operations/URLEncode.mjs new file mode 100644 index 00000000..23fd8ec9 --- /dev/null +++ b/src/core/operations/URLEncode.mjs @@ -0,0 +1,68 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * URL Encode operation + */ +class URLEncode extends Operation { + + /** + * URLEncode constructor + */ + constructor() { + super(); + + this.name = "URL Encode"; + this.module = "URL"; + this.description = "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.

e.g. = becomes %3d"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Encode all special chars", + "type": "boolean", + "value": false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const encodeAll = args[0]; + return encodeAll ? this.encodeAllChars(input) : encodeURI(input); + } + + /** + * Encode characters in URL outside of encodeURI() function spec + * + * @param {string} str + * @returns {string} + */ + encodeAllChars (str) { + // TODO Do this programatically + return encodeURIComponent(str) + .replace(/!/g, "%21") + .replace(/#/g, "%23") + .replace(/'/g, "%27") + .replace(/\(/g, "%28") + .replace(/\)/g, "%29") + .replace(/\*/g, "%2A") + .replace(/-/g, "%2D") + .replace(/\./g, "%2E") + .replace(/_/g, "%5F") + .replace(/~/g, "%7E"); + } + +} + + +export default URLEncode; diff --git a/src/core/operations/UnescapeString.mjs b/src/core/operations/UnescapeString.mjs new file mode 100644 index 00000000..0500eecd --- /dev/null +++ b/src/core/operations/UnescapeString.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Unescape string operation + */ +class UnescapeString extends Operation { + + /** + * UnescapeString constructor + */ + constructor() { + super(); + + this.name = "Unescape string"; + this.module = "Default"; + this.description = "Unescapes characters in a string that have been escaped. For example, Don\\'t stop me now becomes Don't stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + return Utils.parseEscapedChars(input); + } + +} + +export default UnescapeString; diff --git a/src/core/operations/UnescapeUnicodeCharacters.mjs b/src/core/operations/UnescapeUnicodeCharacters.mjs new file mode 100644 index 00000000..ab8af2a8 --- /dev/null +++ b/src/core/operations/UnescapeUnicodeCharacters.mjs @@ -0,0 +1,75 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Unescape Unicode Characters operation + */ +class UnescapeUnicodeCharacters extends Operation { + + /** + * UnescapeUnicodeCharacters constructor + */ + constructor() { + super(); + + this.name = "Unescape Unicode Characters"; + this.module = "Default"; + this.description = "Converts unicode-escaped character notation back into raw characters.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. \\u03c3\\u03bf\\u03c5 becomes σου"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Prefix", + "type": "option", + "value": ["\\u", "%u", "U+"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const prefix = prefixToRegex[args[0]], + regex = new RegExp(prefix+"([a-f\\d]{4})", "ig"); + let output = "", + m, + i = 0; + + while ((m = regex.exec(input))) { + // Add up to match + output += input.slice(i, m.index); + i = m.index; + + // Add match + output += Utils.chr(parseInt(m[1], 16)); + + i = regex.lastIndex; + } + + // Add all after final match + output += input.slice(i, input.length); + + return output; + } + +} + +/** + * Lookup table to add prefixes to unicode delimiters so that they can be used in a regex. + */ +const prefixToRegex = { + "\\u": "\\\\u", + "%u": "%u", + "U+": "U\\+" +}; + +export default UnescapeUnicodeCharacters; diff --git a/src/core/operations/Unique.mjs b/src/core/operations/Unique.mjs new file mode 100644 index 00000000..6848968b --- /dev/null +++ b/src/core/operations/Unique.mjs @@ -0,0 +1,48 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; +import {INPUT_DELIM_OPTIONS} from "../lib/Delim"; + +/** + * Unique operation + */ +class Unique extends Operation { + + /** + * Unique constructor + */ + constructor() { + super(); + + this.name = "Unique"; + this.module = "Default"; + this.description = "Removes duplicate strings from the input."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Delimiter", + "type": "option", + "value": INPUT_DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const delim = Utils.charRep(args[0]); + return input.split(delim).unique().join(delim); + } + +} + +export default Unique; diff --git a/src/core/operations/Untar.mjs b/src/core/operations/Untar.mjs new file mode 100644 index 00000000..6bca05d0 --- /dev/null +++ b/src/core/operations/Untar.mjs @@ -0,0 +1,138 @@ +/** + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import Utils from "../Utils"; + +/** + * Untar operation + */ +class Untar extends Operation { + + /** + * Untar constructor + */ + constructor() { + super(); + + this.name = "Untar"; + this.module = "Compression"; + this.description = "Unpacks a tarball and displays it per file."; + this.inputType = "byteArray"; + this.outputType = "List"; + this.presentType = "html"; + this.args = []; + this.patterns = [ + { + "match": "^.{257}\\x75\\x73\\x74\\x61\\x72", + "flags": "", + "args": [] + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {List} + */ + run(input, args) { + const Stream = function(input) { + this.bytes = input; + this.position = 0; + }; + + Stream.prototype.getBytes = function(bytesToGet) { + const newPosition = this.position + bytesToGet; + const bytes = this.bytes.slice(this.position, newPosition); + this.position = newPosition; + return bytes; + }; + + Stream.prototype.readString = function(numBytes) { + let result = ""; + for (let i = this.position; i < this.position + numBytes; i++) { + const currentByte = this.bytes[i]; + if (currentByte === 0) break; + result += String.fromCharCode(currentByte); + } + this.position += numBytes; + return result; + }; + + Stream.prototype.readInt = function(numBytes, base) { + const string = this.readString(numBytes); + return parseInt(string, base); + }; + + Stream.prototype.hasMore = function() { + return this.position < this.bytes.length; + }; + + const stream = new Stream(input), + files = []; + + while (stream.hasMore()) { + const dataPosition = stream.position + 512; + + const file = { + fileName: stream.readString(100), + fileMode: stream.readString(8), + ownerUID: stream.readString(8), + ownerGID: stream.readString(8), + size: parseInt(stream.readString(12), 8), // Octal + lastModTime: new Date(1000 * stream.readInt(12, 8)), // Octal + checksum: stream.readString(8), + type: stream.readString(1), + linkedFileName: stream.readString(100), + USTARFormat: stream.readString(6).indexOf("ustar") >= 0, + }; + + if (file.USTARFormat) { + file.version = stream.readString(2); + file.ownerUserName = stream.readString(32); + file.ownerGroupName = stream.readString(32); + file.deviceMajor = stream.readString(8); + file.deviceMinor = stream.readString(8); + file.filenamePrefix = stream.readString(155); + } + + stream.position = dataPosition; + + if (file.type === "0") { + // File + let endPosition = stream.position + file.size; + if (file.size % 512 !== 0) { + endPosition += 512 - (file.size % 512); + } + + file.bytes = stream.getBytes(file.size); + files.push(new File([new Uint8Array(file.bytes)], file.fileName)); + stream.position = endPosition; + } else if (file.type === "5") { + // Directory + files.push(new File([new Uint8Array(file.bytes)], file.fileName)); + } else { + // Symlink or empty bytes + } + } + + return files; + } + + /** + * Displays the files in HTML for web apps. + * + * @param {File[]} files + * @returns {html} + */ + async present(files) { + return await Utils.displayFilesAsHTML(files); + } + +} + +export default Untar; diff --git a/src/core/operations/Unzip.mjs b/src/core/operations/Unzip.mjs index e94b1858..8e6bb633 100644 --- a/src/core/operations/Unzip.mjs +++ b/src/core/operations/Unzip.mjs @@ -39,6 +39,13 @@ class Unzip extends Operation { value: false } ]; + this.patterns = [ + { + match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)", + flags: "", + args: ["", false] + }, + ]; } /** diff --git a/src/core/operations/VigenèreDecode.mjs b/src/core/operations/VigenèreDecode.mjs new file mode 100644 index 00000000..b1512a3e --- /dev/null +++ b/src/core/operations/VigenèreDecode.mjs @@ -0,0 +1,101 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; +/** + * Vigenère Decode operation + */ +class VigenèreDecode extends Operation { + + /** + * VigenèreDecode constructor + */ + constructor() { + super(); + + this.name = "Vigenère Decode"; + this.module = "Ciphers"; + this.description = "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const alphabet = "abcdefghijklmnopqrstuvwxyz", + key = args[0].toLowerCase(); + let output = "", + fail = 0, + keyIndex, + msgIndex, + chr; + + if (!key) throw new OperationError("No key entered"); + if (!/^[a-zA-Z]+$/.test(key)) throw new OperationError("The key must consist only of letters"); + + for (let i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + chr = key[(i - fail) % key.length]; + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i]); + // Subtract indexes from each other, add 26 just in case the value is negative, + // modulo to remove if neccessary + output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26]; + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + chr = key[(i - fail) % key.length].toLowerCase(); + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i].toLowerCase()); + output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase(); + } else { + output += input[i]; + fail++; + } + } + + return output; + } + + /** + * Highlight Vigenère Decode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Vigenère Decode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default VigenèreDecode; diff --git a/src/core/operations/VigenèreEncode.mjs b/src/core/operations/VigenèreEncode.mjs new file mode 100644 index 00000000..9172ed06 --- /dev/null +++ b/src/core/operations/VigenèreEncode.mjs @@ -0,0 +1,106 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * Vigenère Encode operation + */ +class VigenèreEncode extends Operation { + + /** + * VigenèreEncode constructor + */ + constructor() { + super(); + + this.name = "Vigenère Encode"; + this.module = "Ciphers"; + this.description = "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const alphabet = "abcdefghijklmnopqrstuvwxyz", + key = args[0].toLowerCase(); + let output = "", + fail = 0, + keyIndex, + msgIndex, + chr; + + if (!key) throw new OperationError("No key entered"); + if (!/^[a-zA-Z]+$/.test(key)) throw new OperationError("The key must consist only of letters"); + + for (let i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + // Get the corresponding character of key for the current letter, accounting + // for chars not in alphabet + chr = key[(i - fail) % key.length]; + // Get the location in the vigenere square of the key char + keyIndex = alphabet.indexOf(chr); + // Get the location in the vigenere square of the message char + msgIndex = alphabet.indexOf(input[i]); + // Get the encoded letter by finding the sum of indexes modulo 26 and finding + // the letter corresponding to that + output += alphabet[(keyIndex + msgIndex) % 26]; + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + chr = key[(i - fail) % key.length].toLowerCase(); + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i].toLowerCase()); + output += alphabet[(keyIndex + msgIndex) % 26].toUpperCase(); + } else { + output += input[i]; + fail++; + } + } + + return output; + } + + /** + * Highlight Vigenère Encode + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight Vigenère Encode in reverse + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlightReverse(pos, args) { + return pos; + } + +} + +export default VigenèreEncode; diff --git a/src/core/operations/Whirlpool.mjs b/src/core/operations/Whirlpool.mjs new file mode 100644 index 00000000..1d32f244 --- /dev/null +++ b/src/core/operations/Whirlpool.mjs @@ -0,0 +1,47 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import {runHash} from "../lib/Hash"; + +/** + * Whirlpool operation + */ +class Whirlpool extends Operation { + + /** + * Whirlpool constructor + */ + constructor() { + super(); + + this.name = "Whirlpool"; + this.module = "Hashing"; + this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.

Several variants exist:
  • Whirlpool-0 is the original version released in 2000.
  • Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.
  • Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.
"; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + { + "name": "Variant", + "type": "option", + "value": ["Whirlpool", "Whirlpool-T", "Whirlpool-0"] + } + ]; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const variant = args[0].toLowerCase(); + return runHash(variant, input); + } + +} + +export default Whirlpool; diff --git a/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs b/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs new file mode 100644 index 00000000..b3d66476 --- /dev/null +++ b/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs @@ -0,0 +1,76 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import OperationError from "../errors/OperationError"; + +/** + * Windows Filetime to UNIX Timestamp operation + */ +class WindowsFiletimeToUNIXTimestamp extends Operation { + + /** + * WindowsFiletimeToUNIXTimestamp constructor + */ + constructor() { + super(); + + this.name = "Windows Filetime to UNIX Timestamp"; + this.module = "Default"; + this.description = "Converts a Windows Filetime value to a UNIX timestamp.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Output units", + "type": "option", + "value": ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"] + }, + { + "name": "Input format", + "type": "option", + "value": ["Decimal", "Hex"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [units, format] = args; + + if (!input) return ""; + + if (format === "Hex") { + input = new BigNumber(input, 16); + } else { + input = new BigNumber(input); + } + + input = input.minus(new BigNumber("116444736000000000")); + + if (units === "Seconds (s)"){ + input = input.dividedBy(new BigNumber("10000000")); + } else if (units === "Milliseconds (ms)") { + input = input.dividedBy(new BigNumber("10000")); + } else if (units === "Microseconds (μs)") { + input = input.dividedBy(new BigNumber("10")); + } else if (units === "Nanoseconds (ns)") { + input = input.multipliedBy(new BigNumber("100")); + } else { + throw new OperationError("Unrecognised unit"); + } + + return input.toFixed(); + } + +} + +export default WindowsFiletimeToUNIXTimestamp; diff --git a/src/core/operations/XKCDRandomNumber.mjs b/src/core/operations/XKCDRandomNumber.mjs new file mode 100644 index 00000000..a9481fbf --- /dev/null +++ b/src/core/operations/XKCDRandomNumber.mjs @@ -0,0 +1,40 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; + +/** + * XKCD Random Number operation + */ +class XKCDRandomNumber extends Operation { + + /** + * XKCDRandomNumber constructor + */ + constructor() { + super(); + + this.name = "XKCD Random Number"; + this.module = "Default"; + this.description = "RFC 1149.5 specifies 4 as the standard IEEE-vetted random number.

XKCD #221"; + this.inputType = "string"; + this.outputType = "number"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {number} + */ + run(input, args) { + return 4; // chosen by fair dice roll. + // guaranteed to be random. + } + +} + +export default XKCDRandomNumber; diff --git a/src/core/operations/ZlibInflate.mjs b/src/core/operations/ZlibInflate.mjs index e50ddd05..36f841d5 100644 --- a/src/core/operations/ZlibInflate.mjs +++ b/src/core/operations/ZlibInflate.mjs @@ -58,6 +58,13 @@ class ZlibInflate extends Operation { value: false } ]; + this.patterns = [ + { + match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)", + flags: "", + args: [0, 0, "Adaptive", false, false] + }, + ]; } /** diff --git a/src/core/operations/legacy/Arithmetic.js b/src/core/operations/legacy/Arithmetic.js index 9be35fd7..e1e44981 100644 --- a/src/core/operations/legacy/Arithmetic.js +++ b/src/core/operations/legacy/Arithmetic.js @@ -1,3 +1,9 @@ +/** + * @author d98762625 [d98762625@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + import Utils from "../Utils.js"; import BigNumber from "bignumber.js"; diff --git a/src/core/operations/legacy/BSON.js b/src/core/operations/legacy/BSON.js index 52ee98bc..4f0d484f 100644 --- a/src/core/operations/legacy/BSON.js +++ b/src/core/operations/legacy/BSON.js @@ -29,7 +29,7 @@ const BSON = { const data = JSON.parse(input); return bson.serialize(data).buffer; } catch (err) { - return err.toString(); + throw err.toString(); } }, diff --git a/src/core/operations/legacy/ByteRepr.js b/src/core/operations/legacy/ByteRepr.js index 6bf91bb6..548db525 100755 --- a/src/core/operations/legacy/ByteRepr.js +++ b/src/core/operations/legacy/ByteRepr.js @@ -18,6 +18,16 @@ const ByteRepr = { * @default */ DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], + /** + * @constant + * @default + */ + TO_HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"], + /** + * @constant + * @default + */ + FROM_HEX_DELIM_OPTIONS: ["Auto", "Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"], /** * @constant * @default diff --git a/src/core/operations/legacy/Checksum.js b/src/core/operations/legacy/Checksum.js index 58aac4bd..6b2cb31c 100755 --- a/src/core/operations/legacy/Checksum.js +++ b/src/core/operations/legacy/Checksum.js @@ -120,7 +120,7 @@ const Checksum = { /** * CRC-32 Checksum operation. * - * @param {string} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ @@ -132,7 +132,7 @@ const Checksum = { /** * CRC-16 Checksum operation. * - * @param {string} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ diff --git a/src/core/operations/legacy/Cipher.js b/src/core/operations/legacy/Cipher.js index e350c17a..197560c1 100755 --- a/src/core/operations/legacy/Cipher.js +++ b/src/core/operations/legacy/Cipher.js @@ -444,80 +444,6 @@ DES uses a key length of 8 bytes (64 bits).`; }, - /** - * Derive EVP key operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runEvpkdf: function (input, args) { - const passphrase = Utils.convertToByteString(args[0].string, args[0].option), - keySize = args[1] / 32, - iterations = args[2], - hasher = args[3], - salt = Utils.convertToByteString(args[4].string, args[4].option), - key = CryptoJS.EvpKDF(passphrase, salt, { - keySize: keySize, - hasher: CryptoJS.algo[hasher], - iterations: iterations, - }); - - return key.toString(CryptoJS.enc.Hex); - }, - - - /** - * @constant - * @default - */ - RC4_KEY_FORMAT: ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Hex", "Base64"], - /** - * @constant - * @default - */ - CJS_IO_FORMAT: ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"], - - - /** - * RC4 operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runRc4: function (input, args) { - let message = Cipher._format[args[1]].parse(input), - passphrase = Cipher._format[args[0].option].parse(args[0].string), - encrypted = CryptoJS.RC4.encrypt(message, passphrase); - - return encrypted.ciphertext.toString(Cipher._format[args[2]]); - }, - - - /** - * @constant - * @default - */ - RC4DROP_BYTES: 768, - - /** - * RC4 Drop operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runRc4drop: function (input, args) { - let message = Cipher._format[args[1]].parse(input), - passphrase = Cipher._format[args[0].option].parse(args[0].string), - drop = args[3], - encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop }); - - return encrypted.ciphertext.toString(Cipher._format[args[2]]); - }, - - /** * @constant * @default @@ -568,468 +494,6 @@ DES uses a key length of 8 bytes (64 bits).`; } }, - - /** - * Vigenère Encode operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runVigenereEnc: function (input, args) { - let alphabet = "abcdefghijklmnopqrstuvwxyz", - key = args[0].toLowerCase(), - output = "", - fail = 0, - keyIndex, - msgIndex, - chr; - - if (!key) return "No key entered"; - if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters"; - - for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { - // Get the corresponding character of key for the current letter, accounting - // for chars not in alphabet - chr = key[(i - fail) % key.length]; - // Get the location in the vigenere square of the key char - keyIndex = alphabet.indexOf(chr); - // Get the location in the vigenere square of the message char - msgIndex = alphabet.indexOf(input[i]); - // Get the encoded letter by finding the sum of indexes modulo 26 and finding - // the letter corresponding to that - output += alphabet[(keyIndex + msgIndex) % 26]; - } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { - chr = key[(i - fail) % key.length].toLowerCase(); - keyIndex = alphabet.indexOf(chr); - msgIndex = alphabet.indexOf(input[i].toLowerCase()); - output += alphabet[(keyIndex + msgIndex) % 26].toUpperCase(); - } else { - output += input[i]; - fail++; - } - } - - return output; - }, - - - /** - * Vigenère Decode operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runVigenereDec: function (input, args) { - let alphabet = "abcdefghijklmnopqrstuvwxyz", - key = args[0].toLowerCase(), - output = "", - fail = 0, - keyIndex, - msgIndex, - chr; - - if (!key) return "No key entered"; - if (!/^[a-zA-Z]+$/.test(key)) return "The key must consist only of letters"; - - for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { - chr = key[(i - fail) % key.length]; - keyIndex = alphabet.indexOf(chr); - msgIndex = alphabet.indexOf(input[i]); - // Subtract indexes from each other, add 26 just in case the value is negative, - // modulo to remove if neccessary - output += alphabet[(msgIndex - keyIndex + alphabet.length) % 26]; - } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { - chr = key[(i - fail) % key.length].toLowerCase(); - keyIndex = alphabet.indexOf(chr); - msgIndex = alphabet.indexOf(input[i].toLowerCase()); - output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase(); - } else { - output += input[i]; - fail++; - } - } - - return output; - }, - - - /** - * @constant - * @default - */ - AFFINE_A: 1, - /** - * @constant - * @default - */ - AFFINE_B: 0, - - /** - * Affine Cipher Encode operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runAffineEnc: function (input, args) { - let alphabet = "abcdefghijklmnopqrstuvwxyz", - a = args[0], - b = args[1], - output = ""; - - if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) { - return "The values of a and b can only be integers."; - } - - for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { - // Uses the affine function ax+b % m = y (where m is length of the alphabet) - output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26]; - } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { - // Same as above, accounting for uppercase - output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase(); - } else { - // Non-alphabetic characters - output += input[i]; - } - } - return output; - }, - - - /** - * Affine Cipher Decode operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runAffineDec: function (input, args) { - let alphabet = "abcdefghijklmnopqrstuvwxyz", - a = args[0], - b = args[1], - output = "", - aModInv; - - if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) { - return "The values of a and b can only be integers."; - } - - if (Utils.gcd(a, 26) !== 1) { - return "The value of a must be coprime to 26."; - } - - // Calculates modular inverse of a - aModInv = Utils.modInv(a, 26); - - for (let i = 0; i < input.length; i++) { - if (alphabet.indexOf(input[i]) >= 0) { - // Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse) - output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)]; - } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { - // Same as above, accounting for uppercase - output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase(); - } else { - // Non-alphabetic characters - output += input[i]; - } - } - return output; - }, - - - /** - * Atbash Cipher Encode operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runAtbash: function (input, args) { - return Cipher.runAffineEnc(input, [25, 25]); - }, - - - /** - * Generates a polybius square for the given keyword - * - * @private - * @author Matt C [matt@artemisbot.uk] - * @param {string} keyword - Must be upper case - * @returns {string} - */ - _genPolybiusSquare: function (keyword) { - const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"; - const polArray = `${keyword}${alpha}`.split("").unique(); - let polybius = []; - - for (let i = 0; i < 5; i++) { - polybius[i] = polArray.slice(i*5, i*5 + 5); - } - - return polybius; - }, - - /** - * Bifid Cipher Encode operation - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runBifidEnc: function (input, args) { - const keywordStr = args[0].toUpperCase().replace("J", "I"), - keyword = keywordStr.split("").unique(), - alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"; - - let output = "", - xCo = [], - yCo = [], - structure = [], - count = 0; - - if (keyword.length > 25) - return "The alphabet keyword must be less than 25 characters."; - - if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0) - return "The key must consist only of letters"; - - const polybius = Cipher._genPolybiusSquare(keywordStr); - - input.replace("J", "I").split("").forEach(letter => { - let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0, - polInd; - - if (alpInd) { - for (let i = 0; i < 5; i++) { - polInd = polybius[i].indexOf(letter.toLocaleUpperCase()); - if (polInd >= 0) { - xCo.push(polInd); - yCo.push(i); - } - } - - if (alpha.split("").indexOf(letter) >= 0) { - structure.push(true); - } else if (alpInd) { - structure.push(false); - } - } else { - structure.push(letter); - } - }); - - const trans = `${yCo.join("")}${xCo.join("")}`; - - structure.forEach(pos => { - if (typeof pos === "boolean") { - let coords = trans.substr(2*count, 2).split(""); - - output += pos ? - polybius[coords[0]][coords[1]] : - polybius[coords[0]][coords[1]].toLocaleLowerCase(); - count++; - } else { - output += pos; - } - }); - - return output; - }, - - /** - * Bifid Cipher Decode operation - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runBifidDec: function (input, args) { - const keywordStr = args[0].toUpperCase().replace("J", "I"), - keyword = keywordStr.split("").unique(), - alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ"; - - let output = "", - structure = [], - count = 0, - trans = ""; - - if (keyword.length > 25) - return "The alphabet keyword must be less than 25 characters."; - - if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0) - return "The key must consist only of letters"; - - const polybius = Cipher._genPolybiusSquare(keywordStr); - - input.replace("J", "I").split("").forEach((letter) => { - let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0, - polInd; - - if (alpInd) { - for (let i = 0; i < 5; i++) { - polInd = polybius[i].indexOf(letter.toLocaleUpperCase()); - if (polInd >= 0) { - trans += `${i}${polInd}`; - } - } - - if (alpha.split("").indexOf(letter) >= 0) { - structure.push(true); - } else if (alpInd) { - structure.push(false); - } - } else { - structure.push(letter); - } - }); - - structure.forEach(pos => { - if (typeof pos === "boolean") { - let coords = [trans[count], trans[count+trans.length/2]]; - - output += pos ? - polybius[coords[0]][coords[1]] : - polybius[coords[0]][coords[1]].toLocaleLowerCase(); - count++; - } else { - output += pos; - } - }); - - return output; - }, - - - /** - * @constant - * @default - */ - SUBS_PLAINTEXT: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - /** - * @constant - * @default - */ - SUBS_CIPHERTEXT: "XYZABCDEFGHIJKLMNOPQRSTUVW", - - /** - * Substitute operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runSubstitute: function (input, args) { - let plaintext = Utils.expandAlphRange(args[0]).join(""), - ciphertext = Utils.expandAlphRange(args[1]).join(""), - output = "", - index = -1; - - if (plaintext.length !== ciphertext.length) { - output = "Warning: Plaintext and Ciphertext lengths differ\n\n"; - } - - for (let i = 0; i < input.length; i++) { - index = plaintext.indexOf(input[i]); - output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]; - } - - return output; - }, - - - /** - * A mapping of string formats to their classes in the CryptoJS library. - * - * @private - * @constant - */ - _format: { - "Hex": CryptoJS.enc.Hex, - "Base64": CryptoJS.enc.Base64, - "UTF8": CryptoJS.enc.Utf8, - "UTF16": CryptoJS.enc.Utf16, - "UTF16LE": CryptoJS.enc.Utf16LE, - "UTF16BE": CryptoJS.enc.Utf16BE, - "Latin1": CryptoJS.enc.Latin1, - }, - }; export default Cipher; - - -/** - * Overwriting the CryptoJS OpenSSL key derivation function so that it is possible to not pass a - * salt in. - - * @param {string} password - The password to derive from. - * @param {number} keySize - The size in words of the key to generate. - * @param {number} ivSize - The size in words of the IV to generate. - * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be - * generated randomly. If set to false, no salt will be added. - * - * @returns {CipherParams} A cipher params object with the key, IV, and salt. - * - * @static - * - * @example - * // Randomly generates a salt - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); - * // Uses the salt 'saltsalt' - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); - * // Does not use a salt - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, false); - */ -CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) { - // Generate random salt if no salt specified and not set to false - // This line changed from `if (!salt) {` to the following - if (salt === undefined || salt === null) { - salt = CryptoJS.lib.WordArray.random(64/8); - } - - // Derive key and IV - const key = CryptoJS.algo.EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); - - // Separate key and IV - const iv = CryptoJS.lib.WordArray.create(key.words.slice(keySize), ivSize * 4); - key.sigBytes = keySize * 4; - - // Return params - return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt }); -}; - - -/** - * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse - * the hex string. - * - * @param {string} hexStr - * @returns {CryptoJS.lib.WordArray} - */ -CryptoJS.enc.Hex.parse = function (hexStr) { - // Remove whitespace - hexStr = hexStr.replace(/\s/g, ""); - - // Shortcut - const hexStrLength = hexStr.length; - - // Convert - const words = []; - for (let i = 0; i < hexStrLength; i += 2) { - words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); - } - - return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2); -}; diff --git a/src/core/operations/legacy/Extract.js b/src/core/operations/legacy/Extract.js deleted file mode 100755 index 92c75a21..00000000 --- a/src/core/operations/legacy/Extract.js +++ /dev/null @@ -1,333 +0,0 @@ -import XRegExp from "xregexp"; - - -/** - * Identifier extraction operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Extract = { - - /** - * Runs search operations across the input data using regular expressions. - * - * @private - * @param {string} input - * @param {RegExp} searchRegex - * @param {RegExp} removeRegex - A regular expression defining results to remove from the - * final list - * @param {boolean} includeTotal - Whether or not to include the total number of results - * @returns {string} - */ - _search: function(input, searchRegex, removeRegex, includeTotal) { - let output = "", - total = 0, - match; - - while ((match = searchRegex.exec(input))) { - // Moves pointer when an empty string is matched (prevents infinite loop) - if (match.index === searchRegex.lastIndex) { - searchRegex.lastIndex++; - } - - if (removeRegex && removeRegex.test(match[0])) - continue; - total++; - output += match[0] + "\n"; - } - - if (includeTotal) - output = "Total found: " + total + "\n\n" + output; - - return output; - }, - - - /** - * @constant - * @default - */ - MIN_STRING_LEN: 4, - /** - * @constant - * @default - */ - STRING_MATCH_TYPE: [ - "[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)", - "[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)" - ], - /** - * @constant - * @default - */ - ENCODING_LIST: ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"], - /** - * @constant - * @default - */ - DISPLAY_TOTAL: false, - - /** - * Strings operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runStrings: function(input, args) { - const encoding = args[0], - minLen = args[1], - matchType = args[2], - displayTotal = args[3], - alphanumeric = "A-Z\\d", - punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@", - printable = "\x20-\x7e", - uniAlphanumeric = "\\pL\\pN", - uniPunctuation = "\\pP\\pZ", - uniPrintable = "\\pL\\pM\\pZ\\pS\\pN\\pP"; - - let strings = ""; - - switch (matchType) { - case "Alphanumeric + punctuation (A)": - strings = `[${alphanumeric + punctuation}]`; - break; - case "All printable chars (A)": - case "Null-terminated strings (A)": - strings = `[${printable}]`; - break; - case "Alphanumeric + punctuation (U)": - strings = `[${uniAlphanumeric + uniPunctuation}]`; - break; - case "All printable chars (U)": - case "Null-terminated strings (U)": - strings = `[${uniPrintable}]`; - break; - } - - // UTF-16 support is hacked in by allowing null bytes on either side of the matched chars - switch (encoding) { - case "All": - strings = `(\x00?${strings}\x00?)`; - break; - case "16-bit littleendian": - strings = `(${strings}\x00)`; - break; - case "16-bit bigendian": - strings = `(\x00${strings})`; - break; - case "Single byte": - default: - break; - } - - strings = `${strings}{${minLen},}`; - - if (matchType.includes("Null-terminated")) { - strings += "\x00"; - } - - const regex = new XRegExp(strings, "ig"); - - return Extract._search(input, regex, null, displayTotal); - }, - - - /** - * @constant - * @default - */ - INCLUDE_IPV4: true, - /** - * @constant - * @default - */ - INCLUDE_IPV6: false, - /** - * @constant - * @default - */ - REMOVE_LOCAL: false, - - /** - * Extract IP addresses operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runIp: function(input, args) { - let includeIpv4 = args[0], - includeIpv6 = args[1], - removeLocal = args[2], - displayTotal = args[3], - ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?", - ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})", - ips = ""; - - if (includeIpv4 && includeIpv6) { - ips = ipv4 + "|" + ipv6; - } else if (includeIpv4) { - ips = ipv4; - } else if (includeIpv6) { - ips = ipv6; - } - - if (ips) { - const regex = new RegExp(ips, "ig"); - - if (removeLocal) { - let ten = "10\\..+", - oneninetwo = "192\\.168\\..+", - oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", - onetwoseven = "127\\..+", - removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + - "|" + oneseventwo + "|" + onetwoseven + ")"); - - return Extract._search(input, regex, removeRegex, displayTotal); - } else { - return Extract._search(input, regex, null, displayTotal); - } - } else { - return ""; - } - }, - - - /** - * Extract email addresses operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runEmail: function(input, args) { - let displayTotal = args[0], - regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig; - - return Extract._search(input, regex, null, displayTotal); - }, - - - /** - * Extract MAC addresses operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runMac: function(input, args) { - let displayTotal = args[0], - regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig; - - return Extract._search(input, regex, null, displayTotal); - }, - - - /** - * Extract URLs operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runUrls: function(input, args) { - let displayTotal = args[0], - protocol = "[A-Z]+://", - hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+", - port = ":\\d+", - path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*"; - - path += "(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*"; - const regex = new RegExp(protocol + hostname + "(?:" + port + - ")?(?:" + path + ")?", "ig"); - return Extract._search(input, regex, null, displayTotal); - }, - - - /** - * Extract domains operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runDomains: function(input, args) { - const displayTotal = args[0], - regex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig; - - return Extract._search(input, regex, null, displayTotal); - }, - - - /** - * @constant - * @default - */ - INCLUDE_WIN_PATH: true, - /** - * @constant - * @default - */ - INCLUDE_UNIX_PATH: true, - - /** - * Extract file paths operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFilePaths: function(input, args) { - let includeWinPath = args[0], - includeUnixPath = args[1], - displayTotal = args[2], - winDrive = "[A-Z]:\\\\", - winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}", - winExt = "[A-Z\\d]{1,6}", - winPath = winDrive + "(?:" + winName + "\\\\?)*" + winName + - "(?:\\." + winExt + ")?", - unixPath = "(?:/[A-Z\\d.][A-Z\\d\\-.]{0,61})+", - filePaths = ""; - - if (includeWinPath && includeUnixPath) { - filePaths = winPath + "|" + unixPath; - } else if (includeWinPath) { - filePaths = winPath; - } else if (includeUnixPath) { - filePaths = unixPath; - } - - if (filePaths) { - const regex = new RegExp(filePaths, "ig"); - return Extract._search(input, regex, null, displayTotal); - } else { - return ""; - } - }, - - - /** - * Extract dates operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runDates: function(input, args) { - let displayTotal = args[0], - date1 = "(?:19|20)\\d\\d[- /.](?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])", // yyyy-mm-dd - date2 = "(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\\d\\d", // dd/mm/yyyy - date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy - regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig"); - - return Extract._search(input, regex, null, displayTotal); - }, - -}; - -export default Extract; diff --git a/src/core/operations/legacy/FileType.js b/src/core/operations/legacy/FileType.js index 715f8205..b9d399cd 100755 --- a/src/core/operations/legacy/FileType.js +++ b/src/core/operations/legacy/FileType.js @@ -225,8 +225,8 @@ const FileType = { if (buf[0] === 0x78 && buf[1] === 0x01) { return { - ext: "dmg", - mime: "application/x-apple-diskimage" + ext: "dmg, zlib", + mime: "application/x-apple-diskimage, application/x-deflate" }; } @@ -434,8 +434,11 @@ const FileType = { }; } - // Added by n1474335 [n1474335@gmail.com] from here on - // ################################################################## // + /** + * + * Added by n1474335 [n1474335@gmail.com] from here on + * + */ if ((buf[0] === 0x1F && buf[1] === 0x9D) || (buf[0] === 0x1F && buf[1] === 0xA0)) { return { ext: "z, tar.z", @@ -469,16 +472,16 @@ const FileType = { // Must be before Little-endian UTF-16 BOM if (buf[0] === 0xFF && buf[1] === 0xFE && buf[2] === 0x00 && buf[3] === 0x00) { return { - ext: "", - mime: "", + ext: "UTF32LE", + mime: "charset/utf32le", desc: "Little-endian UTF-32 encoded Unicode byte order mark detected." }; } if (buf[0] === 0xFF && buf[1] === 0xFE) { return { - ext: "", - mime: "", + ext: "UTF16LE", + mime: "charset/utf16le", desc: "Little-endian UTF-16 encoded Unicode byte order mark detected." }; } @@ -524,6 +527,13 @@ const FileType = { }; } + if (buf[0] === 0x78 && (buf[1] === 0x01 || buf[1] === 0x9C || buf[1] === 0xDA || buf[1] === 0x5e)) { + return { + ext: "zlib", + mime: "application/x-deflate" + }; + } + return null; }, diff --git a/src/core/operations/legacy/PublicKey.js b/src/core/operations/legacy/PublicKey.js index 80c35196..a52caf25 100755 --- a/src/core/operations/legacy/PublicKey.js +++ b/src/core/operations/legacy/PublicKey.js @@ -62,7 +62,7 @@ const PublicKey = { pkStr = "", sig = cert.getSignatureValueHex(), sigStr = "", - extensions = cert.getInfo().split("X509v3 Extensions:\n")[1].split("signature")[0]; + extensions = ""; // Public Key fields pkFields.push({ @@ -144,6 +144,10 @@ const PublicKey = { sigStr = " Signature: " + PublicKey._formatByteStr(sig, 16, 18); } + // Extensions + try { + extensions = cert.getInfo().split("X509v3 Extensions:\n")[1].split("signature")[0]; + } catch (err) {} let issuerStr = PublicKey._formatDnStr(issuer, 2), nbDate = PublicKey._formatDate(cert.getNotBefore()), diff --git a/src/core/operations/legacy/ToTable.js b/src/core/operations/legacy/ToTable.js new file mode 100644 index 00000000..b18b56f1 --- /dev/null +++ b/src/core/operations/legacy/ToTable.js @@ -0,0 +1,164 @@ +/** + * ToTable operations. + * + * @author Mark Jones [github.com/justanothermark] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + * + * @namespace + */ +import Utils from "../Utils.js"; + +const ToTable = { + + /** + * @constant + * @default + */ + FORMATS: [ + "ASCII", + "HTML" + ], + + + /** + * To Table operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + runToTable: function (input, args) { + const [cellDelims, rowDelims, firstRowHeader, format] = args; + + // Process the input into a nested array of elements. + const tableData = Utils.parseCSV(input, cellDelims.split(""), rowDelims.split("")); + + if (!tableData.length) return ""; + + // Render the data in the requested format. + switch (format) { + case "ASCII": + return asciiOutput(tableData); + case "HTML": + default: + return htmlOutput(tableData); + } + + /** + * Outputs an array of data as an ASCII table. + * + * @param {string[][]} tableData + * @returns {string} + */ + function asciiOutput(tableData) { + const horizontalBorder = "-"; + const verticalBorder = "|"; + const crossBorder = "+"; + + let output = ""; + let longestCells = []; + + // Find longestCells value per column to pad cells equally. + tableData.forEach(function(row, index) { + row.forEach(function(cell, cellIndex) { + if (longestCells[cellIndex] === undefined || cell.length > longestCells[cellIndex]) { + longestCells[cellIndex] = cell.length; + } + }); + }); + + // Add the top border of the table to the output. + output += outputHorizontalBorder(longestCells); + + // If the first row is a header, remove the row from the data and + // add it to the output with another horizontal border. + if (firstRowHeader) { + let row = tableData.shift(); + output += outputRow(row, longestCells); + output += outputHorizontalBorder(longestCells); + } + + // Add the rest of the table rows. + tableData.forEach(function(row, index) { + output += outputRow(row, longestCells); + }); + + // Close the table with a final horizontal border. + output += outputHorizontalBorder(longestCells); + + return output; + + /** + * Outputs a row of correctly padded cells. + */ + function outputRow(row, longestCells) { + let rowOutput = verticalBorder; + row.forEach(function(cell, index) { + rowOutput += " " + cell + " ".repeat(longestCells[index] - cell.length) + " " + verticalBorder; + }); + rowOutput += "\n"; + return rowOutput; + } + + /** + * Outputs a horizontal border with a different character where + * the horizontal border meets a vertical border. + */ + function outputHorizontalBorder(longestCells) { + let rowOutput = crossBorder; + longestCells.forEach(function(cellLength) { + rowOutput += horizontalBorder.repeat(cellLength + 2) + crossBorder; + }); + rowOutput += "\n"; + return rowOutput; + } + } + + /** + * Outputs a table of data as a HTML table. + * + * @param {string[][]} tableData + * @returns {string} + */ + function htmlOutput(tableData) { + // Start the HTML output with suitable classes for styling. + let output = ""; + + // If the first row is a header then put it in with "; + output += outputRow(row, "th"); + output += ""; + } + + // Output the rest of the rows in the . + output += ""; + tableData.forEach(function(row, index) { + output += outputRow(row, "td"); + }); + + // Close the body and table elements. + output += "
cells. + if (firstRowHeader) { + let row = tableData.shift(); + output += "
"; + return output; + + /** + * Outputs a table row. + * + * @param {string[]} row + * @param {string} cellType + */ + function outputRow(row, cellType) { + let output = ""; + row.forEach(function(cell) { + output += "<" + cellType + ">" + cell + ""; + }); + output += ""; + return output; + } + } + } +}; + +export default ToTable; diff --git a/src/core/operations/legacy/URL.js b/src/core/operations/legacy/URL.js deleted file mode 100755 index 2f30c952..00000000 --- a/src/core/operations/legacy/URL.js +++ /dev/null @@ -1,118 +0,0 @@ -/* globals unescape */ -import url from "url"; - - -/** - * URL operations. - * Namespace is appended with an underscore to prevent overwriting the global URL object. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const URL_ = { - - /** - * @constant - * @default - */ - ENCODE_ALL: false, - - /** - * URL Encode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runTo: function(input, args) { - const encodeAll = args[0]; - return encodeAll ? URL_._encodeAllChars(input) : encodeURI(input); - }, - - - /** - * URL Decode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFrom: function(input, args) { - const data = input.replace(/\+/g, "%20"); - try { - return decodeURIComponent(data); - } catch (err) { - return unescape(data); - } - }, - - - /** - * Parse URI operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParse: function(input, args) { - const uri = url.parse(input, true); - - let output = ""; - - if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n"; - if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n"; - if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n"; - if (uri.port) output += "Port:\t\t" + uri.port + "\n"; - if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n"; - if (uri.query) { - let keys = Object.keys(uri.query), - padding = 0; - - keys.forEach(k => { - padding = (k.length > padding) ? k.length : padding; - }); - - output += "Arguments:\n"; - for (let key in uri.query) { - output += "\t" + key.padEnd(padding, " "); - if (uri.query[key].length) { - output += " = " + uri.query[key] + "\n"; - } else { - output += "\n"; - } - } - } - if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n"; - - return output; - }, - - - /** - * URL encodes additional special characters beyond the standard set. - * - * @private - * @param {string} str - * @returns {string} - */ - _encodeAllChars: function(str) { - //TODO Do this programatically - return encodeURIComponent(str) - .replace(/!/g, "%21") - .replace(/#/g, "%23") - .replace(/'/g, "%27") - .replace(/\(/g, "%28") - .replace(/\)/g, "%29") - .replace(/\*/g, "%2A") - .replace(/-/g, "%2D") - .replace(/\./g, "%2E") - .replace(/_/g, "%5F") - .replace(/~/g, "%7E"); - }, - -}; - -export default URL_; diff --git a/src/core/vendor/DisassembleX86-64.js b/src/core/vendor/DisassembleX86-64.mjs similarity index 99% rename from src/core/vendor/DisassembleX86-64.js rename to src/core/vendor/DisassembleX86-64.mjs index e320c6c2..f0d30511 100644 --- a/src/core/vendor/DisassembleX86-64.js +++ b/src/core/vendor/DisassembleX86-64.mjs @@ -3316,7 +3316,7 @@ If input "type" is set 5 it will adjust the mnemonic array to decode Centaur ins If input "type" is set 6 it will adjust the mnemonic array to decode instruction for the X86/486 CPU which conflict with the vector unit instructions with UMOV. -------------------------------------------------------------------------------------------------------------------------*/ -function CompatibilityMode( type ) +export function CompatibilityMode( type ) { //Reset the changeable sections of the Mnemonics array, and operand encoding array. @@ -3515,7 +3515,7 @@ The function "GetPosition()" Gives back the current base address in it's proper If the hex input is invalid returns false. -------------------------------------------------------------------------------------------------------------------------*/ -function LoadBinCode( HexStr ) +export function LoadBinCode( HexStr ) { //Clear BinCode, and Reset Code Position in Bin Code array. @@ -3605,7 +3605,7 @@ segment, and offset address. Note that the Code Segment is used in 16 bit code. if set 36, or higher. Effects instruction location in memory when decoding a program. -------------------------------------------------------------------------------------------------------------------------*/ -function SetBasePosition( Address ) +export function SetBasePosition( Address ) { //Split the Segment:offset. @@ -5652,7 +5652,7 @@ function Reset() do an linear disassemble. -------------------------------------------------------------------------------------------------------------------------*/ -function LDisassemble() +export function LDisassemble() { var Instruction = ""; //Stores the Decoded instruction. var Out = ""; //The Disassemble output @@ -5709,13 +5709,13 @@ function LDisassemble() * The following code has been added to expose public methods for use in CyberChef */ -export default { - LoadBinCode: LoadBinCode, - LDisassemble: LDisassemble, - SetBasePosition: SetBasePosition, - CompatibilityMode: CompatibilityMode, - - setBitMode: val => { BitMode = val; }, - setShowInstructionHex: val => { ShowInstructionHex = val; }, - setShowInstructionPos: val => { ShowInstructionPos = val; }, +export function setBitMode (val) { + BitMode = val; }; +export function setShowInstructionHex (val) { + ShowInstructionHex = val; +}; +export function setShowInstructionPos (val) { + ShowInstructionPos = val; +}; + diff --git a/src/core/vendor/bzip2.js b/src/core/vendor/bzip2.js index 03c8c97c..12dc3852 100755 --- a/src/core/vendor/bzip2.js +++ b/src/core/vendor/bzip2.js @@ -261,3 +261,5 @@ bzip2.decompress = function(bits, size, len){ } return output; } + +module.exports = bzip2; diff --git a/src/core/vendor/canvascomponents.js b/src/core/vendor/canvascomponents.js deleted file mode 100755 index f6ea0538..00000000 --- a/src/core/vendor/canvascomponents.js +++ /dev/null @@ -1,186 +0,0 @@ -"use strict"; - -/** - * Various components for drawing diagrams on an HTML5 canvas. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constant - * @namespace - */ -const CanvasComponents = { - - drawLine: function(ctx, startX, startY, endX, endY) { - ctx.beginPath(); - ctx.moveTo(startX, startY); - ctx.lineTo(endX, endY); - ctx.closePath(); - ctx.stroke(); - }, - - drawBarChart: function(canvas, scores, xAxisLabel, yAxisLabel, numXLabels, numYLabels, fontSize) { - fontSize = fontSize || 15; - if (!numXLabels || numXLabels > Math.round(canvas.width / 50)) { - numXLabels = Math.round(canvas.width / 50); - } - if (!numYLabels || numYLabels > Math.round(canvas.width / 50)) { - numYLabels = Math.round(canvas.height / 50); - } - - // Graph properties - var ctx = canvas.getContext("2d"), - leftPadding = canvas.width * 0.08, - rightPadding = canvas.width * 0.03, - topPadding = canvas.height * 0.08, - bottomPadding = canvas.height * 0.15, - graphHeight = canvas.height - topPadding - bottomPadding, - graphWidth = canvas.width - leftPadding - rightPadding, - base = topPadding + graphHeight, - ceil = topPadding; - - ctx.font = fontSize + "px Arial"; - - // Draw axis - ctx.lineWidth = "1.0"; - ctx.strokeStyle = "#444"; - CanvasComponents.drawLine(ctx, leftPadding, base, graphWidth + leftPadding, base); // x - CanvasComponents.drawLine(ctx, leftPadding, base, leftPadding, ceil); // y - - // Bar properties - var barPadding = graphWidth * 0.003, - barWidth = (graphWidth - (barPadding * scores.length)) / scores.length, - currX = leftPadding + barPadding, - max = Math.max.apply(Math, scores); - - // Draw bars - ctx.fillStyle = "green"; - for (var i = 0; i < scores.length; i++) { - var h = scores[i] / max * graphHeight; - ctx.fillRect(currX, base - h, barWidth, h); - currX += barWidth + barPadding; - } - - // Mark x axis - ctx.fillStyle = "black"; - ctx.textAlign = "center"; - currX = leftPadding + barPadding; - if (numXLabels >= scores.length) { - // Mark every score - for (i = 0; i <= scores.length; i++) { - ctx.fillText(i, currX, base + (bottomPadding * 0.3)); - currX += barWidth + barPadding; - } - } else { - // Mark some scores - for (i = 0; i <= numXLabels; i++) { - var val = Math.ceil((scores.length / numXLabels) * i); - currX = (graphWidth / numXLabels) * i + leftPadding; - ctx.fillText(val, currX, base + (bottomPadding * 0.3)); - } - } - - // Mark y axis - ctx.textAlign = "right"; - var currY; - if (numYLabels >= max) { - // Mark every increment - for (i = 0; i <= max; i++) { - currY = base - (i / max * graphHeight) + fontSize / 3; - ctx.fillText(i, leftPadding * 0.8, currY); - } - } else { - // Mark some increments - for (i = 0; i <= numYLabels; i++) { - val = Math.ceil((max / numYLabels) * i); - currY = base - (val / max * graphHeight) + fontSize / 3; - ctx.fillText(val, leftPadding * 0.8, currY); - } - } - - // Label x axis - if (xAxisLabel) { - ctx.textAlign = "center"; - ctx.fillText(xAxisLabel, graphWidth / 2 + leftPadding, base + bottomPadding * 0.8); - } - - // Label y axis - if (yAxisLabel) { - ctx.save(); - var x = leftPadding * 0.3, - y = graphHeight / 2 + topPadding; - ctx.translate(x, y); - ctx.rotate(-Math.PI / 2); - ctx.textAlign = "center"; - ctx.fillText(yAxisLabel, 0, 0); - ctx.restore(); - } - }, - - drawScaleBar: function(canvas, score, max, markings) { - // Bar properties - var ctx = canvas.getContext("2d"), - leftPadding = canvas.width * 0.01, - rightPadding = canvas.width * 0.01, - topPadding = canvas.height * 0.1, - bottomPadding = canvas.height * 0.3, - barHeight = canvas.height - topPadding - bottomPadding, - barWidth = canvas.width - leftPadding - rightPadding; - - // Scale properties - var proportion = score / max; - - // Draw bar outline - ctx.strokeRect(leftPadding, topPadding, barWidth, barHeight); - - // Shade in up to proportion - var grad = ctx.createLinearGradient(leftPadding, 0, barWidth + leftPadding, 0); - grad.addColorStop(0, "green"); - grad.addColorStop(0.5, "gold"); - grad.addColorStop(1, "red"); - ctx.fillStyle = grad; - ctx.fillRect(leftPadding, topPadding, barWidth * proportion, barHeight); - - // Add markings - var x0, y0, x1, y1; - ctx.fillStyle = "black"; - ctx.textAlign = "center"; - ctx.font = "13px Arial"; - for (var i = 0; i < markings.length; i++) { - // Draw min line down - x0 = barWidth / max * markings[i].min + leftPadding; - y0 = topPadding + barHeight + (bottomPadding * 0.1); - x1 = x0; - y1 = topPadding + barHeight + (bottomPadding * 0.3); - CanvasComponents.drawLine(ctx, x0, y0, x1, y1); - - // Draw max line down - x0 = barWidth / max * markings[i].max + leftPadding; - x1 = x0; - CanvasComponents.drawLine(ctx, x0, y0, x1, y1); - - // Join min and max lines - x0 = barWidth / max * markings[i].min + leftPadding; - y0 = topPadding + barHeight + (bottomPadding * 0.3); - x1 = barWidth / max * markings[i].max + leftPadding; - y1 = y0; - CanvasComponents.drawLine(ctx, x0, y0, x1, y1); - - // Add label - if (markings[i].max >= max * 0.9) { - ctx.textAlign = "right"; - x0 = x1; - } else if (markings[i].max <= max * 0.1) { - ctx.textAlign = "left"; - } else { - x0 = x0 + (x1 - x0) / 2; - } - y0 = topPadding + barHeight + (bottomPadding * 0.8); - ctx.fillText(markings[i].label, x0, y0); - } - }, - -}; - -export default CanvasComponents; diff --git a/src/web/App.js b/src/web/App.js old mode 100755 new mode 100644 index 29b858f2..c08658a7 --- a/src/web/App.js +++ b/src/web/App.js @@ -1,737 +1,753 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + import Utils from "../core/Utils"; import {fromBase64} from "../core/lib/Base64"; -import Manager from "./Manager.js"; -import HTMLCategory from "./HTMLCategory.js"; -import HTMLOperation from "./HTMLOperation.js"; +import Manager from "./Manager"; +import HTMLCategory from "./HTMLCategory"; +import HTMLOperation from "./HTMLOperation"; import Split from "split.js"; /** * HTML view for CyberChef responsible for building the web page and dealing with all user * interactions. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {CatConf[]} categories - The list of categories and operations to be populated. - * @param {Object.} operations - The list of operation configuration objects. - * @param {String[]} defaultFavourites - A list of default favourite operations. - * @param {Object} options - Default setting for app options. */ -const App = function(categories, operations, defaultFavourites, defaultOptions) { - this.categories = categories; - this.operations = operations; - this.dfavourites = defaultFavourites; - this.doptions = defaultOptions; - this.options = Object.assign({}, defaultOptions); +class App { - this.manager = new Manager(this); + /** + * App constructor. + * + * @param {CatConf[]} categories - The list of categories and operations to be populated. + * @param {Object.} operations - The list of operation configuration objects. + * @param {String[]} defaultFavourites - A list of default favourite operations. + * @param {Object} options - Default setting for app options. + */ + constructor(categories, operations, defaultFavourites, defaultOptions) { + this.categories = categories; + this.operations = operations; + this.dfavourites = defaultFavourites; + this.doptions = defaultOptions; + this.options = Object.assign({}, defaultOptions); - this.baking = false; - this.autoBake_ = false; - this.autoBakePause = false; - this.progress = 0; - this.ingId = 0; -}; + this.manager = new Manager(this); - -/** - * This function sets up the stage and creates listeners for all events. - * - * @fires Manager#appstart - */ -App.prototype.setup = function() { - document.dispatchEvent(this.manager.appstart); - this.initialiseSplitter(); - this.loadLocalStorage(); - this.populateOperationsList(); - this.manager.setup(); - this.resetLayout(); - this.setCompileMessage(); - - log.debug("App loaded"); - this.appLoaded = true; - - this.loadURIParams(); - this.loaded(); -}; - - -/** - * Fires once all setup activities have completed. - * - * @fires Manager#apploaded - */ -App.prototype.loaded = function() { - // Check that both the app and the worker have loaded successfully, and that - // we haven't already loaded before attempting to remove the loading screen. - if (!this.workerLoaded || !this.appLoaded || - !document.getElementById("loader-wrapper")) return; - - // Trigger CSS animations to remove preloader - document.body.classList.add("loaded"); - - // Wait for animations to complete then remove the preloader and loaded style - // so that the animations for existing elements don't play again. - setTimeout(function() { - document.getElementById("loader-wrapper").remove(); - document.body.classList.remove("loaded"); - }, 1000); - - // Clear the loading message interval - clearInterval(window.loadingMsgsInt); - - document.dispatchEvent(this.manager.apploaded); -}; - - -/** - * An error handler for displaying the error to the user. - * - * @param {Error} err - * @param {boolean} [logToConsole=false] - */ -App.prototype.handleError = function(err, logToConsole) { - if (logToConsole) log.error(err); - const msg = err.displayStr || err.toString(); - this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); -}; - - -/** - * Asks the ChefWorker to bake the current input using the current recipe. - * - * @param {boolean} [step] - Set to true if we should only execute one operation instead of the - * whole recipe. - */ -App.prototype.bake = function(step) { - if (this.baking) return; - - // Reset attemptHighlight flag - this.options.attemptHighlight = true; - - this.manager.worker.bake( - this.getInput(), // The user's input - this.getRecipeConfig(), // The configuration of the recipe - this.options, // Options set by the user - this.progress, // The current position in the recipe - step // Whether or not to take one step or execute the whole recipe - ); -}; - - -/** - * Runs Auto Bake if it is set. - */ -App.prototype.autoBake = function() { - // If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no - // need to set the staleness indicator. Just exit and wait until auto bake is called after loading - // has completed. - if (this.autoBakePause) return false; - - if (this.autoBake_ && !this.baking) { - log.debug("Auto-baking"); - this.bake(); - } else { - this.manager.controls.showStaleIndicator(); - } -}; - - -/** - * Runs a silent bake, forcing the browser to load and cache all the relevant JavaScript code needed - * to do a real bake. - * - * The output will not be modified (hence "silent" bake). This will only actually execute the recipe - * if auto-bake is enabled, otherwise it will just wake up the ChefWorker with an empty recipe. - */ -App.prototype.silentBake = function() { - let recipeConfig = []; - - if (this.autoBake_) { - // If auto-bake is not enabled we don't want to actually run the recipe as it may be disabled - // for a good reason. - recipeConfig = this.getRecipeConfig(); + this.baking = false; + this.autoBake_ = false; + this.autoBakePause = false; + this.progress = 0; + this.ingId = 0; } - this.manager.worker.silentBake(recipeConfig); -}; + /** + * This function sets up the stage and creates listeners for all events. + * + * @fires Manager#appstart + */ + setup() { + document.dispatchEvent(this.manager.appstart); + this.initialiseSplitter(); + this.loadLocalStorage(); + this.populateOperationsList(); + this.manager.setup(); + this.resetLayout(); + this.setCompileMessage(); -/** - * Gets the user's input data. - * - * @returns {string} - */ -App.prototype.getInput = function() { - return this.manager.input.get(); -}; + log.debug("App loaded"); + this.appLoaded = true; - -/** - * Sets the user's input data. - * - * @param {string} input - The string to set the input to - */ -App.prototype.setInput = function(input) { - this.manager.input.set(input); -}; - - -/** - * Populates the operations accordion list with the categories and operations specified in the - * view constructor. - * - * @fires Manager#oplistcreate - */ -App.prototype.populateOperationsList = function() { - // Move edit button away before we overwrite it - document.body.appendChild(document.getElementById("edit-favourites")); - - let html = ""; - let i; - - for (i = 0; i < this.categories.length; i++) { - const catConf = this.categories[i], - selected = i === 0, - cat = new HTMLCategory(catConf.name, selected); - - for (let j = 0; j < catConf.ops.length; j++) { - const opName = catConf.ops[j], - op = new HTMLOperation(opName, this.operations[opName], this, this.manager); - cat.addOperation(op); - } - - html += cat.toHtml(); + this.loadURIParams(); + this.loaded(); } - document.getElementById("categories").innerHTML = html; - const opLists = document.querySelectorAll("#categories .op-list"); + /** + * Fires once all setup activities have completed. + * + * @fires Manager#apploaded + */ + loaded() { + // Check that both the app and the worker have loaded successfully, and that + // we haven't already loaded before attempting to remove the loading screen. + if (!this.workerLoaded || !this.appLoaded || + !document.getElementById("loader-wrapper")) return; - for (i = 0; i < opLists.length; i++) { - opLists[i].dispatchEvent(this.manager.oplistcreate); + // Trigger CSS animations to remove preloader + document.body.classList.add("loaded"); + + // Wait for animations to complete then remove the preloader and loaded style + // so that the animations for existing elements don't play again. + setTimeout(function() { + document.getElementById("loader-wrapper").remove(); + document.body.classList.remove("loaded"); + }, 1000); + + // Clear the loading message interval + clearInterval(window.loadingMsgsInt); + + // Remove the loading error handler + window.removeEventListener("error", window.loadingErrorHandler); + + document.dispatchEvent(this.manager.apploaded); } - // Add edit button to first category (Favourites) - document.querySelector("#categories a").appendChild(document.getElementById("edit-favourites")); -}; - -/** - * Sets up the adjustable splitter to allow the user to resize areas of the page. - */ -App.prototype.initialiseSplitter = function() { - this.columnSplitter = Split(["#operations", "#recipe", "#IO"], { - sizes: [20, 30, 50], - minSize: [240, 325, 450], - gutterSize: 4, - onDrag: function() { - this.manager.controls.adjustWidth(); - this.manager.output.adjustWidth(); - }.bind(this) - }); - - this.ioSplitter = Split(["#input", "#output"], { - direction: "vertical", - gutterSize: 4, - }); - - this.resetLayout(); -}; - - -/** - * Loads the information previously saved to the HTML5 local storage object so that user options - * and favourites can be restored. - */ -App.prototype.loadLocalStorage = function() { - // Load options - let lOptions; - if (this.isLocalStorageAvailable() && localStorage.options !== undefined) { - lOptions = JSON.parse(localStorage.options); - } - this.manager.options.load(lOptions); - - // Load favourites - this.loadFavourites(); -}; - - -/** - * Loads the user's favourite operations from the HTML5 local storage object and populates the - * Favourites category with them. - * If the user currently has no saved favourites, the defaults from the view constructor are used. - */ -App.prototype.loadFavourites = function() { - let favourites; - - if (this.isLocalStorageAvailable()) { - favourites = localStorage.favourites && localStorage.favourites.length > 2 ? - JSON.parse(localStorage.favourites) : - this.dfavourites; - favourites = this.validFavourites(favourites); - this.saveFavourites(favourites); - } else { - favourites = this.dfavourites; + /** + * An error handler for displaying the error to the user. + * + * @param {Error} err + * @param {boolean} [logToConsole=false] + */ + handleError(err, logToConsole) { + if (logToConsole) log.error(err); + const msg = err.displayStr || err.toString(); + this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); } - const favCat = this.categories.filter(function(c) { - return c.name === "Favourites"; - })[0]; - if (favCat) { - favCat.ops = favourites; - } else { - this.categories.unshift({ - name: "Favourites", - ops: favourites - }); - } -}; + /** + * Asks the ChefWorker to bake the current input using the current recipe. + * + * @param {boolean} [step] - Set to true if we should only execute one operation instead of the + * whole recipe. + */ + bake(step) { + if (this.baking) return; + // Reset attemptHighlight flag + this.options.attemptHighlight = true; -/** - * Filters the list of favourite operations that the user had stored and removes any that are no - * longer available. The user is notified if this is the case. - - * @param {string[]} favourites - A list of the user's favourite operations - * @returns {string[]} A list of the valid favourites - */ -App.prototype.validFavourites = function(favourites) { - const validFavs = []; - for (let i = 0; i < favourites.length; i++) { - if (this.operations.hasOwnProperty(favourites[i])) { - validFavs.push(favourites[i]); - } else { - this.alert("The operation \"" + Utils.escapeHtml(favourites[i]) + - "\" is no longer available. It has been removed from your favourites.", "info"); - } - } - return validFavs; -}; - - -/** - * Saves a list of favourite operations to the HTML5 local storage object. - * - * @param {string[]} favourites - A list of the user's favourite operations - */ -App.prototype.saveFavourites = function(favourites) { - if (!this.isLocalStorageAvailable()) { - this.alert( - "Your security settings do not allow access to local storage so your favourites cannot be saved.", - "danger", - 5000 + this.manager.worker.bake( + this.getInput(), // The user's input + this.getRecipeConfig(), // The configuration of the recipe + this.options, // Options set by the user + this.progress, // The current position in the recipe + step // Whether or not to take one step or execute the whole recipe ); - return false; } - localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites))); -}; + /** + * Runs Auto Bake if it is set. + */ + autoBake() { + // If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no + // need to set the staleness indicator. Just exit and wait until auto bake is called after loading + // has completed. + if (this.autoBakePause) return false; -/** - * Resets favourite operations back to the default as specified in the view constructor and - * refreshes the operation list. - */ -App.prototype.resetFavourites = function() { - this.saveFavourites(this.dfavourites); - this.loadFavourites(); - this.populateOperationsList(); - this.manager.recipe.initialiseOperationDragNDrop(); -}; - - -/** - * Adds an operation to the user's favourites. - * - * @param {string} name - The name of the operation - */ -App.prototype.addFavourite = function(name) { - const favourites = JSON.parse(localStorage.favourites); - - if (favourites.indexOf(name) >= 0) { - this.alert("'" + name + "' is already in your favourites", "info", 2000); - return; + if (this.autoBake_ && !this.baking) { + log.debug("Auto-baking"); + this.bake(); + } else { + this.manager.controls.showStaleIndicator(); + } } - favourites.push(name); - this.saveFavourites(favourites); - this.loadFavourites(); - this.populateOperationsList(); - this.manager.recipe.initialiseOperationDragNDrop(); -}; + /** + * Runs a silent bake, forcing the browser to load and cache all the relevant JavaScript code needed + * to do a real bake. + * + * The output will not be modified (hence "silent" bake). This will only actually execute the recipe + * if auto-bake is enabled, otherwise it will just wake up the ChefWorker with an empty recipe. + */ + silentBake() { + let recipeConfig = []; -/** - * Checks for input and recipe in the URI parameters and loads them if present. - */ -App.prototype.loadURIParams = function() { - // Load query string or hash from URI (depending on which is populated) - // We prefer getting the hash by splitting the href rather than referencing - // location.hash as some browsers (Firefox) automatically URL decode it, - // which cause issues. - const params = window.location.search || - window.location.href.split("#")[1] || - window.location.hash; - this.uriParams = Utils.parseURIParams(params); - this.autoBakePause = true; - - // Read in recipe from URI params - if (this.uriParams.recipe) { - try { - const recipeConfig = Utils.parseRecipeConfig(this.uriParams.recipe); - this.setRecipeConfig(recipeConfig); - } catch (err) {} - } else if (this.uriParams.op) { - // If there's no recipe, look for single operations - this.manager.recipe.clearRecipe(); - - // Search for nearest match and add it - const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false); - if (matchedOps.length) { - this.manager.recipe.addOperation(matchedOps[0].name); + if (this.autoBake_) { + // If auto-bake is not enabled we don't want to actually run the recipe as it may be disabled + // for a good reason. + recipeConfig = this.getRecipeConfig(); } - // Populate search with the string - const search = document.getElementById("search"); - - search.value = this.uriParams.op; - search.dispatchEvent(new Event("search")); + this.manager.worker.silentBake(recipeConfig); } - // Read in input data from URI params - if (this.uriParams.input) { - try { - const inputData = fromBase64(this.uriParams.input); - this.setInput(inputData); - } catch (err) {} + + /** + * Gets the user's input data. + * + * @returns {string} + */ + getInput() { + return this.manager.input.get(); } - this.autoBakePause = false; - this.autoBake(); -}; + + /** + * Sets the user's input data. + * + * @param {string} input - The string to set the input to + */ + setInput(input) { + this.manager.input.set(input); + } -/** - * Returns the next ingredient ID and increments it for next time. - * - * @returns {number} - */ -App.prototype.nextIngId = function() { - return this.ingId++; -}; + /** + * Populates the operations accordion list with the categories and operations specified in the + * view constructor. + * + * @fires Manager#oplistcreate + */ + populateOperationsList() { + // Move edit button away before we overwrite it + document.body.appendChild(document.getElementById("edit-favourites")); + + let html = ""; + let i; + + for (i = 0; i < this.categories.length; i++) { + const catConf = this.categories[i], + selected = i === 0, + cat = new HTMLCategory(catConf.name, selected); + + for (let j = 0; j < catConf.ops.length; j++) { + const opName = catConf.ops[j]; + if (!this.operations.hasOwnProperty(opName)) { + log.warn(`${opName} could not be found.`); + continue; + } + + const op = new HTMLOperation(opName, this.operations[opName], this, this.manager); + cat.addOperation(op); + } + + html += cat.toHtml(); + } + + document.getElementById("categories").innerHTML = html; + + const opLists = document.querySelectorAll("#categories .op-list"); + + for (i = 0; i < opLists.length; i++) { + opLists[i].dispatchEvent(this.manager.oplistcreate); + } + + // Add edit button to first category (Favourites) + document.querySelector("#categories a").appendChild(document.getElementById("edit-favourites")); + } -/** - * Gets the current recipe configuration. - * - * @returns {Object[]} - */ -App.prototype.getRecipeConfig = function() { - return this.manager.recipe.getConfig(); -}; + /** + * Sets up the adjustable splitter to allow the user to resize areas of the page. + */ + initialiseSplitter() { + this.columnSplitter = Split(["#operations", "#recipe", "#IO"], { + sizes: [20, 30, 50], + minSize: [240, 325, 450], + gutterSize: 4, + onDrag: function() { + this.manager.controls.adjustWidth(); + this.manager.output.adjustWidth(); + }.bind(this) + }); + + this.ioSplitter = Split(["#input", "#output"], { + direction: "vertical", + gutterSize: 4, + }); + + this.resetLayout(); + } -/** - * Given a recipe configuration, sets the recipe to that configuration. - * - * @fires Manager#statechange - * @param {Object[]} recipeConfig - The recipe configuration - */ -App.prototype.setRecipeConfig = function(recipeConfig) { - document.getElementById("rec-list").innerHTML = null; + /** + * Loads the information previously saved to the HTML5 local storage object so that user options + * and favourites can be restored. + */ + loadLocalStorage() { + // Load options + let lOptions; + if (this.isLocalStorageAvailable() && localStorage.options !== undefined) { + lOptions = JSON.parse(localStorage.options); + } + this.manager.options.load(lOptions); - // Pause auto-bake while loading but don't modify `this.autoBake_` - // otherwise `manualBake` cannot trigger. - this.autoBakePause = true; + // Load favourites + this.loadFavourites(); + } - for (let i = 0; i < recipeConfig.length; i++) { - const item = this.manager.recipe.addOperation(recipeConfig[i].op); - // Populate arguments - const args = item.querySelectorAll(".arg"); - for (let j = 0; j < args.length; j++) { - if (recipeConfig[i].args[j] === undefined) continue; - if (args[j].getAttribute("type") === "checkbox") { - // checkbox - args[j].checked = recipeConfig[i].args[j]; - } else if (args[j].classList.contains("toggle-string")) { - // toggleString - args[j].value = recipeConfig[i].args[j].string; - args[j].previousSibling.children[0].innerHTML = - Utils.escapeHtml(recipeConfig[i].args[j].option) + - " "; + /** + * Loads the user's favourite operations from the HTML5 local storage object and populates the + * Favourites category with them. + * If the user currently has no saved favourites, the defaults from the view constructor are used. + */ + loadFavourites() { + let favourites; + + if (this.isLocalStorageAvailable()) { + favourites = localStorage.favourites && localStorage.favourites.length > 2 ? + JSON.parse(localStorage.favourites) : + this.dfavourites; + favourites = this.validFavourites(favourites); + this.saveFavourites(favourites); + } else { + favourites = this.dfavourites; + } + + const favCat = this.categories.filter(function(c) { + return c.name === "Favourites"; + })[0]; + + if (favCat) { + favCat.ops = favourites; + } else { + this.categories.unshift({ + name: "Favourites", + ops: favourites + }); + } + } + + + /** + * Filters the list of favourite operations that the user had stored and removes any that are no + * longer available. The user is notified if this is the case. + + * @param {string[]} favourites - A list of the user's favourite operations + * @returns {string[]} A list of the valid favourites + */ + validFavourites(favourites) { + const validFavs = []; + for (let i = 0; i < favourites.length; i++) { + if (this.operations.hasOwnProperty(favourites[i])) { + validFavs.push(favourites[i]); } else { - // all others - args[j].value = recipeConfig[i].args[j]; + this.alert("The operation \"" + Utils.escapeHtml(favourites[i]) + + "\" is no longer available. It has been removed from your favourites.", "info"); } } + return validFavs; + } - // Set disabled and breakpoint - if (recipeConfig[i].disabled) { - item.querySelector(".disable-icon").click(); - } - if (recipeConfig[i].breakpoint) { - item.querySelector(".breakpoint").click(); + + /** + * Saves a list of favourite operations to the HTML5 local storage object. + * + * @param {string[]} favourites - A list of the user's favourite operations + */ + saveFavourites(favourites) { + if (!this.isLocalStorageAvailable()) { + this.alert( + "Your security settings do not allow access to local storage so your favourites cannot be saved.", + "danger", + 5000 + ); + return false; } - this.progress = 0; + localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites))); } - // Unpause auto bake - this.autoBakePause = false; -}; - -/** - * Resets the splitter positions to default. - */ -App.prototype.resetLayout = function() { - this.columnSplitter.setSizes([20, 30, 50]); - this.ioSplitter.setSizes([50, 50]); - - this.manager.controls.adjustWidth(); - this.manager.output.adjustWidth(); -}; - - -/** - * Sets the compile message. - */ -App.prototype.setCompileMessage = function() { - // Display time since last build and compile message - const now = new Date(), - timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime); - - // Calculate previous version to compare to - const prev = PKG_VERSION.split(".").map(n => { - return parseInt(n, 10); - }); - if (prev[2] > 0) prev[2]--; - else if (prev[1] > 0) prev[1]--; - else prev[0]--; - - const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`; - - let compileInfo = `Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago`; - - if (window.compileMessage !== "") { - compileInfo += " - " + window.compileMessage; + /** + * Resets favourite operations back to the default as specified in the view constructor and + * refreshes the operation list. + */ + resetFavourites() { + this.saveFavourites(this.dfavourites); + this.loadFavourites(); + this.populateOperationsList(); + this.manager.recipe.initialiseOperationDragNDrop(); } - document.getElementById("notice").innerHTML = compileInfo; -}; + /** + * Adds an operation to the user's favourites. + * + * @param {string} name - The name of the operation + */ + addFavourite(name) { + const favourites = JSON.parse(localStorage.favourites); -/** - * Determines whether the browser supports Local Storage and if it is accessible. - * - * @returns {boolean} - */ -App.prototype.isLocalStorageAvailable = function() { - try { - if (!localStorage) return false; - return true; - } catch (err) { - // Access to LocalStorage is denied - return false; - } -}; + if (favourites.indexOf(name) >= 0) { + this.alert("'" + name + "' is already in your favourites", "info", 2000); + return; + } - -/** - * Pops up a message to the user and writes it to the console log. - * - * @param {string} str - The message to display (HTML supported) - * @param {string} style - The colour of the popup - * "danger" = red - * "warning" = amber - * "info" = blue - * "success" = green - * @param {number} timeout - The number of milliseconds before the popup closes automatically - * 0 for never (until the user closes it) - * @param {boolean} [silent=false] - Don't show the message in the popup, only print it to the - * console - * - * @example - * // Pops up a red box with the message "[current time] Error: Something has gone wrong!" - * // that will need to be dismissed by the user. - * this.alert("Error: Something has gone wrong!", "danger", 0); - * - * // Pops up a blue information box with the message "[current time] Happy Christmas!" - * // that will disappear after 5 seconds. - * this.alert("Happy Christmas!", "info", 5000); - */ -App.prototype.alert = function(str, style, timeout, silent) { - const time = new Date(); - - log.info("[" + time.toLocaleString() + "] " + str); - if (silent) return; - - style = style || "danger"; - timeout = timeout || 0; - - const alertEl = document.getElementById("alert"), - alertContent = document.getElementById("alert-content"); - - alertEl.classList.remove("alert-danger"); - alertEl.classList.remove("alert-warning"); - alertEl.classList.remove("alert-info"); - alertEl.classList.remove("alert-success"); - alertEl.classList.add("alert-" + style); - - // If the box hasn't been closed, append to it rather than replacing - if (alertEl.style.display === "block") { - alertContent.innerHTML += - "

[" + time.toLocaleTimeString() + "] " + str; - } else { - alertContent.innerHTML = - "[" + time.toLocaleTimeString() + "] " + str; + favourites.push(name); + this.saveFavourites(favourites); + this.loadFavourites(); + this.populateOperationsList(); + this.manager.recipe.initialiseOperationDragNDrop(); } - // Stop the animation if it is in progress - $("#alert").stop(); - alertEl.style.display = "block"; - alertEl.style.opacity = 1; - if (timeout > 0) { - clearTimeout(this.alertTimeout); - this.alertTimeout = setTimeout(function(){ - $("#alert").slideUp(100); - }, timeout); + /** + * Checks for input and recipe in the URI parameters and loads them if present. + */ + loadURIParams() { + // Load query string or hash from URI (depending on which is populated) + // We prefer getting the hash by splitting the href rather than referencing + // location.hash as some browsers (Firefox) automatically URL decode it, + // which cause issues. + const params = window.location.search || + window.location.href.split("#")[1] || + window.location.hash; + this.uriParams = Utils.parseURIParams(params); + this.autoBakePause = true; + + // Read in recipe from URI params + if (this.uriParams.recipe) { + try { + const recipeConfig = Utils.parseRecipeConfig(this.uriParams.recipe); + this.setRecipeConfig(recipeConfig); + } catch (err) {} + } else if (this.uriParams.op) { + // If there's no recipe, look for single operations + this.manager.recipe.clearRecipe(); + + // Search for nearest match and add it + const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false); + if (matchedOps.length) { + this.manager.recipe.addOperation(matchedOps[0].name); + } + + // Populate search with the string + const search = document.getElementById("search"); + + search.value = this.uriParams.op; + search.dispatchEvent(new Event("search")); + } + + // Read in input data from URI params + if (this.uriParams.input) { + try { + const inputData = fromBase64(this.uriParams.input); + this.setInput(inputData); + } catch (err) {} + } + + this.autoBakePause = false; + this.autoBake(); } -}; -/** - * Pops up a box asking the user a question and sending the answer to a specified callback function. - * - * @param {string} title - The title of the box - * @param {string} body - The question (HTML supported) - * @param {function} callback - A function accepting one boolean argument which handles the - * response e.g. function(answer) {...} - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. - * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); - */ -App.prototype.confirm = function(title, body, callback, scope) { - scope = scope || this; - document.getElementById("confirm-title").innerHTML = title; - document.getElementById("confirm-body").innerHTML = body; - document.getElementById("confirm-modal").style.display = "block"; - - this.confirmClosed = false; - $("#confirm-modal").modal() - .one("show.bs.modal", function(e) { - this.confirmClosed = false; - }.bind(this)) - .one("click", "#confirm-yes", function() { - this.confirmClosed = true; - callback.bind(scope)(true); - $("#confirm-modal").modal("hide"); - }.bind(this)) - .one("hide.bs.modal", function(e) { - if (!this.confirmClosed) - callback.bind(scope)(false); - this.confirmClosed = true; - }.bind(this)); -}; + /** + * Returns the next ingredient ID and increments it for next time. + * + * @returns {number} + */ + nextIngId() { + return this.ingId++; + } -/** - * Handler for the alert close button click event. - * Closes the alert box. - */ -App.prototype.alertCloseClick = function() { - document.getElementById("alert").style.display = "none"; -}; + /** + * Gets the current recipe configuration. + * + * @returns {Object[]} + */ + getRecipeConfig() { + return this.manager.recipe.getConfig(); + } -/** - * Handler for CyerChef statechange events. - * Fires whenever the input or recipe changes in any way. - * - * @listens Manager#statechange - * @param {event} e - */ -App.prototype.stateChange = function(e) { - this.autoBake(); + /** + * Given a recipe configuration, sets the recipe to that configuration. + * + * @fires Manager#statechange + * @param {Object[]} recipeConfig - The recipe configuration + */ + setRecipeConfig(recipeConfig) { + document.getElementById("rec-list").innerHTML = null; - // Set title - const recipeConfig = this.getRecipeConfig(); - let title = "CyberChef"; - if (recipeConfig.length === 1) { - title = `${recipeConfig[0].op} - ${title}`; - } else if (recipeConfig.length > 1) { - // See how long the full recipe is - const ops = recipeConfig.map(op => op.op).join(", "); - if (ops.length < 45) { - title = `${ops} - ${title}`; + // Pause auto-bake while loading but don't modify `this.autoBake_` + // otherwise `manualBake` cannot trigger. + this.autoBakePause = true; + + for (let i = 0; i < recipeConfig.length; i++) { + const item = this.manager.recipe.addOperation(recipeConfig[i].op); + + // Populate arguments + const args = item.querySelectorAll(".arg"); + for (let j = 0; j < args.length; j++) { + if (recipeConfig[i].args[j] === undefined) continue; + if (args[j].getAttribute("type") === "checkbox") { + // checkbox + args[j].checked = recipeConfig[i].args[j]; + } else if (args[j].classList.contains("toggle-string")) { + // toggleString + args[j].value = recipeConfig[i].args[j].string; + args[j].previousSibling.children[0].innerHTML = + Utils.escapeHtml(recipeConfig[i].args[j].option) + + " "; + } else { + // all others + args[j].value = recipeConfig[i].args[j]; + } + } + + // Set disabled and breakpoint + if (recipeConfig[i].disabled) { + item.querySelector(".disable-icon").click(); + } + if (recipeConfig[i].breakpoint) { + item.querySelector(".breakpoint").click(); + } + + this.progress = 0; + } + + // Unpause auto bake + this.autoBakePause = false; + } + + + /** + * Resets the splitter positions to default. + */ + resetLayout() { + this.columnSplitter.setSizes([20, 30, 50]); + this.ioSplitter.setSizes([50, 50]); + + this.manager.controls.adjustWidth(); + this.manager.output.adjustWidth(); + } + + + /** + * Sets the compile message. + */ + setCompileMessage() { + // Display time since last build and compile message + const now = new Date(), + timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime); + + // Calculate previous version to compare to + const prev = PKG_VERSION.split(".").map(n => { + return parseInt(n, 10); + }); + if (prev[2] > 0) prev[2]--; + else if (prev[1] > 0) prev[1]--; + else prev[0]--; + + const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`; + + let compileInfo = `Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago`; + + if (window.compileMessage !== "") { + compileInfo += " - " + window.compileMessage; + } + + document.getElementById("notice").innerHTML = compileInfo; + } + + + /** + * Determines whether the browser supports Local Storage and if it is accessible. + * + * @returns {boolean} + */ + isLocalStorageAvailable() { + try { + if (!localStorage) return false; + return true; + } catch (err) { + // Access to LocalStorage is denied + return false; + } + } + + + /** + * Pops up a message to the user and writes it to the console log. + * + * @param {string} str - The message to display (HTML supported) + * @param {string} style - The colour of the popup + * "danger" = red + * "warning" = amber + * "info" = blue + * "success" = green + * @param {number} timeout - The number of milliseconds before the popup closes automatically + * 0 for never (until the user closes it) + * @param {boolean} [silent=false] - Don't show the message in the popup, only print it to the + * console + * + * @example + * // Pops up a red box with the message "[current time] Error: Something has gone wrong!" + * // that will need to be dismissed by the user. + * this.alert("Error: Something has gone wrong!", "danger", 0); + * + * // Pops up a blue information box with the message "[current time] Happy Christmas!" + * // that will disappear after 5 seconds. + * this.alert("Happy Christmas!", "info", 5000); + */ + alert(str, style, timeout, silent) { + const time = new Date(); + + log.info("[" + time.toLocaleString() + "] " + str); + if (silent) return; + + style = style || "danger"; + timeout = timeout || 0; + + const alertEl = document.getElementById("alert"), + alertContent = document.getElementById("alert-content"); + + alertEl.classList.remove("alert-danger"); + alertEl.classList.remove("alert-warning"); + alertEl.classList.remove("alert-info"); + alertEl.classList.remove("alert-success"); + alertEl.classList.add("alert-" + style); + + // If the box hasn't been closed, append to it rather than replacing + if (alertEl.style.display === "block") { + alertContent.innerHTML += + "

[" + time.toLocaleTimeString() + "] " + str; } else { - // If it's too long, just use the first one and say how many more there are - title = `${recipeConfig[0].op}, ${recipeConfig.length - 1} more - ${title}`; + alertContent.innerHTML = + "[" + time.toLocaleTimeString() + "] " + str; + } + + // Stop the animation if it is in progress + $("#alert").stop(); + alertEl.style.display = "block"; + alertEl.style.opacity = 1; + + if (timeout > 0) { + clearTimeout(this.alertTimeout); + this.alertTimeout = setTimeout(function(){ + $("#alert").slideUp(100); + }, timeout); } } - document.title = title; - // Update the current history state (not creating a new one) - if (this.options.updateUrl) { - this.lastStateUrl = this.manager.controls.generateStateUrl(true, true, recipeConfig); - window.history.replaceState({}, title, this.lastStateUrl); + + /** + * Pops up a box asking the user a question and sending the answer to a specified callback function. + * + * @param {string} title - The title of the box + * @param {string} body - The question (HTML supported) + * @param {function} callback - A function accepting one boolean argument which handles the + * response e.g. function(answer) {...} + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. + * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); + */ + confirm(title, body, callback, scope) { + scope = scope || this; + document.getElementById("confirm-title").innerHTML = title; + document.getElementById("confirm-body").innerHTML = body; + document.getElementById("confirm-modal").style.display = "block"; + + this.confirmClosed = false; + $("#confirm-modal").modal() + .one("show.bs.modal", function(e) { + this.confirmClosed = false; + }.bind(this)) + .one("click", "#confirm-yes", function() { + this.confirmClosed = true; + callback.bind(scope)(true); + $("#confirm-modal").modal("hide"); + }.bind(this)) + .one("hide.bs.modal", function(e) { + if (!this.confirmClosed) + callback.bind(scope)(false); + this.confirmClosed = true; + }.bind(this)); } -}; -/** - * Handler for the history popstate event. - * Reloads parameters from the URL. - * - * @param {event} e - */ -App.prototype.popState = function(e) { - this.loadURIParams(); -}; + /** + * Handler for the alert close button click event. + * Closes the alert box. + */ + alertCloseClick() { + document.getElementById("alert").style.display = "none"; + } -/** - * Function to call an external API from this view. - */ -App.prototype.callApi = function(url, type, data, dataType, contentType) { - type = type || "POST"; - data = data || {}; - dataType = dataType || undefined; - contentType = contentType || "application/json"; + /** + * Handler for CyerChef statechange events. + * Fires whenever the input or recipe changes in any way. + * + * @listens Manager#statechange + * @param {event} e + */ + stateChange(e) { + this.autoBake(); - let response = null, - success = false; + // Set title + const recipeConfig = this.getRecipeConfig(); + let title = "CyberChef"; + if (recipeConfig.length === 1) { + title = `${recipeConfig[0].op} - ${title}`; + } else if (recipeConfig.length > 1) { + // See how long the full recipe is + const ops = recipeConfig.map(op => op.op).join(", "); + if (ops.length < 45) { + title = `${ops} - ${title}`; + } else { + // If it's too long, just use the first one and say how many more there are + title = `${recipeConfig[0].op}, ${recipeConfig.length - 1} more - ${title}`; + } + } + document.title = title; - $.ajax({ - url: url, - async: false, - type: type, - data: data, - dataType: dataType, - contentType: contentType, - success: function(data) { - success = true; - response = data; - }, - error: function(data) { + // Update the current history state (not creating a new one) + if (this.options.updateUrl) { + this.lastStateUrl = this.manager.controls.generateStateUrl(true, true, recipeConfig); + window.history.replaceState({}, title, this.lastStateUrl); + } + } + + + /** + * Handler for the history popstate event. + * Reloads parameters from the URL. + * + * @param {event} e + */ + popState(e) { + this.loadURIParams(); + } + + + /** + * Function to call an external API from this view. + */ + callApi(url, type, data, dataType, contentType) { + type = type || "POST"; + data = data || {}; + dataType = dataType || undefined; + contentType = contentType || "application/json"; + + let response = null, success = false; - response = data; - }, - }); - return { - success: success, - response: response - }; -}; + $.ajax({ + url: url, + async: false, + type: type, + data: data, + dataType: dataType, + contentType: contentType, + success: function(data) { + success = true; + response = data; + }, + error: function(data) { + success = false; + response = data; + }, + }); + + return { + success: success, + response: response + }; + } + +} export default App; diff --git a/src/web/App.mjs b/src/web/App.mjs new file mode 100755 index 00000000..c08658a7 --- /dev/null +++ b/src/web/App.mjs @@ -0,0 +1,753 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Utils from "../core/Utils"; +import {fromBase64} from "../core/lib/Base64"; +import Manager from "./Manager"; +import HTMLCategory from "./HTMLCategory"; +import HTMLOperation from "./HTMLOperation"; +import Split from "split.js"; + + +/** + * HTML view for CyberChef responsible for building the web page and dealing with all user + * interactions. + */ +class App { + + /** + * App constructor. + * + * @param {CatConf[]} categories - The list of categories and operations to be populated. + * @param {Object.} operations - The list of operation configuration objects. + * @param {String[]} defaultFavourites - A list of default favourite operations. + * @param {Object} options - Default setting for app options. + */ + constructor(categories, operations, defaultFavourites, defaultOptions) { + this.categories = categories; + this.operations = operations; + this.dfavourites = defaultFavourites; + this.doptions = defaultOptions; + this.options = Object.assign({}, defaultOptions); + + this.manager = new Manager(this); + + this.baking = false; + this.autoBake_ = false; + this.autoBakePause = false; + this.progress = 0; + this.ingId = 0; + } + + + /** + * This function sets up the stage and creates listeners for all events. + * + * @fires Manager#appstart + */ + setup() { + document.dispatchEvent(this.manager.appstart); + this.initialiseSplitter(); + this.loadLocalStorage(); + this.populateOperationsList(); + this.manager.setup(); + this.resetLayout(); + this.setCompileMessage(); + + log.debug("App loaded"); + this.appLoaded = true; + + this.loadURIParams(); + this.loaded(); + } + + + /** + * Fires once all setup activities have completed. + * + * @fires Manager#apploaded + */ + loaded() { + // Check that both the app and the worker have loaded successfully, and that + // we haven't already loaded before attempting to remove the loading screen. + if (!this.workerLoaded || !this.appLoaded || + !document.getElementById("loader-wrapper")) return; + + // Trigger CSS animations to remove preloader + document.body.classList.add("loaded"); + + // Wait for animations to complete then remove the preloader and loaded style + // so that the animations for existing elements don't play again. + setTimeout(function() { + document.getElementById("loader-wrapper").remove(); + document.body.classList.remove("loaded"); + }, 1000); + + // Clear the loading message interval + clearInterval(window.loadingMsgsInt); + + // Remove the loading error handler + window.removeEventListener("error", window.loadingErrorHandler); + + document.dispatchEvent(this.manager.apploaded); + } + + + /** + * An error handler for displaying the error to the user. + * + * @param {Error} err + * @param {boolean} [logToConsole=false] + */ + handleError(err, logToConsole) { + if (logToConsole) log.error(err); + const msg = err.displayStr || err.toString(); + this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); + } + + + /** + * Asks the ChefWorker to bake the current input using the current recipe. + * + * @param {boolean} [step] - Set to true if we should only execute one operation instead of the + * whole recipe. + */ + bake(step) { + if (this.baking) return; + + // Reset attemptHighlight flag + this.options.attemptHighlight = true; + + this.manager.worker.bake( + this.getInput(), // The user's input + this.getRecipeConfig(), // The configuration of the recipe + this.options, // Options set by the user + this.progress, // The current position in the recipe + step // Whether or not to take one step or execute the whole recipe + ); + } + + + /** + * Runs Auto Bake if it is set. + */ + autoBake() { + // If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no + // need to set the staleness indicator. Just exit and wait until auto bake is called after loading + // has completed. + if (this.autoBakePause) return false; + + if (this.autoBake_ && !this.baking) { + log.debug("Auto-baking"); + this.bake(); + } else { + this.manager.controls.showStaleIndicator(); + } + } + + + /** + * Runs a silent bake, forcing the browser to load and cache all the relevant JavaScript code needed + * to do a real bake. + * + * The output will not be modified (hence "silent" bake). This will only actually execute the recipe + * if auto-bake is enabled, otherwise it will just wake up the ChefWorker with an empty recipe. + */ + silentBake() { + let recipeConfig = []; + + if (this.autoBake_) { + // If auto-bake is not enabled we don't want to actually run the recipe as it may be disabled + // for a good reason. + recipeConfig = this.getRecipeConfig(); + } + + this.manager.worker.silentBake(recipeConfig); + } + + + /** + * Gets the user's input data. + * + * @returns {string} + */ + getInput() { + return this.manager.input.get(); + } + + + /** + * Sets the user's input data. + * + * @param {string} input - The string to set the input to + */ + setInput(input) { + this.manager.input.set(input); + } + + + /** + * Populates the operations accordion list with the categories and operations specified in the + * view constructor. + * + * @fires Manager#oplistcreate + */ + populateOperationsList() { + // Move edit button away before we overwrite it + document.body.appendChild(document.getElementById("edit-favourites")); + + let html = ""; + let i; + + for (i = 0; i < this.categories.length; i++) { + const catConf = this.categories[i], + selected = i === 0, + cat = new HTMLCategory(catConf.name, selected); + + for (let j = 0; j < catConf.ops.length; j++) { + const opName = catConf.ops[j]; + if (!this.operations.hasOwnProperty(opName)) { + log.warn(`${opName} could not be found.`); + continue; + } + + const op = new HTMLOperation(opName, this.operations[opName], this, this.manager); + cat.addOperation(op); + } + + html += cat.toHtml(); + } + + document.getElementById("categories").innerHTML = html; + + const opLists = document.querySelectorAll("#categories .op-list"); + + for (i = 0; i < opLists.length; i++) { + opLists[i].dispatchEvent(this.manager.oplistcreate); + } + + // Add edit button to first category (Favourites) + document.querySelector("#categories a").appendChild(document.getElementById("edit-favourites")); + } + + + /** + * Sets up the adjustable splitter to allow the user to resize areas of the page. + */ + initialiseSplitter() { + this.columnSplitter = Split(["#operations", "#recipe", "#IO"], { + sizes: [20, 30, 50], + minSize: [240, 325, 450], + gutterSize: 4, + onDrag: function() { + this.manager.controls.adjustWidth(); + this.manager.output.adjustWidth(); + }.bind(this) + }); + + this.ioSplitter = Split(["#input", "#output"], { + direction: "vertical", + gutterSize: 4, + }); + + this.resetLayout(); + } + + + /** + * Loads the information previously saved to the HTML5 local storage object so that user options + * and favourites can be restored. + */ + loadLocalStorage() { + // Load options + let lOptions; + if (this.isLocalStorageAvailable() && localStorage.options !== undefined) { + lOptions = JSON.parse(localStorage.options); + } + this.manager.options.load(lOptions); + + // Load favourites + this.loadFavourites(); + } + + + /** + * Loads the user's favourite operations from the HTML5 local storage object and populates the + * Favourites category with them. + * If the user currently has no saved favourites, the defaults from the view constructor are used. + */ + loadFavourites() { + let favourites; + + if (this.isLocalStorageAvailable()) { + favourites = localStorage.favourites && localStorage.favourites.length > 2 ? + JSON.parse(localStorage.favourites) : + this.dfavourites; + favourites = this.validFavourites(favourites); + this.saveFavourites(favourites); + } else { + favourites = this.dfavourites; + } + + const favCat = this.categories.filter(function(c) { + return c.name === "Favourites"; + })[0]; + + if (favCat) { + favCat.ops = favourites; + } else { + this.categories.unshift({ + name: "Favourites", + ops: favourites + }); + } + } + + + /** + * Filters the list of favourite operations that the user had stored and removes any that are no + * longer available. The user is notified if this is the case. + + * @param {string[]} favourites - A list of the user's favourite operations + * @returns {string[]} A list of the valid favourites + */ + validFavourites(favourites) { + const validFavs = []; + for (let i = 0; i < favourites.length; i++) { + if (this.operations.hasOwnProperty(favourites[i])) { + validFavs.push(favourites[i]); + } else { + this.alert("The operation \"" + Utils.escapeHtml(favourites[i]) + + "\" is no longer available. It has been removed from your favourites.", "info"); + } + } + return validFavs; + } + + + /** + * Saves a list of favourite operations to the HTML5 local storage object. + * + * @param {string[]} favourites - A list of the user's favourite operations + */ + saveFavourites(favourites) { + if (!this.isLocalStorageAvailable()) { + this.alert( + "Your security settings do not allow access to local storage so your favourites cannot be saved.", + "danger", + 5000 + ); + return false; + } + + localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites))); + } + + + /** + * Resets favourite operations back to the default as specified in the view constructor and + * refreshes the operation list. + */ + resetFavourites() { + this.saveFavourites(this.dfavourites); + this.loadFavourites(); + this.populateOperationsList(); + this.manager.recipe.initialiseOperationDragNDrop(); + } + + + /** + * Adds an operation to the user's favourites. + * + * @param {string} name - The name of the operation + */ + addFavourite(name) { + const favourites = JSON.parse(localStorage.favourites); + + if (favourites.indexOf(name) >= 0) { + this.alert("'" + name + "' is already in your favourites", "info", 2000); + return; + } + + favourites.push(name); + this.saveFavourites(favourites); + this.loadFavourites(); + this.populateOperationsList(); + this.manager.recipe.initialiseOperationDragNDrop(); + } + + + /** + * Checks for input and recipe in the URI parameters and loads them if present. + */ + loadURIParams() { + // Load query string or hash from URI (depending on which is populated) + // We prefer getting the hash by splitting the href rather than referencing + // location.hash as some browsers (Firefox) automatically URL decode it, + // which cause issues. + const params = window.location.search || + window.location.href.split("#")[1] || + window.location.hash; + this.uriParams = Utils.parseURIParams(params); + this.autoBakePause = true; + + // Read in recipe from URI params + if (this.uriParams.recipe) { + try { + const recipeConfig = Utils.parseRecipeConfig(this.uriParams.recipe); + this.setRecipeConfig(recipeConfig); + } catch (err) {} + } else if (this.uriParams.op) { + // If there's no recipe, look for single operations + this.manager.recipe.clearRecipe(); + + // Search for nearest match and add it + const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false); + if (matchedOps.length) { + this.manager.recipe.addOperation(matchedOps[0].name); + } + + // Populate search with the string + const search = document.getElementById("search"); + + search.value = this.uriParams.op; + search.dispatchEvent(new Event("search")); + } + + // Read in input data from URI params + if (this.uriParams.input) { + try { + const inputData = fromBase64(this.uriParams.input); + this.setInput(inputData); + } catch (err) {} + } + + this.autoBakePause = false; + this.autoBake(); + } + + + /** + * Returns the next ingredient ID and increments it for next time. + * + * @returns {number} + */ + nextIngId() { + return this.ingId++; + } + + + /** + * Gets the current recipe configuration. + * + * @returns {Object[]} + */ + getRecipeConfig() { + return this.manager.recipe.getConfig(); + } + + + /** + * Given a recipe configuration, sets the recipe to that configuration. + * + * @fires Manager#statechange + * @param {Object[]} recipeConfig - The recipe configuration + */ + setRecipeConfig(recipeConfig) { + document.getElementById("rec-list").innerHTML = null; + + // Pause auto-bake while loading but don't modify `this.autoBake_` + // otherwise `manualBake` cannot trigger. + this.autoBakePause = true; + + for (let i = 0; i < recipeConfig.length; i++) { + const item = this.manager.recipe.addOperation(recipeConfig[i].op); + + // Populate arguments + const args = item.querySelectorAll(".arg"); + for (let j = 0; j < args.length; j++) { + if (recipeConfig[i].args[j] === undefined) continue; + if (args[j].getAttribute("type") === "checkbox") { + // checkbox + args[j].checked = recipeConfig[i].args[j]; + } else if (args[j].classList.contains("toggle-string")) { + // toggleString + args[j].value = recipeConfig[i].args[j].string; + args[j].previousSibling.children[0].innerHTML = + Utils.escapeHtml(recipeConfig[i].args[j].option) + + " "; + } else { + // all others + args[j].value = recipeConfig[i].args[j]; + } + } + + // Set disabled and breakpoint + if (recipeConfig[i].disabled) { + item.querySelector(".disable-icon").click(); + } + if (recipeConfig[i].breakpoint) { + item.querySelector(".breakpoint").click(); + } + + this.progress = 0; + } + + // Unpause auto bake + this.autoBakePause = false; + } + + + /** + * Resets the splitter positions to default. + */ + resetLayout() { + this.columnSplitter.setSizes([20, 30, 50]); + this.ioSplitter.setSizes([50, 50]); + + this.manager.controls.adjustWidth(); + this.manager.output.adjustWidth(); + } + + + /** + * Sets the compile message. + */ + setCompileMessage() { + // Display time since last build and compile message + const now = new Date(), + timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime); + + // Calculate previous version to compare to + const prev = PKG_VERSION.split(".").map(n => { + return parseInt(n, 10); + }); + if (prev[2] > 0) prev[2]--; + else if (prev[1] > 0) prev[1]--; + else prev[0]--; + + const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`; + + let compileInfo = `Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago`; + + if (window.compileMessage !== "") { + compileInfo += " - " + window.compileMessage; + } + + document.getElementById("notice").innerHTML = compileInfo; + } + + + /** + * Determines whether the browser supports Local Storage and if it is accessible. + * + * @returns {boolean} + */ + isLocalStorageAvailable() { + try { + if (!localStorage) return false; + return true; + } catch (err) { + // Access to LocalStorage is denied + return false; + } + } + + + /** + * Pops up a message to the user and writes it to the console log. + * + * @param {string} str - The message to display (HTML supported) + * @param {string} style - The colour of the popup + * "danger" = red + * "warning" = amber + * "info" = blue + * "success" = green + * @param {number} timeout - The number of milliseconds before the popup closes automatically + * 0 for never (until the user closes it) + * @param {boolean} [silent=false] - Don't show the message in the popup, only print it to the + * console + * + * @example + * // Pops up a red box with the message "[current time] Error: Something has gone wrong!" + * // that will need to be dismissed by the user. + * this.alert("Error: Something has gone wrong!", "danger", 0); + * + * // Pops up a blue information box with the message "[current time] Happy Christmas!" + * // that will disappear after 5 seconds. + * this.alert("Happy Christmas!", "info", 5000); + */ + alert(str, style, timeout, silent) { + const time = new Date(); + + log.info("[" + time.toLocaleString() + "] " + str); + if (silent) return; + + style = style || "danger"; + timeout = timeout || 0; + + const alertEl = document.getElementById("alert"), + alertContent = document.getElementById("alert-content"); + + alertEl.classList.remove("alert-danger"); + alertEl.classList.remove("alert-warning"); + alertEl.classList.remove("alert-info"); + alertEl.classList.remove("alert-success"); + alertEl.classList.add("alert-" + style); + + // If the box hasn't been closed, append to it rather than replacing + if (alertEl.style.display === "block") { + alertContent.innerHTML += + "

[" + time.toLocaleTimeString() + "] " + str; + } else { + alertContent.innerHTML = + "[" + time.toLocaleTimeString() + "] " + str; + } + + // Stop the animation if it is in progress + $("#alert").stop(); + alertEl.style.display = "block"; + alertEl.style.opacity = 1; + + if (timeout > 0) { + clearTimeout(this.alertTimeout); + this.alertTimeout = setTimeout(function(){ + $("#alert").slideUp(100); + }, timeout); + } + } + + + /** + * Pops up a box asking the user a question and sending the answer to a specified callback function. + * + * @param {string} title - The title of the box + * @param {string} body - The question (HTML supported) + * @param {function} callback - A function accepting one boolean argument which handles the + * response e.g. function(answer) {...} + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. + * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); + */ + confirm(title, body, callback, scope) { + scope = scope || this; + document.getElementById("confirm-title").innerHTML = title; + document.getElementById("confirm-body").innerHTML = body; + document.getElementById("confirm-modal").style.display = "block"; + + this.confirmClosed = false; + $("#confirm-modal").modal() + .one("show.bs.modal", function(e) { + this.confirmClosed = false; + }.bind(this)) + .one("click", "#confirm-yes", function() { + this.confirmClosed = true; + callback.bind(scope)(true); + $("#confirm-modal").modal("hide"); + }.bind(this)) + .one("hide.bs.modal", function(e) { + if (!this.confirmClosed) + callback.bind(scope)(false); + this.confirmClosed = true; + }.bind(this)); + } + + + /** + * Handler for the alert close button click event. + * Closes the alert box. + */ + alertCloseClick() { + document.getElementById("alert").style.display = "none"; + } + + + /** + * Handler for CyerChef statechange events. + * Fires whenever the input or recipe changes in any way. + * + * @listens Manager#statechange + * @param {event} e + */ + stateChange(e) { + this.autoBake(); + + // Set title + const recipeConfig = this.getRecipeConfig(); + let title = "CyberChef"; + if (recipeConfig.length === 1) { + title = `${recipeConfig[0].op} - ${title}`; + } else if (recipeConfig.length > 1) { + // See how long the full recipe is + const ops = recipeConfig.map(op => op.op).join(", "); + if (ops.length < 45) { + title = `${ops} - ${title}`; + } else { + // If it's too long, just use the first one and say how many more there are + title = `${recipeConfig[0].op}, ${recipeConfig.length - 1} more - ${title}`; + } + } + document.title = title; + + // Update the current history state (not creating a new one) + if (this.options.updateUrl) { + this.lastStateUrl = this.manager.controls.generateStateUrl(true, true, recipeConfig); + window.history.replaceState({}, title, this.lastStateUrl); + } + } + + + /** + * Handler for the history popstate event. + * Reloads parameters from the URL. + * + * @param {event} e + */ + popState(e) { + this.loadURIParams(); + } + + + /** + * Function to call an external API from this view. + */ + callApi(url, type, data, dataType, contentType) { + type = type || "POST"; + data = data || {}; + dataType = dataType || undefined; + contentType = contentType || "application/json"; + + let response = null, + success = false; + + $.ajax({ + url: url, + async: false, + type: type, + data: data, + dataType: dataType, + contentType: contentType, + success: function(data) { + success = true; + response = data; + }, + error: function(data) { + success = false; + response = data; + }, + }); + + return { + success: success, + response: response + }; + } + +} + +export default App; diff --git a/src/web/BindingsWaiter.js b/src/web/BindingsWaiter.js deleted file mode 100755 index 802590b8..00000000 --- a/src/web/BindingsWaiter.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Waiter to handle keybindings to CyberChef functions (i.e. Bake, Step, Save, Load etc.) - * - * @author Matt C [matt@artemisbot.uk] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const BindingsWaiter = function (app, manager) { - this.app = app; - this.manager = manager; -}; - - -/** - * Handler for all keydown events - * Checks whether valid keyboard shortcut has been instated - * - * @fires Manager#statechange - * @param {event} e - */ -BindingsWaiter.prototype.parseInput = function(e) { - const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey; - - if (e.ctrlKey && modKey) { - let elem; - switch (e.code) { - case "KeyF": // Focus search - e.preventDefault(); - document.getElementById("search").focus(); - break; - case "KeyI": // Focus input - e.preventDefault(); - document.getElementById("input-text").focus(); - break; - case "KeyO": // Focus output - e.preventDefault(); - document.getElementById("output-text").focus(); - break; - case "Period": // Focus next operation - e.preventDefault(); - try { - elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation"); - if (elem.parentNode.lastChild === elem) { - // If operation is last in recipe, loop around to the top operation's first argument - elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus(); - } else { - // Focus first argument of next operation - elem.nextSibling.querySelectorAll(".arg")[0].focus(); - } - } catch (e) { - // do nothing, just don't throw an error - } - break; - case "KeyB": // Set breakpoint - e.preventDefault(); - try { - elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0]; - if (elem.getAttribute("break") === "false") { - elem.setAttribute("break", "true"); // add break point if not already enabled - elem.classList.add("breakpoint-selected"); - } else { - elem.setAttribute("break", "false"); // remove break point if already enabled - elem.classList.remove("breakpoint-selected"); - } - window.dispatchEvent(this.manager.statechange); - } catch (e) { - // do nothing, just don't throw an error - } - break; - case "KeyD": // Disable operation - e.preventDefault(); - try { - elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0]; - if (elem.getAttribute("disabled") === "false") { - elem.setAttribute("disabled", "true"); // disable operation if enabled - elem.classList.add("disable-elem-selected"); - elem.parentNode.parentNode.classList.add("disabled"); - } else { - elem.setAttribute("disabled", "false"); // enable operation if disabled - elem.classList.remove("disable-elem-selected"); - elem.parentNode.parentNode.classList.remove("disabled"); - } - this.app.progress = 0; - window.dispatchEvent(this.manager.statechange); - } catch (e) { - // do nothing, just don't throw an error - } - break; - case "Space": // Bake - e.preventDefault(); - this.app.bake(); - break; - case "Quote": // Step through - e.preventDefault(); - this.app.bake(true); - break; - case "KeyC": // Clear recipe - e.preventDefault(); - this.manager.recipe.clearRecipe(); - break; - case "KeyS": // Save output to file - e.preventDefault(); - this.manager.output.saveClick(); - break; - case "KeyL": // Load recipe - e.preventDefault(); - this.manager.controls.loadClick(); - break; - case "KeyM": // Switch input and output - e.preventDefault(); - this.manager.output.switchClick(); - break; - default: - if (e.code.match(/Digit[0-9]/g)) { // Select nth operation - e.preventDefault(); - try { - // Select the first argument of the operation corresponding to the number pressed - document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus(); - } catch (e) { - // do nothing, just don't throw an error - } - } - break; - } - } -}; - - -/** - * Updates keybinding list when metaKey option is toggled - * - */ -BindingsWaiter.prototype.updateKeybList = function() { - let modWinLin = "Alt"; - let modMac = "Opt"; - if (this.app.options.useMetaKey) { - modWinLin = "Win"; - modMac = "Cmd"; - } - document.getElementById("keybList").innerHTML = ` - - Command - Shortcut (Win/Linux) - Shortcut (Mac) - - - Place cursor in search field - Ctrl+${modWinLin}+f - Ctrl+${modMac}+f - - Place cursor in input box - Ctrl+${modWinLin}+i - Ctrl+${modMac}+i - - - Place cursor in output box - Ctrl+${modWinLin}+o - Ctrl+${modMac}+o - - - Place cursor in first argument field of the next operation in the recipe - Ctrl+${modWinLin}+. - Ctrl+${modMac}+. - - - Place cursor in first argument field of the nth operation in the recipe - Ctrl+${modWinLin}+[1-9] - Ctrl+${modMac}+[1-9] - - - Disable current operation - Ctrl+${modWinLin}+d - Ctrl+${modMac}+d - - - Set/clear breakpoint - Ctrl+${modWinLin}+b - Ctrl+${modMac}+b - - - Bake - Ctrl+${modWinLin}+Space - Ctrl+${modMac}+Space - - - Step - Ctrl+${modWinLin}+' - Ctrl+${modMac}+' - - - Clear recipe - Ctrl+${modWinLin}+c - Ctrl+${modMac}+c - - - Save to file - Ctrl+${modWinLin}+s - Ctrl+${modMac}+s - - - Load recipe - Ctrl+${modWinLin}+l - Ctrl+${modMac}+l - - - Move output to input - Ctrl+${modWinLin}+m - Ctrl+${modMac}+m - - `; -}; - -export default BindingsWaiter; diff --git a/src/web/BindingsWaiter.mjs b/src/web/BindingsWaiter.mjs new file mode 100755 index 00000000..74262c61 --- /dev/null +++ b/src/web/BindingsWaiter.mjs @@ -0,0 +1,224 @@ +/** + * @author Matt C [matt@artemisbot.uk] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Waiter to handle keybindings to CyberChef functions (i.e. Bake, Step, Save, Load etc.) + */ +class BindingsWaiter { + + /** + * BindingsWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + } + + + /** + * Handler for all keydown events + * Checks whether valid keyboard shortcut has been instated + * + * @fires Manager#statechange + * @param {event} e + */ + parseInput(e) { + const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey; + + if (e.ctrlKey && modKey) { + let elem; + switch (e.code) { + case "KeyF": // Focus search + e.preventDefault(); + document.getElementById("search").focus(); + break; + case "KeyI": // Focus input + e.preventDefault(); + document.getElementById("input-text").focus(); + break; + case "KeyO": // Focus output + e.preventDefault(); + document.getElementById("output-text").focus(); + break; + case "Period": // Focus next operation + e.preventDefault(); + try { + elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation"); + if (elem.parentNode.lastChild === elem) { + // If operation is last in recipe, loop around to the top operation's first argument + elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus(); + } else { + // Focus first argument of next operation + elem.nextSibling.querySelectorAll(".arg")[0].focus(); + } + } catch (e) { + // do nothing, just don't throw an error + } + break; + case "KeyB": // Set breakpoint + e.preventDefault(); + try { + elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0]; + if (elem.getAttribute("break") === "false") { + elem.setAttribute("break", "true"); // add break point if not already enabled + elem.classList.add("breakpoint-selected"); + } else { + elem.setAttribute("break", "false"); // remove break point if already enabled + elem.classList.remove("breakpoint-selected"); + } + window.dispatchEvent(this.manager.statechange); + } catch (e) { + // do nothing, just don't throw an error + } + break; + case "KeyD": // Disable operation + e.preventDefault(); + try { + elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0]; + if (elem.getAttribute("disabled") === "false") { + elem.setAttribute("disabled", "true"); // disable operation if enabled + elem.classList.add("disable-elem-selected"); + elem.parentNode.parentNode.classList.add("disabled"); + } else { + elem.setAttribute("disabled", "false"); // enable operation if disabled + elem.classList.remove("disable-elem-selected"); + elem.parentNode.parentNode.classList.remove("disabled"); + } + this.app.progress = 0; + window.dispatchEvent(this.manager.statechange); + } catch (e) { + // do nothing, just don't throw an error + } + break; + case "Space": // Bake + e.preventDefault(); + this.app.bake(); + break; + case "Quote": // Step through + e.preventDefault(); + this.app.bake(true); + break; + case "KeyC": // Clear recipe + e.preventDefault(); + this.manager.recipe.clearRecipe(); + break; + case "KeyS": // Save output to file + e.preventDefault(); + this.manager.output.saveClick(); + break; + case "KeyL": // Load recipe + e.preventDefault(); + this.manager.controls.loadClick(); + break; + case "KeyM": // Switch input and output + e.preventDefault(); + this.manager.output.switchClick(); + break; + default: + if (e.code.match(/Digit[0-9]/g)) { // Select nth operation + e.preventDefault(); + try { + // Select the first argument of the operation corresponding to the number pressed + document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus(); + } catch (e) { + // do nothing, just don't throw an error + } + } + break; + } + } + } + + + /** + * Updates keybinding list when metaKey option is toggled + */ + updateKeybList() { + let modWinLin = "Alt"; + let modMac = "Opt"; + if (this.app.options.useMetaKey) { + modWinLin = "Win"; + modMac = "Cmd"; + } + document.getElementById("keybList").innerHTML = ` + + Command + Shortcut (Win/Linux) + Shortcut (Mac) + + + Place cursor in search field + Ctrl+${modWinLin}+f + Ctrl+${modMac}+f + + Place cursor in input box + Ctrl+${modWinLin}+i + Ctrl+${modMac}+i + + + Place cursor in output box + Ctrl+${modWinLin}+o + Ctrl+${modMac}+o + + + Place cursor in first argument field of the next operation in the recipe + Ctrl+${modWinLin}+. + Ctrl+${modMac}+. + + + Place cursor in first argument field of the nth operation in the recipe + Ctrl+${modWinLin}+[1-9] + Ctrl+${modMac}+[1-9] + + + Disable current operation + Ctrl+${modWinLin}+d + Ctrl+${modMac}+d + + + Set/clear breakpoint + Ctrl+${modWinLin}+b + Ctrl+${modMac}+b + + + Bake + Ctrl+${modWinLin}+Space + Ctrl+${modMac}+Space + + + Step + Ctrl+${modWinLin}+' + Ctrl+${modMac}+' + + + Clear recipe + Ctrl+${modWinLin}+c + Ctrl+${modMac}+c + + + Save to file + Ctrl+${modWinLin}+s + Ctrl+${modMac}+s + + + Load recipe + Ctrl+${modWinLin}+l + Ctrl+${modMac}+l + + + Move output to input + Ctrl+${modWinLin}+m + Ctrl+${modMac}+m + + `; + } + +} + +export default BindingsWaiter; diff --git a/src/web/ControlsWaiter.js b/src/web/ControlsWaiter.js deleted file mode 100755 index bf3082cd..00000000 --- a/src/web/ControlsWaiter.js +++ /dev/null @@ -1,441 +0,0 @@ -import Utils from "../core/Utils"; -import {toBase64} from "../core/lib/Base64"; - - -/** - * Waiter to handle events related to the CyberChef controls (i.e. Bake, Step, Save, Load etc.) - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const ControlsWaiter = function(app, manager) { - this.app = app; - this.manager = manager; -}; - - -/** - * Adjusts the display properties of the control buttons so that they fit within the current width - * without wrapping or overflowing. - */ -ControlsWaiter.prototype.adjustWidth = function() { - const controls = document.getElementById("controls"); - const step = document.getElementById("step"); - const clrBreaks = document.getElementById("clr-breaks"); - const saveImg = document.querySelector("#save img"); - const loadImg = document.querySelector("#load img"); - const stepImg = document.querySelector("#step img"); - const clrRecipImg = document.querySelector("#clr-recipe img"); - const clrBreaksImg = document.querySelector("#clr-breaks img"); - - if (controls.clientWidth < 470) { - step.childNodes[1].nodeValue = " Step"; - } else { - step.childNodes[1].nodeValue = " Step through"; - } - - if (controls.clientWidth < 400) { - saveImg.style.display = "none"; - loadImg.style.display = "none"; - stepImg.style.display = "none"; - clrRecipImg.style.display = "none"; - clrBreaksImg.style.display = "none"; - } else { - saveImg.style.display = "inline"; - loadImg.style.display = "inline"; - stepImg.style.display = "inline"; - clrRecipImg.style.display = "inline"; - clrBreaksImg.style.display = "inline"; - } - - if (controls.clientWidth < 330) { - clrBreaks.childNodes[1].nodeValue = " Clear breaks"; - } else { - clrBreaks.childNodes[1].nodeValue = " Clear breakpoints"; - } -}; - - -/** - * Checks or unchecks the Auto Bake checkbox based on the given value. - * - * @param {boolean} value - The new value for Auto Bake. - */ -ControlsWaiter.prototype.setAutoBake = function(value) { - const autoBakeCheckbox = document.getElementById("auto-bake"); - - if (autoBakeCheckbox.checked !== value) { - autoBakeCheckbox.click(); - } -}; - - -/** - * Handler to trigger baking. - */ -ControlsWaiter.prototype.bakeClick = function() { - if (document.getElementById("bake").textContent.indexOf("Bake") > 0) { - this.app.bake(); - } else { - this.manager.worker.cancelBake(); - } -}; - - -/** - * Handler for the 'Step through' command. Executes the next step of the recipe. - */ -ControlsWaiter.prototype.stepClick = function() { - this.app.bake(true); -}; - - -/** - * Handler for changes made to the Auto Bake checkbox. - */ -ControlsWaiter.prototype.autoBakeChange = function() { - const autoBakeLabel = document.getElementById("auto-bake-label"); - const autoBakeCheckbox = document.getElementById("auto-bake"); - - this.app.autoBake_ = autoBakeCheckbox.checked; - - if (autoBakeCheckbox.checked) { - autoBakeLabel.classList.add("btn-success"); - autoBakeLabel.classList.remove("btn-default"); - } else { - autoBakeLabel.classList.add("btn-default"); - autoBakeLabel.classList.remove("btn-success"); - } -}; - - -/** - * Handler for the 'Clear recipe' command. Removes all operations from the recipe. - */ -ControlsWaiter.prototype.clearRecipeClick = function() { - this.manager.recipe.clearRecipe(); -}; - - -/** - * Handler for the 'Clear breakpoints' command. Removes all breakpoints from operations in the - * recipe. - */ -ControlsWaiter.prototype.clearBreaksClick = function() { - const bps = document.querySelectorAll("#rec-list li.operation .breakpoint"); - - for (let i = 0; i < bps.length; i++) { - bps[i].setAttribute("break", "false"); - bps[i].classList.remove("breakpoint-selected"); - } -}; - - -/** - * Populates the save disalog box with a URL incorporating the recipe and input. - * - * @param {Object[]} [recipeConfig] - The recipe configuration object array. - */ -ControlsWaiter.prototype.initialiseSaveLink = function(recipeConfig) { - recipeConfig = recipeConfig || this.app.getRecipeConfig(); - - const includeRecipe = document.getElementById("save-link-recipe-checkbox").checked; - const includeInput = document.getElementById("save-link-input-checkbox").checked; - const saveLinkEl = document.getElementById("save-link"); - const saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig); - - saveLinkEl.innerHTML = Utils.truncate(saveLink, 120); - saveLinkEl.setAttribute("href", saveLink); -}; - - -/** - * Generates a URL containing the current recipe and input state. - * - * @param {boolean} includeRecipe - Whether to include the recipe in the URL. - * @param {boolean} includeInput - Whether to include the input in the URL. - * @param {Object[]} [recipeConfig] - The recipe configuration object array. - * @param {string} [baseURL] - The CyberChef URL, set to the current URL if not included - * @returns {string} - */ -ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput, recipeConfig, baseURL) { - recipeConfig = recipeConfig || this.app.getRecipeConfig(); - - const link = baseURL || window.location.protocol + "//" + - window.location.host + - window.location.pathname; - const recipeStr = Utils.generatePrettyRecipe(recipeConfig); - const inputStr = toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding - - includeRecipe = includeRecipe && (recipeConfig.length > 0); - // Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded) - includeInput = includeInput && (inputStr.length > 0) && (inputStr.length <= 68267); - - const params = [ - includeRecipe ? ["recipe", recipeStr] : undefined, - includeInput ? ["input", inputStr] : undefined, - ]; - - const hash = params - .filter(v => v) - .map(([key, value]) => `${key}=${Utils.encodeURIFragment(value)}`) - .join("&"); - - if (hash) { - return `${link}#${hash}`; - } - - return link; -}; - - -/** - * Handler for changes made to the save dialog text area. Re-initialises the save link. - */ -ControlsWaiter.prototype.saveTextChange = function(e) { - try { - const recipeConfig = Utils.parseRecipeConfig(e.target.value); - this.initialiseSaveLink(recipeConfig); - } catch (err) {} -}; - - -/** - * Handler for the 'Save' command. Pops up the save dialog box. - */ -ControlsWaiter.prototype.saveClick = function() { - const recipeConfig = this.app.getRecipeConfig(); - const recipeStr = JSON.stringify(recipeConfig); - - document.getElementById("save-text-chef").value = Utils.generatePrettyRecipe(recipeConfig, true); - document.getElementById("save-text-clean").value = JSON.stringify(recipeConfig, null, 2) - .replace(/{\n\s+"/g, "{ \"") - .replace(/\[\n\s{3,}/g, "[") - .replace(/\n\s{3,}]/g, "]") - .replace(/\s*\n\s*}/g, " }") - .replace(/\n\s{6,}/g, " "); - document.getElementById("save-text-compact").value = recipeStr; - - this.initialiseSaveLink(recipeConfig); - $("#save-modal").modal(); -}; - - -/** - * Handler for the save link recipe checkbox change event. - */ -ControlsWaiter.prototype.slrCheckChange = function() { - this.initialiseSaveLink(); -}; - - -/** - * Handler for the save link input checkbox change event. - */ -ControlsWaiter.prototype.sliCheckChange = function() { - this.initialiseSaveLink(); -}; - - -/** - * Handler for the 'Load' command. Pops up the load dialog box. - */ -ControlsWaiter.prototype.loadClick = function() { - this.populateLoadRecipesList(); - $("#load-modal").modal(); -}; - - -/** - * Saves the recipe specified in the save textarea to local storage. - */ -ControlsWaiter.prototype.saveButtonClick = function() { - if (!this.app.isLocalStorageAvailable()) { - this.app.alert( - "Your security settings do not allow access to local storage so your recipe cannot be saved.", - "danger", - 5000 - ); - return false; - } - - const recipeName = Utils.escapeHtml(document.getElementById("save-name").value); - const recipeStr = document.querySelector("#save-texts .tab-pane.active textarea").value; - - if (!recipeName) { - this.app.alert("Please enter a recipe name", "danger", 2000); - return; - } - - const savedRecipes = localStorage.savedRecipes ? - JSON.parse(localStorage.savedRecipes) : []; - let recipeId = localStorage.recipeId || 0; - - savedRecipes.push({ - id: ++recipeId, - name: recipeName, - recipe: recipeStr - }); - - localStorage.savedRecipes = JSON.stringify(savedRecipes); - localStorage.recipeId = recipeId; - - this.app.alert("Recipe saved as \"" + recipeName + "\".", "success", 2000); -}; - - -/** - * Populates the list of saved recipes in the load dialog box from local storage. - */ -ControlsWaiter.prototype.populateLoadRecipesList = function() { - if (!this.app.isLocalStorageAvailable()) return false; - - const loadNameEl = document.getElementById("load-name"); - - // Remove current recipes from select - let i = loadNameEl.options.length; - while (i--) { - loadNameEl.remove(i); - } - - // Add recipes to select - const savedRecipes = localStorage.savedRecipes ? - JSON.parse(localStorage.savedRecipes) : []; - - for (i = 0; i < savedRecipes.length; i++) { - const opt = document.createElement("option"); - opt.value = savedRecipes[i].id; - // Unescape then re-escape in case localStorage has been corrupted - opt.innerHTML = Utils.escapeHtml(Utils.unescapeHtml(savedRecipes[i].name)); - - loadNameEl.appendChild(opt); - } - - // Populate textarea with first recipe - document.getElementById("load-text").value = savedRecipes.length ? savedRecipes[0].recipe : ""; -}; - - -/** - * Removes the currently selected recipe from local storage. - */ -ControlsWaiter.prototype.loadDeleteClick = function() { - if (!this.app.isLocalStorageAvailable()) return false; - - const id = parseInt(document.getElementById("load-name").value, 10); - const rawSavedRecipes = localStorage.savedRecipes ? - JSON.parse(localStorage.savedRecipes) : []; - - const savedRecipes = rawSavedRecipes.filter(r => r.id !== id); - - localStorage.savedRecipes = JSON.stringify(savedRecipes); - this.populateLoadRecipesList(); -}; - - -/** - * Displays the selected recipe in the load text box. - */ -ControlsWaiter.prototype.loadNameChange = function(e) { - if (!this.app.isLocalStorageAvailable()) return false; - - const el = e.target; - const savedRecipes = localStorage.savedRecipes ? - JSON.parse(localStorage.savedRecipes) : []; - const id = parseInt(el.value, 10); - - const recipe = savedRecipes.find(r => r.id === id); - - document.getElementById("load-text").value = recipe.recipe; -}; - - -/** - * Loads the selected recipe and populates the Recipe with its operations. - */ -ControlsWaiter.prototype.loadButtonClick = function() { - try { - const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value); - this.app.setRecipeConfig(recipeConfig); - this.app.autoBake(); - - $("#rec-list [data-toggle=popover]").popover(); - } catch (e) { - this.app.alert("Invalid recipe", "danger", 2000); - } -}; - - -/** - * Populates the bug report information box with useful technical info. - * - * @param {event} e - */ -ControlsWaiter.prototype.supportButtonClick = function(e) { - e.preventDefault(); - - const reportBugInfo = document.getElementById("report-bug-info"); - const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/"); - - if (reportBugInfo) { - reportBugInfo.innerHTML = `* Version: ${PKG_VERSION + (typeof INLINE === "undefined" ? "" : "s")} -* Compile time: ${COMPILE_TIME} -* User-Agent: -${navigator.userAgent} -* [Link to reproduce](${saveLink}) - -`; - } -}; - - -/** - * Shows the stale indicator to show that the input or recipe has changed - * since the last bake. - */ -ControlsWaiter.prototype.showStaleIndicator = function() { - const staleIndicator = document.getElementById("stale-indicator"); - - staleIndicator.style.visibility = "visible"; - staleIndicator.style.opacity = 1; -}; - - -/** - * Hides the stale indicator to show that the input or recipe has not changed - * since the last bake. - */ -ControlsWaiter.prototype.hideStaleIndicator = function() { - const staleIndicator = document.getElementById("stale-indicator"); - - staleIndicator.style.opacity = 0; - staleIndicator.style.visibility = "hidden"; -}; - - -/** - * Switches the Bake button between 'Bake' and 'Cancel' functions. - * - * @param {boolean} cancel - Whether to change to cancel or not - */ -ControlsWaiter.prototype.toggleBakeButtonFunction = function(cancel) { - const bakeButton = document.getElementById("bake"), - btnText = bakeButton.querySelector("span"); - - if (cancel) { - btnText.innerText = "Cancel"; - bakeButton.classList.remove("btn-success"); - bakeButton.classList.add("btn-danger"); - } else { - btnText.innerText = "Bake!"; - bakeButton.classList.remove("btn-danger"); - bakeButton.classList.add("btn-success"); - } -}; - -export default ControlsWaiter; diff --git a/src/web/ControlsWaiter.mjs b/src/web/ControlsWaiter.mjs new file mode 100755 index 00000000..2e8da9a0 --- /dev/null +++ b/src/web/ControlsWaiter.mjs @@ -0,0 +1,449 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Utils from "../core/Utils"; +import {toBase64} from "../core/lib/Base64"; + + +/** + * Waiter to handle events related to the CyberChef controls (i.e. Bake, Step, Save, Load etc.) + */ +class ControlsWaiter { + + /** + * ControlsWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + } + + + /** + * Adjusts the display properties of the control buttons so that they fit within the current width + * without wrapping or overflowing. + */ + adjustWidth() { + const controls = document.getElementById("controls"); + const step = document.getElementById("step"); + const clrBreaks = document.getElementById("clr-breaks"); + const saveImg = document.querySelector("#save img"); + const loadImg = document.querySelector("#load img"); + const stepImg = document.querySelector("#step img"); + const clrRecipImg = document.querySelector("#clr-recipe img"); + const clrBreaksImg = document.querySelector("#clr-breaks img"); + + if (controls.clientWidth < 470) { + step.childNodes[1].nodeValue = " Step"; + } else { + step.childNodes[1].nodeValue = " Step through"; + } + + if (controls.clientWidth < 400) { + saveImg.style.display = "none"; + loadImg.style.display = "none"; + stepImg.style.display = "none"; + clrRecipImg.style.display = "none"; + clrBreaksImg.style.display = "none"; + } else { + saveImg.style.display = "inline"; + loadImg.style.display = "inline"; + stepImg.style.display = "inline"; + clrRecipImg.style.display = "inline"; + clrBreaksImg.style.display = "inline"; + } + + if (controls.clientWidth < 330) { + clrBreaks.childNodes[1].nodeValue = " Clear breaks"; + } else { + clrBreaks.childNodes[1].nodeValue = " Clear breakpoints"; + } + } + + + /** + * Checks or unchecks the Auto Bake checkbox based on the given value. + * + * @param {boolean} value - The new value for Auto Bake. + */ + setAutoBake(value) { + const autoBakeCheckbox = document.getElementById("auto-bake"); + + if (autoBakeCheckbox.checked !== value) { + autoBakeCheckbox.click(); + } + } + + + /** + * Handler to trigger baking. + */ + bakeClick() { + if (document.getElementById("bake").textContent.indexOf("Bake") > 0) { + this.app.bake(); + } else { + this.manager.worker.cancelBake(); + } + } + + + /** + * Handler for the 'Step through' command. Executes the next step of the recipe. + */ + stepClick() { + this.app.bake(true); + } + + + /** + * Handler for changes made to the Auto Bake checkbox. + */ + autoBakeChange() { + const autoBakeLabel = document.getElementById("auto-bake-label"); + const autoBakeCheckbox = document.getElementById("auto-bake"); + + this.app.autoBake_ = autoBakeCheckbox.checked; + + if (autoBakeCheckbox.checked) { + autoBakeLabel.classList.add("btn-success"); + autoBakeLabel.classList.remove("btn-default"); + } else { + autoBakeLabel.classList.add("btn-default"); + autoBakeLabel.classList.remove("btn-success"); + } + } + + + /** + * Handler for the 'Clear recipe' command. Removes all operations from the recipe. + */ + clearRecipeClick() { + this.manager.recipe.clearRecipe(); + } + + + /** + * Handler for the 'Clear breakpoints' command. Removes all breakpoints from operations in the + * recipe. + */ + clearBreaksClick() { + const bps = document.querySelectorAll("#rec-list li.operation .breakpoint"); + + for (let i = 0; i < bps.length; i++) { + bps[i].setAttribute("break", "false"); + bps[i].classList.remove("breakpoint-selected"); + } + } + + + /** + * Populates the save disalog box with a URL incorporating the recipe and input. + * + * @param {Object[]} [recipeConfig] - The recipe configuration object array. + */ + initialiseSaveLink(recipeConfig) { + recipeConfig = recipeConfig || this.app.getRecipeConfig(); + + const includeRecipe = document.getElementById("save-link-recipe-checkbox").checked; + const includeInput = document.getElementById("save-link-input-checkbox").checked; + const saveLinkEl = document.getElementById("save-link"); + const saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig); + + saveLinkEl.innerHTML = Utils.truncate(saveLink, 120); + saveLinkEl.setAttribute("href", saveLink); + } + + + /** + * Generates a URL containing the current recipe and input state. + * + * @param {boolean} includeRecipe - Whether to include the recipe in the URL. + * @param {boolean} includeInput - Whether to include the input in the URL. + * @param {Object[]} [recipeConfig] - The recipe configuration object array. + * @param {string} [baseURL] - The CyberChef URL, set to the current URL if not included + * @returns {string} + */ + generateStateUrl(includeRecipe, includeInput, recipeConfig, baseURL) { + recipeConfig = recipeConfig || this.app.getRecipeConfig(); + + const link = baseURL || window.location.protocol + "//" + + window.location.host + + window.location.pathname; + const recipeStr = Utils.generatePrettyRecipe(recipeConfig); + const inputStr = toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding + + includeRecipe = includeRecipe && (recipeConfig.length > 0); + // Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded) + includeInput = includeInput && (inputStr.length > 0) && (inputStr.length <= 68267); + + const params = [ + includeRecipe ? ["recipe", recipeStr] : undefined, + includeInput ? ["input", inputStr] : undefined, + ]; + + const hash = params + .filter(v => v) + .map(([key, value]) => `${key}=${Utils.encodeURIFragment(value)}`) + .join("&"); + + if (hash) { + return `${link}#${hash}`; + } + + return link; + } + + + /** + * Handler for changes made to the save dialog text area. Re-initialises the save link. + */ + saveTextChange(e) { + try { + const recipeConfig = Utils.parseRecipeConfig(e.target.value); + this.initialiseSaveLink(recipeConfig); + } catch (err) {} + } + + + /** + * Handler for the 'Save' command. Pops up the save dialog box. + */ + saveClick() { + const recipeConfig = this.app.getRecipeConfig(); + const recipeStr = JSON.stringify(recipeConfig); + + document.getElementById("save-text-chef").value = Utils.generatePrettyRecipe(recipeConfig, true); + document.getElementById("save-text-clean").value = JSON.stringify(recipeConfig, null, 2) + .replace(/{\n\s+"/g, "{ \"") + .replace(/\[\n\s{3,}/g, "[") + .replace(/\n\s{3,}]/g, "]") + .replace(/\s*\n\s*}/g, " }") + .replace(/\n\s{6,}/g, " "); + document.getElementById("save-text-compact").value = recipeStr; + + this.initialiseSaveLink(recipeConfig); + $("#save-modal").modal(); + } + + + /** + * Handler for the save link recipe checkbox change event. + */ + slrCheckChange() { + this.initialiseSaveLink(); + } + + + /** + * Handler for the save link input checkbox change event. + */ + sliCheckChange() { + this.initialiseSaveLink(); + } + + + /** + * Handler for the 'Load' command. Pops up the load dialog box. + */ + loadClick() { + this.populateLoadRecipesList(); + $("#load-modal").modal(); + } + + + /** + * Saves the recipe specified in the save textarea to local storage. + */ + saveButtonClick() { + if (!this.app.isLocalStorageAvailable()) { + this.app.alert( + "Your security settings do not allow access to local storage so your recipe cannot be saved.", + "danger", + 5000 + ); + return false; + } + + const recipeName = Utils.escapeHtml(document.getElementById("save-name").value); + const recipeStr = document.querySelector("#save-texts .tab-pane.active textarea").value; + + if (!recipeName) { + this.app.alert("Please enter a recipe name", "danger", 2000); + return; + } + + const savedRecipes = localStorage.savedRecipes ? + JSON.parse(localStorage.savedRecipes) : []; + let recipeId = localStorage.recipeId || 0; + + savedRecipes.push({ + id: ++recipeId, + name: recipeName, + recipe: recipeStr + }); + + localStorage.savedRecipes = JSON.stringify(savedRecipes); + localStorage.recipeId = recipeId; + + this.app.alert("Recipe saved as \"" + recipeName + "\".", "success", 2000); + } + + + /** + * Populates the list of saved recipes in the load dialog box from local storage. + */ + populateLoadRecipesList() { + if (!this.app.isLocalStorageAvailable()) return false; + + const loadNameEl = document.getElementById("load-name"); + + // Remove current recipes from select + let i = loadNameEl.options.length; + while (i--) { + loadNameEl.remove(i); + } + + // Add recipes to select + const savedRecipes = localStorage.savedRecipes ? + JSON.parse(localStorage.savedRecipes) : []; + + for (i = 0; i < savedRecipes.length; i++) { + const opt = document.createElement("option"); + opt.value = savedRecipes[i].id; + // Unescape then re-escape in case localStorage has been corrupted + opt.innerHTML = Utils.escapeHtml(Utils.unescapeHtml(savedRecipes[i].name)); + + loadNameEl.appendChild(opt); + } + + // Populate textarea with first recipe + document.getElementById("load-text").value = savedRecipes.length ? savedRecipes[0].recipe : ""; + } + + + /** + * Removes the currently selected recipe from local storage. + */ + loadDeleteClick() { + if (!this.app.isLocalStorageAvailable()) return false; + + const id = parseInt(document.getElementById("load-name").value, 10); + const rawSavedRecipes = localStorage.savedRecipes ? + JSON.parse(localStorage.savedRecipes) : []; + + const savedRecipes = rawSavedRecipes.filter(r => r.id !== id); + + localStorage.savedRecipes = JSON.stringify(savedRecipes); + this.populateLoadRecipesList(); + } + + + /** + * Displays the selected recipe in the load text box. + */ + loadNameChange(e) { + if (!this.app.isLocalStorageAvailable()) return false; + + const el = e.target; + const savedRecipes = localStorage.savedRecipes ? + JSON.parse(localStorage.savedRecipes) : []; + const id = parseInt(el.value, 10); + + const recipe = savedRecipes.find(r => r.id === id); + + document.getElementById("load-text").value = recipe.recipe; + } + + + /** + * Loads the selected recipe and populates the Recipe with its operations. + */ + loadButtonClick() { + try { + const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value); + this.app.setRecipeConfig(recipeConfig); + this.app.autoBake(); + + $("#rec-list [data-toggle=popover]").popover(); + } catch (e) { + this.app.alert("Invalid recipe", "danger", 2000); + } + } + + + /** + * Populates the bug report information box with useful technical info. + * + * @param {event} e + */ + supportButtonClick(e) { + e.preventDefault(); + + const reportBugInfo = document.getElementById("report-bug-info"); + const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/"); + + if (reportBugInfo) { + reportBugInfo.innerHTML = `* Version: ${PKG_VERSION + (typeof INLINE === "undefined" ? "" : "s")} +* Compile time: ${COMPILE_TIME} +* User-Agent: +${navigator.userAgent} +* [Link to reproduce](${saveLink}) + +`; + } + } + + + /** + * Shows the stale indicator to show that the input or recipe has changed + * since the last bake. + */ + showStaleIndicator() { + const staleIndicator = document.getElementById("stale-indicator"); + + staleIndicator.style.visibility = "visible"; + staleIndicator.style.opacity = 1; + } + + + /** + * Hides the stale indicator to show that the input or recipe has not changed + * since the last bake. + */ + hideStaleIndicator() { + const staleIndicator = document.getElementById("stale-indicator"); + + staleIndicator.style.opacity = 0; + staleIndicator.style.visibility = "hidden"; + } + + + /** + * Switches the Bake button between 'Bake' and 'Cancel' functions. + * + * @param {boolean} cancel - Whether to change to cancel or not + */ + toggleBakeButtonFunction(cancel) { + const bakeButton = document.getElementById("bake"), + btnText = bakeButton.querySelector("span"); + + if (cancel) { + btnText.innerText = "Cancel"; + bakeButton.classList.remove("btn-success"); + bakeButton.classList.add("btn-danger"); + } else { + btnText.innerText = "Bake!"; + bakeButton.classList.remove("btn-danger"); + bakeButton.classList.add("btn-success"); + } + } + +} + +export default ControlsWaiter; diff --git a/src/web/HTMLCategory.js b/src/web/HTMLCategory.js deleted file mode 100755 index e3a168ba..00000000 --- a/src/web/HTMLCategory.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Object to handle the creation of operation categories. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {string} name - The name of the category. - * @param {boolean} selected - Whether this category is pre-selected or not. - */ -const HTMLCategory = function(name, selected) { - this.name = name; - this.selected = selected; - this.opList = []; -}; - - -/** - * Adds an operation to this category. - * - * @param {HTMLOperation} operation - The operation to add. - */ -HTMLCategory.prototype.addOperation = function(operation) { - this.opList.push(operation); -}; - - -/** - * Renders the category and all operations within it in HTML. - * - * @returns {string} - */ -HTMLCategory.prototype.toHtml = function() { - const catName = "cat" + this.name.replace(/[\s/-:_]/g, ""); - let html = "
\ - \ - " + this.name + "\ - \ -
    "; - - for (let i = 0; i < this.opList.length; i++) { - html += this.opList[i].toStubHtml(); - } - - html += "
"; - return html; -}; - -export default HTMLCategory; diff --git a/src/web/HTMLCategory.mjs b/src/web/HTMLCategory.mjs new file mode 100755 index 00000000..5a2e3f7e --- /dev/null +++ b/src/web/HTMLCategory.mjs @@ -0,0 +1,60 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Object to handle the creation of operation categories. + */ +class HTMLCategory { + + /** + * HTMLCategory constructor. + * + * @param {string} name - The name of the category. + * @param {boolean} selected - Whether this category is pre-selected or not. + */ + constructor(name, selected) { + this.name = name; + this.selected = selected; + this.opList = []; + } + + + /** + * Adds an operation to this category. + * + * @param {HTMLOperation} operation - The operation to add. + */ + addOperation(operation) { + this.opList.push(operation); + } + + + /** + * Renders the category and all operations within it in HTML. + * + * @returns {string} + */ + toHtml() { + const catName = "cat" + this.name.replace(/[\s/-:_]/g, ""); + let html = "
\ + \ + " + this.name + "\ + \ +
    "; + + for (let i = 0; i < this.opList.length; i++) { + html += this.opList[i].toStubHtml(); + } + + html += "
"; + return html; + } + +} + +export default HTMLCategory; diff --git a/src/web/HTMLIngredient.js b/src/web/HTMLIngredient.js deleted file mode 100755 index ca28ab01..00000000 --- a/src/web/HTMLIngredient.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * Object to handle the creation of operation ingredients. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {Object} config - The configuration object for this ingredient. - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const HTMLIngredient = function(config, app, manager) { - this.app = app; - this.manager = manager; - - this.name = config.name; - this.type = config.type; - this.value = config.value; - this.disabled = config.disabled || false; - this.disableArgs = config.disableArgs || false; - this.placeholder = config.placeholder || false; - this.target = config.target; - this.toggleValues = config.toggleValues; - this.id = "ing-" + this.app.nextIngId(); -}; - - -/** - * Renders the ingredient in HTML. - * - * @returns {string} - */ -HTMLIngredient.prototype.toHtml = function() { - const inline = ( - this.type === "boolean" || - this.type === "number" || - this.type === "option" || - this.type === "shortString" || - this.type === "binaryShortString" - ); - let html = inline ? "" : "
 
", - i, m; - - html += "
"; - - switch (this.type) { - case "string": - case "binaryString": - case "byteArray": - html += ""; - break; - case "shortString": - case "binaryShortString": - html += ""; - break; - case "toggleString": - html += "
\ -
"; - break; - case "number": - html += ""; - break; - case "boolean": - html += ""; - - if (this.disableArgs) { - this.manager.addDynamicListener("#" + this.id, "click", this.toggleDisableArgs, this); - } - break; - case "option": - html += ""; - break; - case "populateOption": - html += ""; - - this.manager.addDynamicListener("#" + this.id, "change", this.populateOptionChange, this); - break; - case "editableOption": - html += "
"; - html += ""; - html += ""; - html += "
"; - - - this.manager.addDynamicListener("#sel-" + this.id, "change", this.editableOptionChange, this); - break; - case "text": - html += ""; - break; - default: - break; - } - html += "
"; - - return html; -}; - - -/** - * Handler for argument disable toggle. - * Toggles disabled state for all arguments in the disableArgs list for this ingredient. - * - * @param {event} e - */ -HTMLIngredient.prototype.toggleDisableArgs = function(e) { - const el = e.target; - const op = el.parentNode.parentNode; - const args = op.querySelectorAll(".arg-group"); - - for (let i = 0; i < this.disableArgs.length; i++) { - const els = args[this.disableArgs[i]].querySelectorAll("input, select, button"); - - for (let j = 0; j < els.length; j++) { - if (els[j].getAttribute("disabled")) { - els[j].removeAttribute("disabled"); - } else { - els[j].setAttribute("disabled", "disabled"); - } - } - } - - this.manager.recipe.ingChange(); -}; - - -/** - * Handler for populate option changes. - * Populates the relevant argument with the specified value. - * - * @param {event} e - */ -HTMLIngredient.prototype.populateOptionChange = function(e) { - const el = e.target; - const op = el.parentNode.parentNode; - const target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea"); - - target.value = el.childNodes[el.selectedIndex].getAttribute("populate-value"); - - this.manager.recipe.ingChange(); -}; - - -/** - * Handler for editable option changes. - * Populates the input box with the selected value. - * - * @param {event} e - */ -HTMLIngredient.prototype.editableOptionChange = function(e) { - const select = e.target, - input = select.nextSibling; - - input.value = select.childNodes[select.selectedIndex].value; - - this.manager.recipe.ingChange(); -}; - -export default HTMLIngredient; diff --git a/src/web/HTMLIngredient.mjs b/src/web/HTMLIngredient.mjs new file mode 100755 index 00000000..2ce3f51f --- /dev/null +++ b/src/web/HTMLIngredient.mjs @@ -0,0 +1,223 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Object to handle the creation of operation ingredients. + */ +class HTMLIngredient { + + /** + * HTMLIngredient constructor. + * + * @param {Object} config - The configuration object for this ingredient. + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(config, app, manager) { + this.app = app; + this.manager = manager; + + this.name = config.name; + this.type = config.type; + this.value = config.value; + this.disabled = config.disabled || false; + this.disableArgs = config.disableArgs || false; + this.placeholder = config.placeholder || false; + this.target = config.target; + this.toggleValues = config.toggleValues; + this.id = "ing-" + this.app.nextIngId(); + } + + + /** + * Renders the ingredient in HTML. + * + * @returns {string} + */ + toHtml() { + const inline = ( + this.type === "boolean" || + this.type === "number" || + this.type === "option" || + this.type === "shortString" || + this.type === "binaryShortString" + ); + let html = inline ? "" : "
 
", + i, m; + + html += "
"; + + switch (this.type) { + case "string": + case "binaryString": + case "byteArray": + html += ""; + break; + case "shortString": + case "binaryShortString": + html += ""; + break; + case "toggleString": + html += "
\ +
"; + break; + case "number": + html += ""; + break; + case "boolean": + html += ""; + + if (this.disableArgs) { + this.manager.addDynamicListener("#" + this.id, "click", this.toggleDisableArgs, this); + } + break; + case "option": + html += ""; + break; + case "populateOption": + html += ""; + + this.manager.addDynamicListener("#" + this.id, "change", this.populateOptionChange, this); + break; + case "editableOption": + html += "
"; + html += ""; + html += ""; + html += "
"; + + + this.manager.addDynamicListener("#sel-" + this.id, "change", this.editableOptionChange, this); + break; + case "text": + html += ""; + break; + default: + break; + } + html += "
"; + + return html; + } + + + /** + * Handler for argument disable toggle. + * Toggles disabled state for all arguments in the disableArgs list for this ingredient. + * + * @param {event} e + */ + toggleDisableArgs(e) { + const el = e.target; + const op = el.parentNode.parentNode; + const args = op.querySelectorAll(".arg-group"); + + for (let i = 0; i < this.disableArgs.length; i++) { + const els = args[this.disableArgs[i]].querySelectorAll("input, select, button"); + + for (let j = 0; j < els.length; j++) { + if (els[j].getAttribute("disabled")) { + els[j].removeAttribute("disabled"); + } else { + els[j].setAttribute("disabled", "disabled"); + } + } + } + + this.manager.recipe.ingChange(); + } + + + /** + * Handler for populate option changes. + * Populates the relevant argument with the specified value. + * + * @param {event} e + */ + populateOptionChange(e) { + const el = e.target; + const op = el.parentNode.parentNode; + const target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea"); + + target.value = el.childNodes[el.selectedIndex].getAttribute("populate-value"); + + this.manager.recipe.ingChange(); + } + + + /** + * Handler for editable option changes. + * Populates the input box with the selected value. + * + * @param {event} e + */ + editableOptionChange(e) { + const select = e.target, + input = select.nextSibling; + + input.value = select.childNodes[select.selectedIndex].value; + + this.manager.recipe.ingChange(); + } + +} + +export default HTMLIngredient; diff --git a/src/web/HTMLOperation.js b/src/web/HTMLOperation.js deleted file mode 100755 index e709066f..00000000 --- a/src/web/HTMLOperation.js +++ /dev/null @@ -1,128 +0,0 @@ -import HTMLIngredient from "./HTMLIngredient.js"; - - -/** - * Object to handle the creation of operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {string} name - The name of the operation. - * @param {Object} config - The configuration object for this operation. - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const HTMLOperation = function(name, config, app, manager) { - this.app = app; - this.manager = manager; - - this.name = name; - this.description = config.description; - this.manualBake = config.manualBake || false; - this.config = config; - this.ingList = []; - - for (let i = 0; i < config.args.length; i++) { - const ing = new HTMLIngredient(config.args[i], this.app, this.manager); - this.ingList.push(ing); - } -}; - - -/** - * @constant - */ -HTMLOperation.INFO_ICON = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByElEQVR4XqVTzWoaYRQ9KZJmoVaS1J1QiYTIuOgqi9lEugguQhYhdGs3hTyAi0CWJTvJIks30ZBNsimUtlqkVLoQCuJsphRriyFjabWtEyf/Rv3iWcwwymTlgQuH851z5hu43wRGkEwmXwCIA4hiGAUAmUQikQbhEHwyGCWVSglVVUW73RYmyKnxjB56ncJ6NpsVxHGrI/ZLuniVb3DIqQmCHnrNkgcggNeSJPlisRgyJR2b737j/TcDsQUPwv6H5NR4BnroZcb6Z16N2PvyX6yna9Z8qp6JQ0Uf0ughmGHWBSAuyzJqrQ7eqKewY/dzE363C71e39LoWQq5wUwul4uzIBoIBHD01RgyrkZ8eDbvwUWnj623v2DHx4qB51IAzLIAXq8XP/7W0bUVVJtXWIk8wvlN364TA+/1IDMLwmWK/Hq3axmhaBdoGLeklm73ElaBYRgIzkyifHIOO4QQJKM3oJcZq6CgaVp0OTyHw9K/kQI4FiyHfdC0n2CWe5ApFosIPZ7C2tNpXpcDOehGyD/FIbd0euhlhllzFxRzC3fydbG4XRYbB9/tQ41n9m1U7l3lyp9LkfygiZeZCoecmtMqj/+Yxn7Od3v0j50qCO3zAAAAAElFTkSuQmCC"; -/** - * @constant - */ -HTMLOperation.REMOVE_ICON = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwklEQVR42qRTPU8CQRB9K2CCMRJ6NTQajOUaqfxIbLCRghhjQixosLAgFNBQ3l8wsabxLxBJbCyVUBiMCVQEQkOEKBbCnefM3p4eohWXzM3uvHlv52b2hG3bmOWZw4yPn1/XQkCQ9wFxcgZZ0QLKpifpN8Z1n1L13griBBjHhYK0nMT4b+wom53ClAAFQacZJ/m8rNfrSOZy0vxJjPP6IJ2WzWYTO6mUwiwtILiJJSHUKVSWkchkZK1WQzQaxU2pVGUglkjIbreLUCiEx0qlStlFCpfPiPstYDtVKJH9ZFI2Gw1FGA6H6LTbCAaDeGu1FJl6UuYjpwTGzucokZW1NfnS66kyfT4fXns9RaZmlgNcuhZQU+jowLzuOK/HgwEW3E5ZlhLXVWKk11P3wNYNWw+HZdA0sUgx1zjGmD05nckx0ilGjBJdUq3fr7K5e8bGf43RdL7fOPSQb4lI8SLbrUfkUIuY32VTI1bJn5BqDnh4Dodt9ryPUDzyD7aquWoKQohl2i9sAbubwPkTcHkP3FHsg+yT+7sN7G0AF3Xg6sHB3onbdgWWKBDQg/BcTuVt51dQA/JrnIcyIu6rmPV3/hJgACPc0BMEYTg+AAAAAElFTkSuQmCC"; - - -/** - * Renders the operation in HTML as a stub operation with no ingredients. - * - * @returns {string} - */ -HTMLOperation.prototype.toStubHtml = function(removeIcon) { - let html = "
  • "; - } - - if (this.description) { - html += ""; - } - - html += "
  • "; - - return html; -}; - - -/** - * Renders the operation in HTML as a full operation with ingredients. - * - * @returns {string} - */ -HTMLOperation.prototype.toFullHtml = function() { - let html = "
    " + this.name + "
    "; - - for (let i = 0; i < this.ingList.length; i++) { - html += this.ingList[i].toHtml(); - } - - html += "
    \ -
    \ -
    "; - - html += "
    \ -
     
    "; - - return html; -}; - - -/** - * Highlights the searched string in the name and description of the operation. - * - * @param {string} searchStr - * @param {number} namePos - The position of the search string in the operation name - * @param {number} descPos - The position of the search string in the operation description - */ -HTMLOperation.prototype.highlightSearchString = function(searchStr, namePos, descPos) { - if (namePos >= 0) { - this.name = this.name.slice(0, namePos) + "" + - this.name.slice(namePos, namePos + searchStr.length) + "" + - this.name.slice(namePos + searchStr.length); - } - - if (this.description && descPos >= 0) { - // Find HTML tag offsets - const re = /<[^>]+>/g; - let match; - while ((match = re.exec(this.description))) { - // If the search string occurs within an HTML tag, return without highlighting it. - if (descPos >= match.index && descPos <= (match.index + match[0].length)) - return; - } - - this.description = this.description.slice(0, descPos) + "" + - this.description.slice(descPos, descPos + searchStr.length) + "" + - this.description.slice(descPos + searchStr.length); - } -}; - -export default HTMLOperation; diff --git a/src/web/HTMLOperation.mjs b/src/web/HTMLOperation.mjs new file mode 100755 index 00000000..5d798308 --- /dev/null +++ b/src/web/HTMLOperation.mjs @@ -0,0 +1,129 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import HTMLIngredient from "./HTMLIngredient"; + +const INFO_ICON = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByElEQVR4XqVTzWoaYRQ9KZJmoVaS1J1QiYTIuOgqi9lEugguQhYhdGs3hTyAi0CWJTvJIks30ZBNsimUtlqkVLoQCuJsphRriyFjabWtEyf/Rv3iWcwwymTlgQuH851z5hu43wRGkEwmXwCIA4hiGAUAmUQikQbhEHwyGCWVSglVVUW73RYmyKnxjB56ncJ6NpsVxHGrI/ZLuniVb3DIqQmCHnrNkgcggNeSJPlisRgyJR2b737j/TcDsQUPwv6H5NR4BnroZcb6Z16N2PvyX6yna9Z8qp6JQ0Uf0ughmGHWBSAuyzJqrQ7eqKewY/dzE363C71e39LoWQq5wUwul4uzIBoIBHD01RgyrkZ8eDbvwUWnj623v2DHx4qB51IAzLIAXq8XP/7W0bUVVJtXWIk8wvlN364TA+/1IDMLwmWK/Hq3axmhaBdoGLeklm73ElaBYRgIzkyifHIOO4QQJKM3oJcZq6CgaVp0OTyHw9K/kQI4FiyHfdC0n2CWe5ApFosIPZ7C2tNpXpcDOehGyD/FIbd0euhlhllzFxRzC3fydbG4XRYbB9/tQ41n9m1U7l3lyp9LkfygiZeZCoecmtMqj/+Yxn7Od3v0j50qCO3zAAAAAElFTkSuQmCC"; +const REMOVE_ICON = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwklEQVR42qRTPU8CQRB9K2CCMRJ6NTQajOUaqfxIbLCRghhjQixosLAgFNBQ3l8wsabxLxBJbCyVUBiMCVQEQkOEKBbCnefM3p4eohWXzM3uvHlv52b2hG3bmOWZw4yPn1/XQkCQ9wFxcgZZ0QLKpifpN8Z1n1L13griBBjHhYK0nMT4b+wom53ClAAFQacZJ/m8rNfrSOZy0vxJjPP6IJ2WzWYTO6mUwiwtILiJJSHUKVSWkchkZK1WQzQaxU2pVGUglkjIbreLUCiEx0qlStlFCpfPiPstYDtVKJH9ZFI2Gw1FGA6H6LTbCAaDeGu1FJl6UuYjpwTGzucokZW1NfnS66kyfT4fXns9RaZmlgNcuhZQU+jowLzuOK/HgwEW3E5ZlhLXVWKk11P3wNYNWw+HZdA0sUgx1zjGmD05nckx0ilGjBJdUq3fr7K5e8bGf43RdL7fOPSQb4lI8SLbrUfkUIuY32VTI1bJn5BqDnh4Dodt9ryPUDzyD7aquWoKQohl2i9sAbubwPkTcHkP3FHsg+yT+7sN7G0AF3Xg6sHB3onbdgWWKBDQg/BcTuVt51dQA/JrnIcyIu6rmPV3/hJgACPc0BMEYTg+AAAAAElFTkSuQmCC"; + + +/** + * Object to handle the creation of operations. + */ +class HTMLOperation { + + /** + * HTMLOperation constructor. + * + * @param {string} name - The name of the operation. + * @param {Object} config - The configuration object for this operation. + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(name, config, app, manager) { + this.app = app; + this.manager = manager; + + this.name = name; + this.description = config.description; + this.manualBake = config.manualBake || false; + this.config = config; + this.ingList = []; + + for (let i = 0; i < config.args.length; i++) { + const ing = new HTMLIngredient(config.args[i], this.app, this.manager); + this.ingList.push(ing); + } + } + + + /** + * Renders the operation in HTML as a stub operation with no ingredients. + * + * @returns {string} + */ + toStubHtml(removeIcon) { + let html = "
  • "; + } + + if (this.description) { + html += ""; + } + + html += "
  • "; + + return html; + } + + + /** + * Renders the operation in HTML as a full operation with ingredients. + * + * @returns {string} + */ + toFullHtml() { + let html = "
    " + this.name + "
    "; + + for (let i = 0; i < this.ingList.length; i++) { + html += this.ingList[i].toHtml(); + } + + html += "
    \ +
    \ +
    "; + + html += "
    \ +
     
    "; + + return html; + } + + + /** + * Highlights the searched string in the name and description of the operation. + * + * @param {string} searchStr + * @param {number} namePos - The position of the search string in the operation name + * @param {number} descPos - The position of the search string in the operation description + */ + highlightSearchString(searchStr, namePos, descPos) { + if (namePos >= 0) { + this.name = this.name.slice(0, namePos) + "" + + this.name.slice(namePos, namePos + searchStr.length) + "" + + this.name.slice(namePos + searchStr.length); + } + + if (this.description && descPos >= 0) { + // Find HTML tag offsets + const re = /<[^>]+>/g; + let match; + while ((match = re.exec(this.description))) { + // If the search string occurs within an HTML tag, return without highlighting it. + if (descPos >= match.index && descPos <= (match.index + match[0].length)) + return; + } + + this.description = this.description.slice(0, descPos) + "" + + this.description.slice(descPos, descPos + searchStr.length) + "" + + this.description.slice(descPos + searchStr.length); + } + } + +} + +export default HTMLOperation; diff --git a/src/web/HighlighterWaiter.js b/src/web/HighlighterWaiter.js deleted file mode 100755 index cfc36128..00000000 --- a/src/web/HighlighterWaiter.js +++ /dev/null @@ -1,461 +0,0 @@ -/** - * Waiter to handle events related to highlighting in CyberChef. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const HighlighterWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - - this.mouseButtonDown = false; - this.mouseTarget = null; -}; - - -/** - * HighlighterWaiter data type enum for the input. - * @readonly - * @enum - */ -HighlighterWaiter.INPUT = 0; -/** - * HighlighterWaiter data type enum for the output. - * @readonly - * @enum - */ -HighlighterWaiter.OUTPUT = 1; - - -/** - * Determines if the current text selection is running backwards or forwards. - * StackOverflow answer id: 12652116 - * - * @private - * @returns {boolean} - */ -HighlighterWaiter.prototype._isSelectionBackwards = function() { - let backwards = false; - const sel = window.getSelection(); - - if (!sel.isCollapsed) { - const range = document.createRange(); - range.setStart(sel.anchorNode, sel.anchorOffset); - range.setEnd(sel.focusNode, sel.focusOffset); - backwards = range.collapsed; - range.detach(); - } - return backwards; -}; - - -/** - * Calculates the text offset of a position in an HTML element, ignoring HTML tags. - * - * @private - * @param {element} node - The parent HTML node. - * @param {number} offset - The offset since the last HTML element. - * @returns {number} - */ -HighlighterWaiter.prototype._getOutputHtmlOffset = function(node, offset) { - const sel = window.getSelection(); - const range = document.createRange(); - - range.selectNodeContents(document.getElementById("output-html")); - range.setEnd(node, offset); - sel.removeAllRanges(); - sel.addRange(range); - - return sel.toString().length; -}; - - -/** - * Gets the current selection offsets in the output HTML, ignoring HTML tags. - * - * @private - * @returns {Object} pos - * @returns {number} pos.start - * @returns {number} pos.end - */ -HighlighterWaiter.prototype._getOutputHtmlSelectionOffsets = function() { - const sel = window.getSelection(); - let range, - start = 0, - end = 0, - backwards = false; - - if (sel.rangeCount) { - range = sel.getRangeAt(sel.rangeCount - 1); - backwards = this._isSelectionBackwards(); - start = this._getOutputHtmlOffset(range.startContainer, range.startOffset); - end = this._getOutputHtmlOffset(range.endContainer, range.endOffset); - sel.removeAllRanges(); - sel.addRange(range); - - if (backwards) { - // If selecting backwards, reverse the start and end offsets for the selection to - // prevent deselecting as the drag continues. - sel.collapseToEnd(); - sel.extend(sel.anchorNode, range.startOffset); - } - } - - return { - start: start, - end: end - }; -}; - - -/** - * Handler for input scroll events. - * Scrolls the highlighter pane to match the input textarea position. - * - * @param {event} e - */ -HighlighterWaiter.prototype.inputScroll = function(e) { - const el = e.target; - document.getElementById("input-highlighter").scrollTop = el.scrollTop; - document.getElementById("input-highlighter").scrollLeft = el.scrollLeft; -}; - - -/** - * Handler for output scroll events. - * Scrolls the highlighter pane to match the output textarea position. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputScroll = function(e) { - const el = e.target; - document.getElementById("output-highlighter").scrollTop = el.scrollTop; - document.getElementById("output-highlighter").scrollLeft = el.scrollLeft; -}; - - -/** - * Handler for input mousedown events. - * Calculates the current selection info, and highlights the corresponding data in the output. - * - * @param {event} e - */ -HighlighterWaiter.prototype.inputMousedown = function(e) { - this.mouseButtonDown = true; - this.mouseTarget = HighlighterWaiter.INPUT; - this.removeHighlights(); - - const el = e.target; - const start = el.selectionStart; - const end = el.selectionEnd; - - if (start !== 0 || end !== 0) { - document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end); - this.highlightOutput([{start: start, end: end}]); - } -}; - - -/** - * Handler for output mousedown events. - * Calculates the current selection info, and highlights the corresponding data in the input. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputMousedown = function(e) { - this.mouseButtonDown = true; - this.mouseTarget = HighlighterWaiter.OUTPUT; - this.removeHighlights(); - - const el = e.target; - const start = el.selectionStart; - const end = el.selectionEnd; - - if (start !== 0 || end !== 0) { - document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end); - this.highlightInput([{start: start, end: end}]); - } -}; - - -/** - * Handler for output HTML mousedown events. - * Calculates the current selection info. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputHtmlMousedown = function(e) { - this.mouseButtonDown = true; - this.mouseTarget = HighlighterWaiter.OUTPUT; - - const sel = this._getOutputHtmlSelectionOffsets(); - if (sel.start !== 0 || sel.end !== 0) { - document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end); - } -}; - - -/** - * Handler for input mouseup events. - * - * @param {event} e - */ -HighlighterWaiter.prototype.inputMouseup = function(e) { - this.mouseButtonDown = false; -}; - - -/** - * Handler for output mouseup events. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputMouseup = function(e) { - this.mouseButtonDown = false; -}; - - -/** - * Handler for output HTML mouseup events. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputHtmlMouseup = function(e) { - this.mouseButtonDown = false; -}; - - -/** - * Handler for input mousemove events. - * Calculates the current selection info, and highlights the corresponding data in the output. - * - * @param {event} e - */ -HighlighterWaiter.prototype.inputMousemove = function(e) { - // Check that the left mouse button is pressed - if (!this.mouseButtonDown || - e.which !== 1 || - this.mouseTarget !== HighlighterWaiter.INPUT) - return; - - const el = e.target; - const start = el.selectionStart; - const end = el.selectionEnd; - - if (start !== 0 || end !== 0) { - document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end); - this.highlightOutput([{start: start, end: end}]); - } -}; - - -/** - * Handler for output mousemove events. - * Calculates the current selection info, and highlights the corresponding data in the input. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputMousemove = function(e) { - // Check that the left mouse button is pressed - if (!this.mouseButtonDown || - e.which !== 1 || - this.mouseTarget !== HighlighterWaiter.OUTPUT) - return; - - const el = e.target; - const start = el.selectionStart; - const end = el.selectionEnd; - - if (start !== 0 || end !== 0) { - document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end); - this.highlightInput([{start: start, end: end}]); - } -}; - - -/** - * Handler for output HTML mousemove events. - * Calculates the current selection info. - * - * @param {event} e - */ -HighlighterWaiter.prototype.outputHtmlMousemove = function(e) { - // Check that the left mouse button is pressed - if (!this.mouseButtonDown || - e.which !== 1 || - this.mouseTarget !== HighlighterWaiter.OUTPUT) - return; - - const sel = this._getOutputHtmlSelectionOffsets(); - if (sel.start !== 0 || sel.end !== 0) { - document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end); - } -}; - - -/** - * Given start and end offsets, writes the HTML for the selection info element with the correct - * padding. - * - * @param {number} start - The start offset. - * @param {number} end - The end offset. - * @returns {string} - */ -HighlighterWaiter.prototype.selectionInfo = function(start, end) { - const len = end.toString().length; - const width = len < 2 ? 2 : len; - const startStr = start.toString().padStart(width, " ").replace(/ /g, " "); - const endStr = end.toString().padStart(width, " ").replace(/ /g, " "); - const lenStr = (end-start).toString().padStart(width, " ").replace(/ /g, " "); - - return "start: " + startStr + "
    end: " + endStr + "
    length: " + lenStr; -}; - - -/** - * Removes highlighting and selection information. - */ -HighlighterWaiter.prototype.removeHighlights = function() { - document.getElementById("input-highlighter").innerHTML = ""; - document.getElementById("output-highlighter").innerHTML = ""; - document.getElementById("input-selection-info").innerHTML = ""; - document.getElementById("output-selection-info").innerHTML = ""; -}; - - -/** - * Highlights the given offsets in the output. - * We will only highlight if: - * - input hasn't changed since last bake - * - last bake was a full bake - * - all operations in the recipe support highlighting - * - * @param {Object} pos - The position object for the highlight. - * @param {number} pos.start - The start offset. - * @param {number} pos.end - The end offset. - */ -HighlighterWaiter.prototype.highlightOutput = function(pos) { - if (!this.app.autoBake_ || this.app.baking) return false; - this.manager.worker.highlight(this.app.getRecipeConfig(), "forward", pos); -}; - - -/** - * Highlights the given offsets in the input. - * We will only highlight if: - * - input hasn't changed since last bake - * - last bake was a full bake - * - all operations in the recipe support highlighting - * - * @param {Object} pos - The position object for the highlight. - * @param {number} pos.start - The start offset. - * @param {number} pos.end - The end offset. - */ -HighlighterWaiter.prototype.highlightInput = function(pos) { - if (!this.app.autoBake_ || this.app.baking) return false; - this.manager.worker.highlight(this.app.getRecipeConfig(), "reverse", pos); -}; - - -/** - * Displays highlight offsets sent back from the Chef. - * - * @param {Object} pos - The position object for the highlight. - * @param {number} pos.start - The start offset. - * @param {number} pos.end - The end offset. - * @param {string} direction - */ -HighlighterWaiter.prototype.displayHighlights = function(pos, direction) { - if (!pos) return; - - const io = direction === "forward" ? "output" : "input"; - - document.getElementById(io + "-selection-info").innerHTML = this.selectionInfo(pos[0].start, pos[0].end); - this.highlight( - document.getElementById(io + "-text"), - document.getElementById(io + "-highlighter"), - pos); -}; - - -/** - * Adds the relevant HTML to the specified highlight element such that highlighting appears - * underneath the correct offset. - * - * @param {element} textarea - The input or output textarea. - * @param {element} highlighter - The input or output highlighter element. - * @param {Object} pos - The position object for the highlight. - * @param {number} pos.start - The start offset. - * @param {number} pos.end - The end offset. - */ -HighlighterWaiter.prototype.highlight = async function(textarea, highlighter, pos) { - if (!this.app.options.showHighlighter) return false; - if (!this.app.options.attemptHighlight) return false; - - // Check if there is a carriage return in the output dish as this will not - // be displayed by the HTML textarea and will mess up highlighting offsets. - if (await this.manager.output.containsCR()) return false; - - const startPlaceholder = "[startHighlight]"; - const startPlaceholderRegex = /\[startHighlight\]/g; - const endPlaceholder = "[endHighlight]"; - const endPlaceholderRegex = /\[endHighlight\]/g; - let text = textarea.value; - - // Put placeholders in position - // If there's only one value, select that - // If there are multiple, ignore the first one and select all others - if (pos.length === 1) { - if (pos[0].end < pos[0].start) return; - text = text.slice(0, pos[0].start) + - startPlaceholder + text.slice(pos[0].start, pos[0].end) + endPlaceholder + - text.slice(pos[0].end, text.length); - } else { - // O(n^2) - Can anyone improve this without overwriting placeholders? - let result = "", - endPlaced = true; - - for (let i = 0; i < text.length; i++) { - for (let j = 1; j < pos.length; j++) { - if (pos[j].end < pos[j].start) continue; - if (pos[j].start === i) { - result += startPlaceholder; - endPlaced = false; - } - if (pos[j].end === i) { - result += endPlaceholder; - endPlaced = true; - } - } - result += text[i]; - } - if (!endPlaced) result += endPlaceholder; - text = result; - } - - const cssClass = "hl1"; - //if (colour) cssClass += "-"+colour; - - // Remove HTML tags - text = text - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/\n/g, " ") - // Convert placeholders to tags - .replace(startPlaceholderRegex, "") - .replace(endPlaceholderRegex, "") + " "; - - // Adjust width to allow for scrollbars - highlighter.style.width = textarea.clientWidth + "px"; - highlighter.innerHTML = text; - highlighter.scrollTop = textarea.scrollTop; - highlighter.scrollLeft = textarea.scrollLeft; -}; - -export default HighlighterWaiter; diff --git a/src/web/HighlighterWaiter.mjs b/src/web/HighlighterWaiter.mjs new file mode 100755 index 00000000..99ae10b1 --- /dev/null +++ b/src/web/HighlighterWaiter.mjs @@ -0,0 +1,468 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * HighlighterWaiter data type enum for the input. + * @enum + */ +const INPUT = 0; + +/** + * HighlighterWaiter data type enum for the output. + * @enum + */ +const OUTPUT = 1; + + +/** + * Waiter to handle events related to highlighting in CyberChef. + */ +class HighlighterWaiter { + + /** + * HighlighterWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + + this.mouseButtonDown = false; + this.mouseTarget = null; + } + + + /** + * Determines if the current text selection is running backwards or forwards. + * StackOverflow answer id: 12652116 + * + * @private + * @returns {boolean} + */ + _isSelectionBackwards() { + let backwards = false; + const sel = window.getSelection(); + + if (!sel.isCollapsed) { + const range = document.createRange(); + range.setStart(sel.anchorNode, sel.anchorOffset); + range.setEnd(sel.focusNode, sel.focusOffset); + backwards = range.collapsed; + range.detach(); + } + return backwards; + } + + + /** + * Calculates the text offset of a position in an HTML element, ignoring HTML tags. + * + * @private + * @param {element} node - The parent HTML node. + * @param {number} offset - The offset since the last HTML element. + * @returns {number} + */ + _getOutputHtmlOffset(node, offset) { + const sel = window.getSelection(); + const range = document.createRange(); + + range.selectNodeContents(document.getElementById("output-html")); + range.setEnd(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + + return sel.toString().length; + } + + + /** + * Gets the current selection offsets in the output HTML, ignoring HTML tags. + * + * @private + * @returns {Object} pos + * @returns {number} pos.start + * @returns {number} pos.end + */ + _getOutputHtmlSelectionOffsets() { + const sel = window.getSelection(); + let range, + start = 0, + end = 0, + backwards = false; + + if (sel.rangeCount) { + range = sel.getRangeAt(sel.rangeCount - 1); + backwards = this._isSelectionBackwards(); + start = this._getOutputHtmlOffset(range.startContainer, range.startOffset); + end = this._getOutputHtmlOffset(range.endContainer, range.endOffset); + sel.removeAllRanges(); + sel.addRange(range); + + if (backwards) { + // If selecting backwards, reverse the start and end offsets for the selection to + // prevent deselecting as the drag continues. + sel.collapseToEnd(); + sel.extend(sel.anchorNode, range.startOffset); + } + } + + return { + start: start, + end: end + }; + } + + + /** + * Handler for input scroll events. + * Scrolls the highlighter pane to match the input textarea position. + * + * @param {event} e + */ + inputScroll(e) { + const el = e.target; + document.getElementById("input-highlighter").scrollTop = el.scrollTop; + document.getElementById("input-highlighter").scrollLeft = el.scrollLeft; + } + + + /** + * Handler for output scroll events. + * Scrolls the highlighter pane to match the output textarea position. + * + * @param {event} e + */ + outputScroll(e) { + const el = e.target; + document.getElementById("output-highlighter").scrollTop = el.scrollTop; + document.getElementById("output-highlighter").scrollLeft = el.scrollLeft; + } + + + /** + * Handler for input mousedown events. + * Calculates the current selection info, and highlights the corresponding data in the output. + * + * @param {event} e + */ + inputMousedown(e) { + this.mouseButtonDown = true; + this.mouseTarget = INPUT; + this.removeHighlights(); + + const el = e.target; + const start = el.selectionStart; + const end = el.selectionEnd; + + if (start !== 0 || end !== 0) { + document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end); + this.highlightOutput([{start: start, end: end}]); + } + } + + + /** + * Handler for output mousedown events. + * Calculates the current selection info, and highlights the corresponding data in the input. + * + * @param {event} e + */ + outputMousedown(e) { + this.mouseButtonDown = true; + this.mouseTarget = OUTPUT; + this.removeHighlights(); + + const el = e.target; + const start = el.selectionStart; + const end = el.selectionEnd; + + if (start !== 0 || end !== 0) { + document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end); + this.highlightInput([{start: start, end: end}]); + } + } + + + /** + * Handler for output HTML mousedown events. + * Calculates the current selection info. + * + * @param {event} e + */ + outputHtmlMousedown(e) { + this.mouseButtonDown = true; + this.mouseTarget = OUTPUT; + + const sel = this._getOutputHtmlSelectionOffsets(); + if (sel.start !== 0 || sel.end !== 0) { + document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end); + } + } + + + /** + * Handler for input mouseup events. + * + * @param {event} e + */ + inputMouseup(e) { + this.mouseButtonDown = false; + } + + + /** + * Handler for output mouseup events. + * + * @param {event} e + */ + outputMouseup(e) { + this.mouseButtonDown = false; + } + + + /** + * Handler for output HTML mouseup events. + * + * @param {event} e + */ + outputHtmlMouseup(e) { + this.mouseButtonDown = false; + } + + + /** + * Handler for input mousemove events. + * Calculates the current selection info, and highlights the corresponding data in the output. + * + * @param {event} e + */ + inputMousemove(e) { + // Check that the left mouse button is pressed + if (!this.mouseButtonDown || + e.which !== 1 || + this.mouseTarget !== INPUT) + return; + + const el = e.target; + const start = el.selectionStart; + const end = el.selectionEnd; + + if (start !== 0 || end !== 0) { + document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end); + this.highlightOutput([{start: start, end: end}]); + } + } + + + /** + * Handler for output mousemove events. + * Calculates the current selection info, and highlights the corresponding data in the input. + * + * @param {event} e + */ + outputMousemove(e) { + // Check that the left mouse button is pressed + if (!this.mouseButtonDown || + e.which !== 1 || + this.mouseTarget !== OUTPUT) + return; + + const el = e.target; + const start = el.selectionStart; + const end = el.selectionEnd; + + if (start !== 0 || end !== 0) { + document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end); + this.highlightInput([{start: start, end: end}]); + } + } + + + /** + * Handler for output HTML mousemove events. + * Calculates the current selection info. + * + * @param {event} e + */ + outputHtmlMousemove(e) { + // Check that the left mouse button is pressed + if (!this.mouseButtonDown || + e.which !== 1 || + this.mouseTarget !== OUTPUT) + return; + + const sel = this._getOutputHtmlSelectionOffsets(); + if (sel.start !== 0 || sel.end !== 0) { + document.getElementById("output-selection-info").innerHTML = this.selectionInfo(sel.start, sel.end); + } + } + + + /** + * Given start and end offsets, writes the HTML for the selection info element with the correct + * padding. + * + * @param {number} start - The start offset. + * @param {number} end - The end offset. + * @returns {string} + */ + selectionInfo(start, end) { + const len = end.toString().length; + const width = len < 2 ? 2 : len; + const startStr = start.toString().padStart(width, " ").replace(/ /g, " "); + const endStr = end.toString().padStart(width, " ").replace(/ /g, " "); + const lenStr = (end-start).toString().padStart(width, " ").replace(/ /g, " "); + + return "start: " + startStr + "
    end: " + endStr + "
    length: " + lenStr; + } + + + /** + * Removes highlighting and selection information. + */ + removeHighlights() { + document.getElementById("input-highlighter").innerHTML = ""; + document.getElementById("output-highlighter").innerHTML = ""; + document.getElementById("input-selection-info").innerHTML = ""; + document.getElementById("output-selection-info").innerHTML = ""; + } + + + /** + * Highlights the given offsets in the output. + * We will only highlight if: + * - input hasn't changed since last bake + * - last bake was a full bake + * - all operations in the recipe support highlighting + * + * @param {Object} pos - The position object for the highlight. + * @param {number} pos.start - The start offset. + * @param {number} pos.end - The end offset. + */ + highlightOutput(pos) { + if (!this.app.autoBake_ || this.app.baking) return false; + this.manager.worker.highlight(this.app.getRecipeConfig(), "forward", pos); + } + + + /** + * Highlights the given offsets in the input. + * We will only highlight if: + * - input hasn't changed since last bake + * - last bake was a full bake + * - all operations in the recipe support highlighting + * + * @param {Object} pos - The position object for the highlight. + * @param {number} pos.start - The start offset. + * @param {number} pos.end - The end offset. + */ + highlightInput(pos) { + if (!this.app.autoBake_ || this.app.baking) return false; + this.manager.worker.highlight(this.app.getRecipeConfig(), "reverse", pos); + } + + + /** + * Displays highlight offsets sent back from the Chef. + * + * @param {Object} pos - The position object for the highlight. + * @param {number} pos.start - The start offset. + * @param {number} pos.end - The end offset. + * @param {string} direction + */ + displayHighlights(pos, direction) { + if (!pos) return; + + const io = direction === "forward" ? "output" : "input"; + + document.getElementById(io + "-selection-info").innerHTML = this.selectionInfo(pos[0].start, pos[0].end); + this.highlight( + document.getElementById(io + "-text"), + document.getElementById(io + "-highlighter"), + pos); + } + + + /** + * Adds the relevant HTML to the specified highlight element such that highlighting appears + * underneath the correct offset. + * + * @param {element} textarea - The input or output textarea. + * @param {element} highlighter - The input or output highlighter element. + * @param {Object} pos - The position object for the highlight. + * @param {number} pos.start - The start offset. + * @param {number} pos.end - The end offset. + */ + async highlight(textarea, highlighter, pos) { + if (!this.app.options.showHighlighter) return false; + if (!this.app.options.attemptHighlight) return false; + + // Check if there is a carriage return in the output dish as this will not + // be displayed by the HTML textarea and will mess up highlighting offsets. + if (await this.manager.output.containsCR()) return false; + + const startPlaceholder = "[startHighlight]"; + const startPlaceholderRegex = /\[startHighlight\]/g; + const endPlaceholder = "[endHighlight]"; + const endPlaceholderRegex = /\[endHighlight\]/g; + let text = textarea.value; + + // Put placeholders in position + // If there's only one value, select that + // If there are multiple, ignore the first one and select all others + if (pos.length === 1) { + if (pos[0].end < pos[0].start) return; + text = text.slice(0, pos[0].start) + + startPlaceholder + text.slice(pos[0].start, pos[0].end) + endPlaceholder + + text.slice(pos[0].end, text.length); + } else { + // O(n^2) - Can anyone improve this without overwriting placeholders? + let result = "", + endPlaced = true; + + for (let i = 0; i < text.length; i++) { + for (let j = 1; j < pos.length; j++) { + if (pos[j].end < pos[j].start) continue; + if (pos[j].start === i) { + result += startPlaceholder; + endPlaced = false; + } + if (pos[j].end === i) { + result += endPlaceholder; + endPlaced = true; + } + } + result += text[i]; + } + if (!endPlaced) result += endPlaceholder; + text = result; + } + + const cssClass = "hl1"; + //if (colour) cssClass += "-"+colour; + + // Remove HTML tags + text = text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/\n/g, " ") + // Convert placeholders to tags + .replace(startPlaceholderRegex, "") + .replace(endPlaceholderRegex, "") + " "; + + // Adjust width to allow for scrollbars + highlighter.style.width = textarea.clientWidth + "px"; + highlighter.innerHTML = text; + highlighter.scrollTop = textarea.scrollTop; + highlighter.scrollLeft = textarea.scrollLeft; + } + +} + +export default HighlighterWaiter; diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js deleted file mode 100755 index d0b648ec..00000000 --- a/src/web/InputWaiter.js +++ /dev/null @@ -1,321 +0,0 @@ -import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker.js"; -import Utils from "../core/Utils"; - - -/** - * Waiter to handle events related to the input. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const InputWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - - // Define keys that don't change the input so we don't have to autobake when they are pressed - this.badKeys = [ - 16, //Shift - 17, //Ctrl - 18, //Alt - 19, //Pause - 20, //Caps - 27, //Esc - 33, 34, 35, 36, //PgUp, PgDn, End, Home - 37, 38, 39, 40, //Directional - 44, //PrntScrn - 91, 92, //Win - 93, //Context - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, //F1-12 - 144, //Num - 145, //Scroll - ]; - - this.loaderWorker = null; - this.fileBuffer = null; -}; - - -/** - * Gets the user's input from the input textarea. - * - * @returns {string} - */ -InputWaiter.prototype.get = function() { - return this.fileBuffer || document.getElementById("input-text").value; -}; - - -/** - * Sets the input in the input area. - * - * @param {string|File} input - * - * @fires Manager#statechange - */ -InputWaiter.prototype.set = function(input) { - const inputText = document.getElementById("input-text"); - if (input instanceof File) { - this.setFile(input); - inputText.value = ""; - this.setInputInfo(input.size, null); - } else { - inputText.value = input; - this.closeFile(); - window.dispatchEvent(this.manager.statechange); - const lines = input.length < (this.app.options.ioDisplayThreshold * 1024) ? - input.count("\n") + 1 : null; - this.setInputInfo(input.length, lines); - } -}; - - -/** - * Shows file details. - * - * @param {File} file - */ -InputWaiter.prototype.setFile = function(file) { - // Display file overlay in input area with details - const fileOverlay = document.getElementById("input-file"), - fileName = document.getElementById("input-file-name"), - fileSize = document.getElementById("input-file-size"), - fileType = document.getElementById("input-file-type"), - fileLoaded = document.getElementById("input-file-loaded"); - - this.fileBuffer = new ArrayBuffer(); - fileOverlay.style.display = "block"; - fileName.textContent = file.name; - fileSize.textContent = file.size.toLocaleString() + " bytes"; - fileType.textContent = file.type || "unknown"; - fileLoaded.textContent = "0%"; -}; - - -/** - * Displays information about the input. - * - * @param {number} length - The length of the current input string - * @param {number} lines - The number of the lines in the current input string - */ -InputWaiter.prototype.setInputInfo = function(length, lines) { - let width = length.toString().length; - width = width < 2 ? 2 : width; - - const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); - let msg = "length: " + lengthStr; - - if (typeof lines === "number") { - const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); - msg += "
    lines: " + linesStr; - } - - document.getElementById("input-info").innerHTML = msg; -}; - - -/** - * Handler for input change events. - * - * @param {event} e - * - * @fires Manager#statechange - */ -InputWaiter.prototype.inputChange = function(e) { - // Ignore this function if the input is a File - if (this.fileBuffer) return; - - // Remove highlighting from input and output panes as the offsets might be different now - this.manager.highlighter.removeHighlights(); - - // Reset recipe progress as any previous processing will be redundant now - this.app.progress = 0; - - // Update the input metadata info - const inputText = this.get(); - const lines = inputText.length < (this.app.options.ioDisplayThreshold * 1024) ? - inputText.count("\n") + 1 : null; - - this.setInputInfo(inputText.length, lines); - - if (e && this.badKeys.indexOf(e.keyCode) < 0) { - // Fire the statechange event as the input has been modified - window.dispatchEvent(this.manager.statechange); - } -}; - - -/** - * Handler for input paste events. - * Checks that the size of the input is below the display limit, otherwise treats it as a file/blob. - * - * @param {event} e - */ -InputWaiter.prototype.inputPaste = function(e) { - const pastedData = e.clipboardData.getData("Text"); - - if (pastedData.length < (this.app.options.ioDisplayThreshold * 1024)) { - this.inputChange(e); - } else { - e.preventDefault(); - e.stopPropagation(); - - const file = new File([pastedData], "PastedData", { - type: "text/plain", - lastModified: Date.now() - }); - - this.loaderWorker = new LoaderWorker(); - this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); - this.loaderWorker.postMessage({"file": file}); - this.set(file); - return false; - } -}; - - -/** - * Handler for input dragover events. - * Gives the user a visual cue to show that items can be dropped here. - * - * @param {event} e - */ -InputWaiter.prototype.inputDragover = function(e) { - // This will be set if we're dragging an operation - if (e.dataTransfer.effectAllowed === "move") - return false; - - e.stopPropagation(); - e.preventDefault(); - e.target.closest("#input-text,#input-file").classList.add("dropping-file"); -}; - - -/** - * Handler for input dragleave events. - * Removes the visual cue. - * - * @param {event} e - */ -InputWaiter.prototype.inputDragleave = function(e) { - e.stopPropagation(); - e.preventDefault(); - document.getElementById("input-text").classList.remove("dropping-file"); - document.getElementById("input-file").classList.remove("dropping-file"); -}; - - -/** - * Handler for input drop events. - * Loads the dragged data into the input textarea. - * - * @param {event} e - */ -InputWaiter.prototype.inputDrop = function(e) { - // This will be set if we're dragging an operation - if (e.dataTransfer.effectAllowed === "move") - return false; - - e.stopPropagation(); - e.preventDefault(); - - const file = e.dataTransfer.files[0]; - const text = e.dataTransfer.getData("Text"); - - document.getElementById("input-text").classList.remove("dropping-file"); - document.getElementById("input-file").classList.remove("dropping-file"); - - if (text) { - this.closeFile(); - this.set(text); - return; - } - - if (file) { - this.closeFile(); - this.loaderWorker = new LoaderWorker(); - this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); - this.loaderWorker.postMessage({"file": file}); - this.set(file); - } -}; - - -/** - * Handler for messages sent back by the LoaderWorker. - * - * @param {MessageEvent} e - */ -InputWaiter.prototype.handleLoaderMessage = function(e) { - const r = e.data; - if (r.hasOwnProperty("progress")) { - const fileLoaded = document.getElementById("input-file-loaded"); - fileLoaded.textContent = r.progress + "%"; - } - - if (r.hasOwnProperty("error")) { - this.app.alert(r.error, "danger", 10000); - } - - if (r.hasOwnProperty("fileBuffer")) { - log.debug("Input file loaded"); - this.fileBuffer = r.fileBuffer; - this.displayFilePreview(); - window.dispatchEvent(this.manager.statechange); - } -}; - - -/** - * Shows a chunk of the file in the input behind the file overlay. - */ -InputWaiter.prototype.displayFilePreview = function() { - const inputText = document.getElementById("input-text"), - fileSlice = this.fileBuffer.slice(0, 4096); - - inputText.style.overflow = "hidden"; - inputText.classList.add("blur"); - inputText.value = Utils.printable(Utils.arrayBufferToStr(fileSlice)); - if (this.fileBuffer.byteLength > 4096) { - inputText.value += "[truncated]..."; - } -}; - - -/** - * Handler for file close events. - */ -InputWaiter.prototype.closeFile = function() { - if (this.loaderWorker) this.loaderWorker.terminate(); - this.fileBuffer = null; - document.getElementById("input-file").style.display = "none"; - const inputText = document.getElementById("input-text"); - inputText.style.overflow = "auto"; - inputText.classList.remove("blur"); -}; - - -/** - * Handler for clear IO events. - * Resets the input, output and info areas. - * - * @fires Manager#statechange - */ -InputWaiter.prototype.clearIoClick = function() { - this.closeFile(); - this.manager.output.closeFile(); - this.manager.highlighter.removeHighlights(); - document.getElementById("input-text").value = ""; - document.getElementById("output-text").value = ""; - document.getElementById("input-info").innerHTML = ""; - document.getElementById("output-info").innerHTML = ""; - document.getElementById("input-selection-info").innerHTML = ""; - document.getElementById("output-selection-info").innerHTML = ""; - window.dispatchEvent(this.manager.statechange); -}; - -export default InputWaiter; diff --git a/src/web/InputWaiter.mjs b/src/web/InputWaiter.mjs new file mode 100755 index 00000000..f1728527 --- /dev/null +++ b/src/web/InputWaiter.mjs @@ -0,0 +1,329 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker"; +import Utils from "../core/Utils"; + + +/** + * Waiter to handle events related to the input. + */ +class InputWaiter { + + /** + * InputWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + + // Define keys that don't change the input so we don't have to autobake when they are pressed + this.badKeys = [ + 16, //Shift + 17, //Ctrl + 18, //Alt + 19, //Pause + 20, //Caps + 27, //Esc + 33, 34, 35, 36, //PgUp, PgDn, End, Home + 37, 38, 39, 40, //Directional + 44, //PrntScrn + 91, 92, //Win + 93, //Context + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, //F1-12 + 144, //Num + 145, //Scroll + ]; + + this.loaderWorker = null; + this.fileBuffer = null; + } + + + /** + * Gets the user's input from the input textarea. + * + * @returns {string} + */ + get() { + return this.fileBuffer || document.getElementById("input-text").value; + } + + + /** + * Sets the input in the input area. + * + * @param {string|File} input + * + * @fires Manager#statechange + */ + set(input) { + const inputText = document.getElementById("input-text"); + if (input instanceof File) { + this.setFile(input); + inputText.value = ""; + this.setInputInfo(input.size, null); + } else { + inputText.value = input; + this.closeFile(); + window.dispatchEvent(this.manager.statechange); + const lines = input.length < (this.app.options.ioDisplayThreshold * 1024) ? + input.count("\n") + 1 : null; + this.setInputInfo(input.length, lines); + } + } + + + /** + * Shows file details. + * + * @param {File} file + */ + setFile(file) { + // Display file overlay in input area with details + const fileOverlay = document.getElementById("input-file"), + fileName = document.getElementById("input-file-name"), + fileSize = document.getElementById("input-file-size"), + fileType = document.getElementById("input-file-type"), + fileLoaded = document.getElementById("input-file-loaded"); + + this.fileBuffer = new ArrayBuffer(); + fileOverlay.style.display = "block"; + fileName.textContent = file.name; + fileSize.textContent = file.size.toLocaleString() + " bytes"; + fileType.textContent = file.type || "unknown"; + fileLoaded.textContent = "0%"; + } + + + /** + * Displays information about the input. + * + * @param {number} length - The length of the current input string + * @param {number} lines - The number of the lines in the current input string + */ + setInputInfo(length, lines) { + let width = length.toString().length; + width = width < 2 ? 2 : width; + + const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); + let msg = "length: " + lengthStr; + + if (typeof lines === "number") { + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); + msg += "
    lines: " + linesStr; + } + + document.getElementById("input-info").innerHTML = msg; + } + + + /** + * Handler for input change events. + * + * @param {event} e + * + * @fires Manager#statechange + */ + inputChange(e) { + // Ignore this function if the input is a File + if (this.fileBuffer) return; + + // Remove highlighting from input and output panes as the offsets might be different now + this.manager.highlighter.removeHighlights(); + + // Reset recipe progress as any previous processing will be redundant now + this.app.progress = 0; + + // Update the input metadata info + const inputText = this.get(); + const lines = inputText.length < (this.app.options.ioDisplayThreshold * 1024) ? + inputText.count("\n") + 1 : null; + + this.setInputInfo(inputText.length, lines); + + if (e && this.badKeys.indexOf(e.keyCode) < 0) { + // Fire the statechange event as the input has been modified + window.dispatchEvent(this.manager.statechange); + } + } + + + /** + * Handler for input paste events. + * Checks that the size of the input is below the display limit, otherwise treats it as a file/blob. + * + * @param {event} e + */ + inputPaste(e) { + const pastedData = e.clipboardData.getData("Text"); + + if (pastedData.length < (this.app.options.ioDisplayThreshold * 1024)) { + this.inputChange(e); + } else { + e.preventDefault(); + e.stopPropagation(); + + const file = new File([pastedData], "PastedData", { + type: "text/plain", + lastModified: Date.now() + }); + + this.loaderWorker = new LoaderWorker(); + this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); + this.loaderWorker.postMessage({"file": file}); + this.set(file); + return false; + } + } + + + /** + * Handler for input dragover events. + * Gives the user a visual cue to show that items can be dropped here. + * + * @param {event} e + */ + inputDragover(e) { + // This will be set if we're dragging an operation + if (e.dataTransfer.effectAllowed === "move") + return false; + + e.stopPropagation(); + e.preventDefault(); + e.target.closest("#input-text,#input-file").classList.add("dropping-file"); + } + + + /** + * Handler for input dragleave events. + * Removes the visual cue. + * + * @param {event} e + */ + inputDragleave(e) { + e.stopPropagation(); + e.preventDefault(); + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); + } + + + /** + * Handler for input drop events. + * Loads the dragged data into the input textarea. + * + * @param {event} e + */ + inputDrop(e) { + // This will be set if we're dragging an operation + if (e.dataTransfer.effectAllowed === "move") + return false; + + e.stopPropagation(); + e.preventDefault(); + + const file = e.dataTransfer.files[0]; + const text = e.dataTransfer.getData("Text"); + + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); + + if (text) { + this.closeFile(); + this.set(text); + return; + } + + if (file) { + this.closeFile(); + this.loaderWorker = new LoaderWorker(); + this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); + this.loaderWorker.postMessage({"file": file}); + this.set(file); + } + } + + + /** + * Handler for messages sent back by the LoaderWorker. + * + * @param {MessageEvent} e + */ + handleLoaderMessage(e) { + const r = e.data; + if (r.hasOwnProperty("progress")) { + const fileLoaded = document.getElementById("input-file-loaded"); + fileLoaded.textContent = r.progress + "%"; + } + + if (r.hasOwnProperty("error")) { + this.app.alert(r.error, "danger", 10000); + } + + if (r.hasOwnProperty("fileBuffer")) { + log.debug("Input file loaded"); + this.fileBuffer = r.fileBuffer; + this.displayFilePreview(); + window.dispatchEvent(this.manager.statechange); + } + } + + + /** + * Shows a chunk of the file in the input behind the file overlay. + */ + displayFilePreview() { + const inputText = document.getElementById("input-text"), + fileSlice = this.fileBuffer.slice(0, 4096); + + inputText.style.overflow = "hidden"; + inputText.classList.add("blur"); + inputText.value = Utils.printable(Utils.arrayBufferToStr(fileSlice)); + if (this.fileBuffer.byteLength > 4096) { + inputText.value += "[truncated]..."; + } + } + + + /** + * Handler for file close events. + */ + closeFile() { + if (this.loaderWorker) this.loaderWorker.terminate(); + this.fileBuffer = null; + document.getElementById("input-file").style.display = "none"; + const inputText = document.getElementById("input-text"); + inputText.style.overflow = "auto"; + inputText.classList.remove("blur"); + } + + + /** + * Handler for clear IO events. + * Resets the input, output and info areas. + * + * @fires Manager#statechange + */ + clearIoClick() { + this.closeFile(); + this.manager.output.closeFile(); + this.manager.highlighter.removeHighlights(); + document.getElementById("input-text").value = ""; + document.getElementById("output-text").value = ""; + document.getElementById("input-info").innerHTML = ""; + document.getElementById("output-info").innerHTML = ""; + document.getElementById("input-selection-info").innerHTML = ""; + document.getElementById("output-selection-info").innerHTML = ""; + window.dispatchEvent(this.manager.statechange); + } + +} + +export default InputWaiter; diff --git a/src/web/Manager.js b/src/web/Manager.js deleted file mode 100755 index 8e5e7374..00000000 --- a/src/web/Manager.js +++ /dev/null @@ -1,299 +0,0 @@ -import WorkerWaiter from "./WorkerWaiter.js"; -import WindowWaiter from "./WindowWaiter.js"; -import ControlsWaiter from "./ControlsWaiter.js"; -import RecipeWaiter from "./RecipeWaiter.js"; -import OperationsWaiter from "./OperationsWaiter.js"; -import InputWaiter from "./InputWaiter.js"; -import OutputWaiter from "./OutputWaiter.js"; -import OptionsWaiter from "./OptionsWaiter.js"; -import HighlighterWaiter from "./HighlighterWaiter.js"; -import SeasonalWaiter from "./SeasonalWaiter.js"; -import BindingsWaiter from "./BindingsWaiter.js"; - - -/** - * This object controls the Waiters responsible for handling events from all areas of the app. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - */ -const Manager = function(app) { - this.app = app; - - // Define custom events - /** - * @event Manager#appstart - */ - this.appstart = new CustomEvent("appstart", {bubbles: true}); - /** - * @event Manager#apploaded - */ - this.apploaded = new CustomEvent("apploaded", {bubbles: true}); - /** - * @event Manager#operationadd - */ - this.operationadd = new CustomEvent("operationadd", {bubbles: true}); - /** - * @event Manager#operationremove - */ - this.operationremove = new CustomEvent("operationremove", {bubbles: true}); - /** - * @event Manager#oplistcreate - */ - this.oplistcreate = new CustomEvent("oplistcreate", {bubbles: true}); - /** - * @event Manager#statechange - */ - this.statechange = new CustomEvent("statechange", {bubbles: true}); - - // Define Waiter objects to handle various areas - this.worker = new WorkerWaiter(this.app, this); - this.window = new WindowWaiter(this.app); - this.controls = new ControlsWaiter(this.app, this); - this.recipe = new RecipeWaiter(this.app, this); - this.ops = new OperationsWaiter(this.app, this); - this.input = new InputWaiter(this.app, this); - this.output = new OutputWaiter(this.app, this); - this.options = new OptionsWaiter(this.app, this); - this.highlighter = new HighlighterWaiter(this.app, this); - this.seasonal = new SeasonalWaiter(this.app, this); - this.bindings = new BindingsWaiter(this.app, this); - - // Object to store dynamic handlers to fire on elements that may not exist yet - this.dynamicHandlers = {}; - - this.initialiseEventListeners(); -}; - - -/** - * Sets up the various components and listeners. - */ -Manager.prototype.setup = function() { - this.worker.registerChefWorker(); - this.recipe.initialiseOperationDragNDrop(); - this.controls.autoBakeChange(); - this.bindings.updateKeybList(); - this.seasonal.load(); -}; - - -/** - * Main function to handle the creation of the event listeners. - */ -Manager.prototype.initialiseEventListeners = function() { - // Global - window.addEventListener("resize", this.window.windowResize.bind(this.window)); - window.addEventListener("blur", this.window.windowBlur.bind(this.window)); - window.addEventListener("focus", this.window.windowFocus.bind(this.window)); - window.addEventListener("statechange", this.app.stateChange.bind(this.app)); - window.addEventListener("popstate", this.app.popState.bind(this.app)); - - // Controls - document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls)); - document.getElementById("auto-bake").addEventListener("change", this.controls.autoBakeChange.bind(this.controls)); - document.getElementById("step").addEventListener("click", this.controls.stepClick.bind(this.controls)); - document.getElementById("clr-recipe").addEventListener("click", this.controls.clearRecipeClick.bind(this.controls)); - document.getElementById("clr-breaks").addEventListener("click", this.controls.clearBreaksClick.bind(this.controls)); - document.getElementById("save").addEventListener("click", this.controls.saveClick.bind(this.controls)); - document.getElementById("save-button").addEventListener("click", this.controls.saveButtonClick.bind(this.controls)); - document.getElementById("save-link-recipe-checkbox").addEventListener("change", this.controls.slrCheckChange.bind(this.controls)); - document.getElementById("save-link-input-checkbox").addEventListener("change", this.controls.sliCheckChange.bind(this.controls)); - document.getElementById("load").addEventListener("click", this.controls.loadClick.bind(this.controls)); - document.getElementById("load-delete-button").addEventListener("click", this.controls.loadDeleteClick.bind(this.controls)); - document.getElementById("load-name").addEventListener("change", this.controls.loadNameChange.bind(this.controls)); - document.getElementById("load-button").addEventListener("click", this.controls.loadButtonClick.bind(this.controls)); - document.getElementById("support").addEventListener("click", this.controls.supportButtonClick.bind(this.controls)); - this.addMultiEventListeners("#save-texts textarea", "keyup paste", this.controls.saveTextChange, this.controls); - - // Operations - this.addMultiEventListener("#search", "keyup paste search", this.ops.searchOperations, this.ops); - this.addDynamicListener(".op-list li.operation", "dblclick", this.ops.operationDblclick, this.ops); - document.getElementById("edit-favourites").addEventListener("click", this.ops.editFavouritesClick.bind(this.ops)); - document.getElementById("save-favourites").addEventListener("click", this.ops.saveFavouritesClick.bind(this.ops)); - document.getElementById("reset-favourites").addEventListener("click", this.ops.resetFavouritesClick.bind(this.ops)); - this.addDynamicListener(".op-list .op-icon", "mouseover", this.ops.opIconMouseover, this.ops); - this.addDynamicListener(".op-list .op-icon", "mouseleave", this.ops.opIconMouseleave, this.ops); - this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops); - this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd, this.recipe); - - // Recipe - this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe); - this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe); - this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe); - this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe); - this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe); - this.addDynamicListener("#rec-list li.operation > div", "dblclick", this.recipe.operationChildDblclick, this.recipe); - this.addDynamicListener("#rec-list .input-group .dropdown-menu a", "click", this.recipe.dropdownToggleClick, this.recipe); - this.addDynamicListener("#rec-list", "operationremove", this.recipe.opRemove.bind(this.recipe)); - - // Input - this.addMultiEventListener("#input-text", "keyup", this.input.inputChange, this.input); - this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input); - document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app)); - document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input)); - this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input); - this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input); - this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input); - document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter)); - document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter)); - document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter)); - this.addMultiEventListener("#input-text", "mousedown dblclick select", this.highlighter.inputMousedown, this.highlighter); - document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input)); - - // Output - document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); - document.getElementById("copy-output").addEventListener("click", this.output.copyClick.bind(this.output)); - document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output)); - document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output)); - document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output)); - document.getElementById("output-text").addEventListener("scroll", this.highlighter.outputScroll.bind(this.highlighter)); - document.getElementById("output-text").addEventListener("mouseup", this.highlighter.outputMouseup.bind(this.highlighter)); - document.getElementById("output-text").addEventListener("mousemove", this.highlighter.outputMousemove.bind(this.highlighter)); - document.getElementById("output-html").addEventListener("mouseup", this.highlighter.outputHtmlMouseup.bind(this.highlighter)); - document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter)); - this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter); - this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); - this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); - this.addDynamicListener("#output-file-slice", "click", this.output.displayFileSlice, this.output); - document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output)); - - // Options - document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); - document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options)); - $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options)); - $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options)); - $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings)); - this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options); - this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options); - this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options); - document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options)); - document.getElementById("logLevel").addEventListener("change", this.options.logLevelChange.bind(this.options)); - - // Misc - window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); - document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app)); -}; - - -/** - * Adds an event listener to each element in the specified group. - * - * @param {string} selector - A selector string for the element group to add the event to, see - * this.getAll() - * @param {string} eventType - The event to listen for - * @param {function} callback - The function to execute when the event is triggered - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Calls the clickable function whenever any element with the .clickable class is clicked - * this.addListeners(".clickable", "click", this.clickable, this); - */ -Manager.prototype.addListeners = function(selector, eventType, callback, scope) { - scope = scope || this; - [].forEach.call(document.querySelectorAll(selector), function(el) { - el.addEventListener(eventType, callback.bind(scope)); - }); -}; - - -/** - * Adds multiple event listeners to the specified element. - * - * @param {string} selector - A selector string for the element to add the events to - * @param {string} eventTypes - A space-separated string of all the event types to listen for - * @param {function} callback - The function to execute when the events are triggered - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Calls the search function whenever the the keyup, paste or search events are triggered on the - * // search element - * this.addMultiEventListener("search", "keyup paste search", this.search, this); - */ -Manager.prototype.addMultiEventListener = function(selector, eventTypes, callback, scope) { - const evs = eventTypes.split(" "); - for (let i = 0; i < evs.length; i++) { - document.querySelector(selector).addEventListener(evs[i], callback.bind(scope)); - } -}; - - -/** - * Adds multiple event listeners to each element in the specified group. - * - * @param {string} selector - A selector string for the element group to add the events to - * @param {string} eventTypes - A space-separated string of all the event types to listen for - * @param {function} callback - The function to execute when the events are triggered - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Calls the save function whenever the the keyup or paste events are triggered on any element - * // with the .saveable class - * this.addMultiEventListener(".saveable", "keyup paste", this.save, this); - */ -Manager.prototype.addMultiEventListeners = function(selector, eventTypes, callback, scope) { - const evs = eventTypes.split(" "); - for (let i = 0; i < evs.length; i++) { - this.addListeners(selector, evs[i], callback, scope); - } -}; - - -/** - * Adds an event listener to the global document object which will listen on dynamic elements which - * may not exist in the DOM yet. - * - * @param {string} selector - A selector string for the element(s) to add the event to - * @param {string} eventType - The event(s) to listen for - * @param {function} callback - The function to execute when the event(s) is/are triggered - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Pops up an alert whenever any button is clicked, even if it is added to the DOM after this - * // listener is created - * this.addDynamicListener("button", "click", alert, this); - */ -Manager.prototype.addDynamicListener = function(selector, eventType, callback, scope) { - const eventConfig = { - selector: selector, - callback: callback.bind(scope || this) - }; - - if (this.dynamicHandlers.hasOwnProperty(eventType)) { - // Listener already exists, add new handler to the appropriate list - this.dynamicHandlers[eventType].push(eventConfig); - } else { - this.dynamicHandlers[eventType] = [eventConfig]; - // Set up listener for this new type - document.addEventListener(eventType, this.dynamicListenerHandler.bind(this)); - } -}; - - -/** - * Handler for dynamic events. This function is called for any dynamic event and decides which - * callback(s) to execute based on the type and selector. - * - * @param {Event} e - The event to be handled - */ -Manager.prototype.dynamicListenerHandler = function(e) { - const { type, target } = e; - const handlers = this.dynamicHandlers[type]; - const matches = target.matches || - target.webkitMatchesSelector || - target.mozMatchesSelector || - target.msMatchesSelector || - target.oMatchesSelector; - - for (let i = 0; i < handlers.length; i++) { - if (matches && matches.call(target, handlers[i].selector)) { - handlers[i].callback(e); - } - } -}; - -export default Manager; diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs new file mode 100755 index 00000000..4f004edc --- /dev/null +++ b/src/web/Manager.mjs @@ -0,0 +1,307 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import WorkerWaiter from "./WorkerWaiter"; +import WindowWaiter from "./WindowWaiter"; +import ControlsWaiter from "./ControlsWaiter"; +import RecipeWaiter from "./RecipeWaiter"; +import OperationsWaiter from "./OperationsWaiter"; +import InputWaiter from "./InputWaiter"; +import OutputWaiter from "./OutputWaiter"; +import OptionsWaiter from "./OptionsWaiter"; +import HighlighterWaiter from "./HighlighterWaiter"; +import SeasonalWaiter from "./SeasonalWaiter"; +import BindingsWaiter from "./BindingsWaiter"; + + +/** + * This object controls the Waiters responsible for handling events from all areas of the app. + */ +class Manager { + + /** + * Manager constructor. + * + * @param {App} app - The main view object for CyberChef. + */ + constructor(app) { + this.app = app; + + // Define custom events + /** + * @event Manager#appstart + */ + this.appstart = new CustomEvent("appstart", {bubbles: true}); + /** + * @event Manager#apploaded + */ + this.apploaded = new CustomEvent("apploaded", {bubbles: true}); + /** + * @event Manager#operationadd + */ + this.operationadd = new CustomEvent("operationadd", {bubbles: true}); + /** + * @event Manager#operationremove + */ + this.operationremove = new CustomEvent("operationremove", {bubbles: true}); + /** + * @event Manager#oplistcreate + */ + this.oplistcreate = new CustomEvent("oplistcreate", {bubbles: true}); + /** + * @event Manager#statechange + */ + this.statechange = new CustomEvent("statechange", {bubbles: true}); + + // Define Waiter objects to handle various areas + this.worker = new WorkerWaiter(this.app, this); + this.window = new WindowWaiter(this.app); + this.controls = new ControlsWaiter(this.app, this); + this.recipe = new RecipeWaiter(this.app, this); + this.ops = new OperationsWaiter(this.app, this); + this.input = new InputWaiter(this.app, this); + this.output = new OutputWaiter(this.app, this); + this.options = new OptionsWaiter(this.app, this); + this.highlighter = new HighlighterWaiter(this.app, this); + this.seasonal = new SeasonalWaiter(this.app, this); + this.bindings = new BindingsWaiter(this.app, this); + + // Object to store dynamic handlers to fire on elements that may not exist yet + this.dynamicHandlers = {}; + + this.initialiseEventListeners(); + } + + + /** + * Sets up the various components and listeners. + */ + setup() { + this.worker.registerChefWorker(); + this.recipe.initialiseOperationDragNDrop(); + this.controls.autoBakeChange(); + this.bindings.updateKeybList(); + this.seasonal.load(); + } + + + /** + * Main function to handle the creation of the event listeners. + */ + initialiseEventListeners() { + // Global + window.addEventListener("resize", this.window.windowResize.bind(this.window)); + window.addEventListener("blur", this.window.windowBlur.bind(this.window)); + window.addEventListener("focus", this.window.windowFocus.bind(this.window)); + window.addEventListener("statechange", this.app.stateChange.bind(this.app)); + window.addEventListener("popstate", this.app.popState.bind(this.app)); + + // Controls + document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls)); + document.getElementById("auto-bake").addEventListener("change", this.controls.autoBakeChange.bind(this.controls)); + document.getElementById("step").addEventListener("click", this.controls.stepClick.bind(this.controls)); + document.getElementById("clr-recipe").addEventListener("click", this.controls.clearRecipeClick.bind(this.controls)); + document.getElementById("clr-breaks").addEventListener("click", this.controls.clearBreaksClick.bind(this.controls)); + document.getElementById("save").addEventListener("click", this.controls.saveClick.bind(this.controls)); + document.getElementById("save-button").addEventListener("click", this.controls.saveButtonClick.bind(this.controls)); + document.getElementById("save-link-recipe-checkbox").addEventListener("change", this.controls.slrCheckChange.bind(this.controls)); + document.getElementById("save-link-input-checkbox").addEventListener("change", this.controls.sliCheckChange.bind(this.controls)); + document.getElementById("load").addEventListener("click", this.controls.loadClick.bind(this.controls)); + document.getElementById("load-delete-button").addEventListener("click", this.controls.loadDeleteClick.bind(this.controls)); + document.getElementById("load-name").addEventListener("change", this.controls.loadNameChange.bind(this.controls)); + document.getElementById("load-button").addEventListener("click", this.controls.loadButtonClick.bind(this.controls)); + document.getElementById("support").addEventListener("click", this.controls.supportButtonClick.bind(this.controls)); + this.addMultiEventListeners("#save-texts textarea", "keyup paste", this.controls.saveTextChange, this.controls); + + // Operations + this.addMultiEventListener("#search", "keyup paste search", this.ops.searchOperations, this.ops); + this.addDynamicListener(".op-list li.operation", "dblclick", this.ops.operationDblclick, this.ops); + document.getElementById("edit-favourites").addEventListener("click", this.ops.editFavouritesClick.bind(this.ops)); + document.getElementById("save-favourites").addEventListener("click", this.ops.saveFavouritesClick.bind(this.ops)); + document.getElementById("reset-favourites").addEventListener("click", this.ops.resetFavouritesClick.bind(this.ops)); + this.addDynamicListener(".op-list .op-icon", "mouseover", this.ops.opIconMouseover, this.ops); + this.addDynamicListener(".op-list .op-icon", "mouseleave", this.ops.opIconMouseleave, this.ops); + this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops); + this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd, this.recipe); + + // Recipe + this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe); + this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe); + this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe); + this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe); + this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe); + this.addDynamicListener("#rec-list li.operation > div", "dblclick", this.recipe.operationChildDblclick, this.recipe); + this.addDynamicListener("#rec-list .input-group .dropdown-menu a", "click", this.recipe.dropdownToggleClick, this.recipe); + this.addDynamicListener("#rec-list", "operationremove", this.recipe.opRemove.bind(this.recipe)); + + // Input + this.addMultiEventListener("#input-text", "keyup", this.input.inputChange, this.input); + this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input); + document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app)); + document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input)); + this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input); + this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input); + this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input); + document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter)); + document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter)); + document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter)); + this.addMultiEventListener("#input-text", "mousedown dblclick select", this.highlighter.inputMousedown, this.highlighter); + document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input)); + + // Output + document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); + document.getElementById("copy-output").addEventListener("click", this.output.copyClick.bind(this.output)); + document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output)); + document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output)); + document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output)); + document.getElementById("output-text").addEventListener("scroll", this.highlighter.outputScroll.bind(this.highlighter)); + document.getElementById("output-text").addEventListener("mouseup", this.highlighter.outputMouseup.bind(this.highlighter)); + document.getElementById("output-text").addEventListener("mousemove", this.highlighter.outputMousemove.bind(this.highlighter)); + document.getElementById("output-html").addEventListener("mouseup", this.highlighter.outputHtmlMouseup.bind(this.highlighter)); + document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter)); + this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter); + this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); + this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); + this.addDynamicListener("#output-file-slice", "click", this.output.displayFileSlice, this.output); + document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output)); + + // Options + document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); + document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options)); + $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options)); + $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options)); + $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings)); + this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options); + this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options); + this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options); + document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options)); + document.getElementById("logLevel").addEventListener("change", this.options.logLevelChange.bind(this.options)); + + // Misc + window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); + document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app)); + } + + + /** + * Adds an event listener to each element in the specified group. + * + * @param {string} selector - A selector string for the element group to add the event to, see + * this.getAll() + * @param {string} eventType - The event to listen for + * @param {function} callback - The function to execute when the event is triggered + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Calls the clickable function whenever any element with the .clickable class is clicked + * this.addListeners(".clickable", "click", this.clickable, this); + */ + addListeners(selector, eventType, callback, scope) { + scope = scope || this; + [].forEach.call(document.querySelectorAll(selector), function(el) { + el.addEventListener(eventType, callback.bind(scope)); + }); + } + + + /** + * Adds multiple event listeners to the specified element. + * + * @param {string} selector - A selector string for the element to add the events to + * @param {string} eventTypes - A space-separated string of all the event types to listen for + * @param {function} callback - The function to execute when the events are triggered + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Calls the search function whenever the the keyup, paste or search events are triggered on the + * // search element + * this.addMultiEventListener("search", "keyup paste search", this.search, this); + */ + addMultiEventListener(selector, eventTypes, callback, scope) { + const evs = eventTypes.split(" "); + for (let i = 0; i < evs.length; i++) { + document.querySelector(selector).addEventListener(evs[i], callback.bind(scope)); + } + } + + + /** + * Adds multiple event listeners to each element in the specified group. + * + * @param {string} selector - A selector string for the element group to add the events to + * @param {string} eventTypes - A space-separated string of all the event types to listen for + * @param {function} callback - The function to execute when the events are triggered + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Calls the save function whenever the the keyup or paste events are triggered on any element + * // with the .saveable class + * this.addMultiEventListener(".saveable", "keyup paste", this.save, this); + */ + addMultiEventListeners(selector, eventTypes, callback, scope) { + const evs = eventTypes.split(" "); + for (let i = 0; i < evs.length; i++) { + this.addListeners(selector, evs[i], callback, scope); + } + } + + + /** + * Adds an event listener to the global document object which will listen on dynamic elements which + * may not exist in the DOM yet. + * + * @param {string} selector - A selector string for the element(s) to add the event to + * @param {string} eventType - The event(s) to listen for + * @param {function} callback - The function to execute when the event(s) is/are triggered + * @param {Object} [scope=this] - The object to bind to the callback function + * + * @example + * // Pops up an alert whenever any button is clicked, even if it is added to the DOM after this + * // listener is created + * this.addDynamicListener("button", "click", alert, this); + */ + addDynamicListener(selector, eventType, callback, scope) { + const eventConfig = { + selector: selector, + callback: callback.bind(scope || this) + }; + + if (this.dynamicHandlers.hasOwnProperty(eventType)) { + // Listener already exists, add new handler to the appropriate list + this.dynamicHandlers[eventType].push(eventConfig); + } else { + this.dynamicHandlers[eventType] = [eventConfig]; + // Set up listener for this new type + document.addEventListener(eventType, this.dynamicListenerHandler.bind(this)); + } + } + + + /** + * Handler for dynamic events. This function is called for any dynamic event and decides which + * callback(s) to execute based on the type and selector. + * + * @param {Event} e - The event to be handled + */ + dynamicListenerHandler(e) { + const { type, target } = e; + const handlers = this.dynamicHandlers[type]; + const matches = target.matches || + target.webkitMatchesSelector || + target.mozMatchesSelector || + target.msMatchesSelector || + target.oMatchesSelector; + + for (let i = 0; i < handlers.length; i++) { + if (matches && matches.call(target, handlers[i].selector)) { + handlers[i].callback(e); + } + } + } + +} + +export default Manager; diff --git a/src/web/OperationsWaiter.js b/src/web/OperationsWaiter.js deleted file mode 100755 index 48bbe158..00000000 --- a/src/web/OperationsWaiter.js +++ /dev/null @@ -1,313 +0,0 @@ -import HTMLOperation from "./HTMLOperation.js"; -import Sortable from "sortablejs"; - - -/** - * Waiter to handle events related to the operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const OperationsWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - - this.options = {}; - this.removeIntent = false; -}; - - -/** - * Handler for search events. - * Finds operations which match the given search term and displays them under the search box. - * - * @param {event} e - */ -OperationsWaiter.prototype.searchOperations = function(e) { - let ops, selected; - - if (e.type === "search") { // Search - e.preventDefault(); - ops = document.querySelectorAll("#search-results li"); - if (ops.length) { - selected = this.getSelectedOp(ops); - if (selected > -1) { - this.manager.recipe.addOperation(ops[selected].innerHTML); - } - } - } - - if (e.keyCode === 13) { // Return - e.preventDefault(); - } else if (e.keyCode === 40) { // Down - e.preventDefault(); - ops = document.querySelectorAll("#search-results li"); - if (ops.length) { - selected = this.getSelectedOp(ops); - if (selected > -1) { - ops[selected].classList.remove("selected-op"); - } - if (selected === ops.length-1) selected = -1; - ops[selected+1].classList.add("selected-op"); - } - } else if (e.keyCode === 38) { // Up - e.preventDefault(); - ops = document.querySelectorAll("#search-results li"); - if (ops.length) { - selected = this.getSelectedOp(ops); - if (selected > -1) { - ops[selected].classList.remove("selected-op"); - } - if (selected === 0) selected = ops.length; - ops[selected-1].classList.add("selected-op"); - } - } else { - const searchResultsEl = document.getElementById("search-results"); - const el = e.target; - const str = el.value; - - while (searchResultsEl.firstChild) { - try { - $(searchResultsEl.firstChild).popover("destroy"); - } catch (err) {} - searchResultsEl.removeChild(searchResultsEl.firstChild); - } - - $("#categories .in").collapse("hide"); - if (str) { - const matchedOps = this.filterOperations(str, true); - const matchedOpsHtml = matchedOps - .map(v => v.toStubHtml()) - .join(""); - - searchResultsEl.innerHTML = matchedOpsHtml; - searchResultsEl.dispatchEvent(this.manager.oplistcreate); - } - } -}; - - -/** - * Filters operations based on the search string and returns the matching ones. - * - * @param {string} searchStr - * @param {boolean} highlight - Whether or not to highlight the matching string in the operation - * name and description - * @returns {string[]} - */ -OperationsWaiter.prototype.filterOperations = function(inStr, highlight) { - const matchedOps = []; - const matchedDescs = []; - - const searchStr = inStr.toLowerCase(); - - for (const opName in this.app.operations) { - const op = this.app.operations[opName]; - const namePos = opName.toLowerCase().indexOf(searchStr); - const descPos = op.description.toLowerCase().indexOf(searchStr); - - if (namePos >= 0 || descPos >= 0) { - const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); - if (highlight) { - operation.highlightSearchString(searchStr, namePos, descPos); - } - - if (namePos < 0) { - matchedOps.push(operation); - } else { - matchedDescs.push(operation); - } - } - } - - return matchedDescs.concat(matchedOps); -}; - - -/** - * Finds the operation which has been selected using keyboard shortcuts. This will have the class - * 'selected-op' set. Returns the index of the operation within the given list. - * - * @param {element[]} ops - * @returns {number} - */ -OperationsWaiter.prototype.getSelectedOp = function(ops) { - for (let i = 0; i < ops.length; i++) { - if (ops[i].classList.contains("selected-op")) { - return i; - } - } - return -1; -}; - - -/** - * Handler for oplistcreate events. - * - * @listens Manager#oplistcreate - * @param {event} e - */ -OperationsWaiter.prototype.opListCreate = function(e) { - this.manager.recipe.createSortableSeedList(e.target); - this.enableOpsListPopovers(e.target); -}; - - -/** - * Sets up popovers, allowing the popover itself to gain focus which enables scrolling - * and other interactions. - * - * @param {Element} el - The element to start selecting from - */ -OperationsWaiter.prototype.enableOpsListPopovers = function(el) { - $(el).find("[data-toggle=popover]").addBack("[data-toggle=popover]") - .popover({trigger: "manual"}) - .on("mouseenter", function(e) { - if (e.buttons > 0) return; // Mouse button held down - likely dragging an opertion - const _this = this; - $(this).popover("show"); - $(".popover").on("mouseleave", function () { - $(_this).popover("hide"); - }); - }).on("mouseleave", function () { - const _this = this; - setTimeout(function() { - // Determine if the popover associated with this element is being hovered over - if ($(_this).data("bs.popover") && - ($(_this).data("bs.popover").$tip && !$(_this).data("bs.popover").$tip.is(":hover"))) { - $(_this).popover("hide"); - } - }, 50); - }); -}; - - -/** - * Handler for operation doubleclick events. - * Adds the operation to the recipe and auto bakes. - * - * @param {event} e - */ -OperationsWaiter.prototype.operationDblclick = function(e) { - const li = e.target; - - this.manager.recipe.addOperation(li.textContent); -}; - - -/** - * Handler for edit favourites click events. - * Sets up the 'Edit favourites' pane and displays it. - * - * @param {event} e - */ -OperationsWaiter.prototype.editFavouritesClick = function(e) { - e.preventDefault(); - e.stopPropagation(); - - // Add favourites to modal - const favCat = this.app.categories.filter(function(c) { - return c.name === "Favourites"; - })[0]; - - let html = ""; - for (let i = 0; i < favCat.ops.length; i++) { - const opName = favCat.ops[i]; - const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); - html += operation.toStubHtml(true); - } - - const editFavouritesList = document.getElementById("edit-favourites-list"); - editFavouritesList.innerHTML = html; - this.removeIntent = false; - - const editableList = Sortable.create(editFavouritesList, { - filter: ".remove-icon", - onFilter: function (evt) { - const el = editableList.closest(evt.item); - if (el && el.parentNode) { - $(el).popover("destroy"); - el.parentNode.removeChild(el); - } - }, - onEnd: function(evt) { - if (this.removeIntent) { - $(evt.item).popover("destroy"); - evt.item.remove(); - } - }.bind(this), - }); - - Sortable.utils.on(editFavouritesList, "dragleave", function() { - this.removeIntent = true; - }.bind(this)); - - Sortable.utils.on(editFavouritesList, "dragover", function() { - this.removeIntent = false; - }.bind(this)); - - $("#edit-favourites-list [data-toggle=popover]").popover(); - $("#favourites-modal").modal(); -}; - - -/** - * Handler for save favourites click events. - * Saves the selected favourites and reloads them. - */ -OperationsWaiter.prototype.saveFavouritesClick = function() { - const favs = document.querySelectorAll("#edit-favourites-list li"); - const favouritesList = Array.from(favs, e => e.textContent); - - this.app.saveFavourites(favouritesList); - this.app.loadFavourites(); - this.app.populateOperationsList(); - this.manager.recipe.initialiseOperationDragNDrop(); -}; - - -/** - * Handler for reset favourites click events. - * Resets favourites to their defaults. - */ -OperationsWaiter.prototype.resetFavouritesClick = function() { - this.app.resetFavourites(); -}; - - -/** - * Handler for opIcon mouseover events. - * Hides any popovers already showing on the operation so that there aren't two at once. - * - * @param {event} e - */ -OperationsWaiter.prototype.opIconMouseover = function(e) { - const opEl = e.target.parentNode; - if (e.target.getAttribute("data-toggle") === "popover") { - $(opEl).popover("hide"); - } -}; - - -/** - * Handler for opIcon mouseleave events. - * If this icon created a popover and we're moving back to the operation element, display the - * operation popover again. - * - * @param {event} e - */ -OperationsWaiter.prototype.opIconMouseleave = function(e) { - const opEl = e.target.parentNode; - const toEl = e.toElement || e.relatedElement; - - if (e.target.getAttribute("data-toggle") === "popover" && toEl === opEl) { - $(opEl).popover("show"); - } -}; - -export default OperationsWaiter; diff --git a/src/web/OperationsWaiter.mjs b/src/web/OperationsWaiter.mjs new file mode 100755 index 00000000..d890cedc --- /dev/null +++ b/src/web/OperationsWaiter.mjs @@ -0,0 +1,321 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import HTMLOperation from "./HTMLOperation"; +import Sortable from "sortablejs"; + + +/** + * Waiter to handle events related to the operations. + */ +class OperationsWaiter { + + /** + * OperationsWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + + this.options = {}; + this.removeIntent = false; + } + + + /** + * Handler for search events. + * Finds operations which match the given search term and displays them under the search box. + * + * @param {event} e + */ + searchOperations(e) { + let ops, selected; + + if (e.type === "search") { // Search + e.preventDefault(); + ops = document.querySelectorAll("#search-results li"); + if (ops.length) { + selected = this.getSelectedOp(ops); + if (selected > -1) { + this.manager.recipe.addOperation(ops[selected].innerHTML); + } + } + } + + if (e.keyCode === 13) { // Return + e.preventDefault(); + } else if (e.keyCode === 40) { // Down + e.preventDefault(); + ops = document.querySelectorAll("#search-results li"); + if (ops.length) { + selected = this.getSelectedOp(ops); + if (selected > -1) { + ops[selected].classList.remove("selected-op"); + } + if (selected === ops.length-1) selected = -1; + ops[selected+1].classList.add("selected-op"); + } + } else if (e.keyCode === 38) { // Up + e.preventDefault(); + ops = document.querySelectorAll("#search-results li"); + if (ops.length) { + selected = this.getSelectedOp(ops); + if (selected > -1) { + ops[selected].classList.remove("selected-op"); + } + if (selected === 0) selected = ops.length; + ops[selected-1].classList.add("selected-op"); + } + } else { + const searchResultsEl = document.getElementById("search-results"); + const el = e.target; + const str = el.value; + + while (searchResultsEl.firstChild) { + try { + $(searchResultsEl.firstChild).popover("destroy"); + } catch (err) {} + searchResultsEl.removeChild(searchResultsEl.firstChild); + } + + $("#categories .in").collapse("hide"); + if (str) { + const matchedOps = this.filterOperations(str, true); + const matchedOpsHtml = matchedOps + .map(v => v.toStubHtml()) + .join(""); + + searchResultsEl.innerHTML = matchedOpsHtml; + searchResultsEl.dispatchEvent(this.manager.oplistcreate); + } + } + } + + + /** + * Filters operations based on the search string and returns the matching ones. + * + * @param {string} searchStr + * @param {boolean} highlight - Whether or not to highlight the matching string in the operation + * name and description + * @returns {string[]} + */ + filterOperations(inStr, highlight) { + const matchedOps = []; + const matchedDescs = []; + + const searchStr = inStr.toLowerCase(); + + for (const opName in this.app.operations) { + const op = this.app.operations[opName]; + const namePos = opName.toLowerCase().indexOf(searchStr); + const descPos = op.description.toLowerCase().indexOf(searchStr); + + if (namePos >= 0 || descPos >= 0) { + const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); + if (highlight) { + operation.highlightSearchString(searchStr, namePos, descPos); + } + + if (namePos < 0) { + matchedOps.push(operation); + } else { + matchedDescs.push(operation); + } + } + } + + return matchedDescs.concat(matchedOps); + } + + + /** + * Finds the operation which has been selected using keyboard shortcuts. This will have the class + * 'selected-op' set. Returns the index of the operation within the given list. + * + * @param {element[]} ops + * @returns {number} + */ + getSelectedOp(ops) { + for (let i = 0; i < ops.length; i++) { + if (ops[i].classList.contains("selected-op")) { + return i; + } + } + return -1; + } + + + /** + * Handler for oplistcreate events. + * + * @listens Manager#oplistcreate + * @param {event} e + */ + opListCreate(e) { + this.manager.recipe.createSortableSeedList(e.target); + this.enableOpsListPopovers(e.target); + } + + + /** + * Sets up popovers, allowing the popover itself to gain focus which enables scrolling + * and other interactions. + * + * @param {Element} el - The element to start selecting from + */ + enableOpsListPopovers(el) { + $(el).find("[data-toggle=popover]").addBack("[data-toggle=popover]") + .popover({trigger: "manual"}) + .on("mouseenter", function(e) { + if (e.buttons > 0) return; // Mouse button held down - likely dragging an opertion + const _this = this; + $(this).popover("show"); + $(".popover").on("mouseleave", function () { + $(_this).popover("hide"); + }); + }).on("mouseleave", function () { + const _this = this; + setTimeout(function() { + // Determine if the popover associated with this element is being hovered over + if ($(_this).data("bs.popover") && + ($(_this).data("bs.popover").$tip && !$(_this).data("bs.popover").$tip.is(":hover"))) { + $(_this).popover("hide"); + } + }, 50); + }); + } + + + /** + * Handler for operation doubleclick events. + * Adds the operation to the recipe and auto bakes. + * + * @param {event} e + */ + operationDblclick(e) { + const li = e.target; + + this.manager.recipe.addOperation(li.textContent); + } + + + /** + * Handler for edit favourites click events. + * Sets up the 'Edit favourites' pane and displays it. + * + * @param {event} e + */ + editFavouritesClick(e) { + e.preventDefault(); + e.stopPropagation(); + + // Add favourites to modal + const favCat = this.app.categories.filter(function(c) { + return c.name === "Favourites"; + })[0]; + + let html = ""; + for (let i = 0; i < favCat.ops.length; i++) { + const opName = favCat.ops[i]; + const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); + html += operation.toStubHtml(true); + } + + const editFavouritesList = document.getElementById("edit-favourites-list"); + editFavouritesList.innerHTML = html; + this.removeIntent = false; + + const editableList = Sortable.create(editFavouritesList, { + filter: ".remove-icon", + onFilter: function (evt) { + const el = editableList.closest(evt.item); + if (el && el.parentNode) { + $(el).popover("destroy"); + el.parentNode.removeChild(el); + } + }, + onEnd: function(evt) { + if (this.removeIntent) { + $(evt.item).popover("destroy"); + evt.item.remove(); + } + }.bind(this), + }); + + Sortable.utils.on(editFavouritesList, "dragleave", function() { + this.removeIntent = true; + }.bind(this)); + + Sortable.utils.on(editFavouritesList, "dragover", function() { + this.removeIntent = false; + }.bind(this)); + + $("#edit-favourites-list [data-toggle=popover]").popover(); + $("#favourites-modal").modal(); + } + + + /** + * Handler for save favourites click events. + * Saves the selected favourites and reloads them. + */ + saveFavouritesClick() { + const favs = document.querySelectorAll("#edit-favourites-list li"); + const favouritesList = Array.from(favs, e => e.textContent); + + this.app.saveFavourites(favouritesList); + this.app.loadFavourites(); + this.app.populateOperationsList(); + this.manager.recipe.initialiseOperationDragNDrop(); + } + + + /** + * Handler for reset favourites click events. + * Resets favourites to their defaults. + */ + resetFavouritesClick() { + this.app.resetFavourites(); + } + + + /** + * Handler for opIcon mouseover events. + * Hides any popovers already showing on the operation so that there aren't two at once. + * + * @param {event} e + */ + opIconMouseover(e) { + const opEl = e.target.parentNode; + if (e.target.getAttribute("data-toggle") === "popover") { + $(opEl).popover("hide"); + } + } + + + /** + * Handler for opIcon mouseleave events. + * If this icon created a popover and we're moving back to the operation element, display the + * operation popover again. + * + * @param {event} e + */ + opIconMouseleave(e) { + const opEl = e.target.parentNode; + const toEl = e.toElement || e.relatedElement; + + if (e.target.getAttribute("data-toggle") === "popover" && toEl === opEl) { + $(opEl).popover("show"); + } + } + +} + +export default OperationsWaiter; diff --git a/src/web/OptionsWaiter.js b/src/web/OptionsWaiter.mjs similarity index 100% rename from src/web/OptionsWaiter.js rename to src/web/OptionsWaiter.mjs diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js deleted file mode 100755 index 6d2f3840..00000000 --- a/src/web/OutputWaiter.js +++ /dev/null @@ -1,441 +0,0 @@ -import Utils from "../core/Utils"; -import FileSaver from "file-saver"; - - -/** - * Waiter to handle events related to the output. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const OutputWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - - this.dishBuffer = null; - this.dishStr = null; -}; - - -/** - * Gets the output string from the output textarea. - * - * @returns {string} - */ -OutputWaiter.prototype.get = function() { - return document.getElementById("output-text").value; -}; - - -/** - * Sets the output in the output textarea. - * - * @param {string|ArrayBuffer} data - The output string/HTML/ArrayBuffer - * @param {string} type - The data type of the output - * @param {number} duration - The length of time (ms) it took to generate the output - * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer - */ -OutputWaiter.prototype.set = async function(data, type, duration, preserveBuffer) { - log.debug("Output type: " + type); - const outputText = document.getElementById("output-text"); - const outputHtml = document.getElementById("output-html"); - const outputFile = document.getElementById("output-file"); - const outputHighlighter = document.getElementById("output-highlighter"); - const inputHighlighter = document.getElementById("input-highlighter"); - let scriptElements, lines, length; - - if (!preserveBuffer) { - this.closeFile(); - this.dishStr = null; - document.getElementById("show-file-overlay").style.display = "none"; - } - - switch (type) { - case "html": - outputText.style.display = "none"; - outputHtml.style.display = "block"; - outputFile.style.display = "none"; - outputHighlighter.display = "none"; - inputHighlighter.display = "none"; - - outputText.value = ""; - outputHtml.innerHTML = data; - - // Execute script sections - scriptElements = outputHtml.querySelectorAll("script"); - for (let i = 0; i < scriptElements.length; i++) { - try { - eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval - } catch (err) { - log.error(err); - } - } - - await this.getDishStr(); - length = this.dishStr.length; - lines = this.dishStr.count("\n") + 1; - break; - case "ArrayBuffer": - outputText.style.display = "block"; - outputHtml.style.display = "none"; - outputHighlighter.display = "none"; - inputHighlighter.display = "none"; - - outputText.value = ""; - outputHtml.innerHTML = ""; - length = data.byteLength; - - this.setFile(data); - break; - case "string": - default: - outputText.style.display = "block"; - outputHtml.style.display = "none"; - outputFile.style.display = "none"; - outputHighlighter.display = "block"; - inputHighlighter.display = "block"; - - outputText.value = Utils.printable(data, true); - outputHtml.innerHTML = ""; - - lines = data.count("\n") + 1; - length = data.length; - this.dishStr = data; - break; - } - - this.manager.highlighter.removeHighlights(); - this.setOutputInfo(length, lines, duration); -}; - - -/** - * Shows file details. - * - * @param {ArrayBuffer} buf - */ -OutputWaiter.prototype.setFile = function(buf) { - this.dishBuffer = buf; - const file = new File([buf], "output.dat"); - - // Display file overlay in output area with details - const fileOverlay = document.getElementById("output-file"), - fileSize = document.getElementById("output-file-size"); - - fileOverlay.style.display = "block"; - fileSize.textContent = file.size.toLocaleString() + " bytes"; - - // Display preview slice in the background - const outputText = document.getElementById("output-text"), - fileSlice = this.dishBuffer.slice(0, 4096); - - outputText.classList.add("blur"); - outputText.value = Utils.printable(Utils.arrayBufferToStr(fileSlice)); -}; - - -/** - * Removes the output file and nulls its memory. - */ -OutputWaiter.prototype.closeFile = function() { - this.dishBuffer = null; - document.getElementById("output-file").style.display = "none"; - document.getElementById("output-text").classList.remove("blur"); -}; - - -/** - * Handler for file download events. - */ -OutputWaiter.prototype.downloadFile = async function() { - this.filename = window.prompt("Please enter a filename:", this.filename || "download.dat"); - await this.getDishBuffer(); - const file = new File([this.dishBuffer], this.filename); - if (this.filename) FileSaver.saveAs(file, this.filename, false); -}; - - -/** - * Handler for file slice display events. - */ -OutputWaiter.prototype.displayFileSlice = function() { - const startTime = new Date().getTime(), - showFileOverlay = document.getElementById("show-file-overlay"), - sliceFromEl = document.getElementById("output-file-slice-from"), - sliceToEl = document.getElementById("output-file-slice-to"), - sliceFrom = parseInt(sliceFromEl.value, 10), - sliceTo = parseInt(sliceToEl.value, 10), - str = Utils.arrayBufferToStr(this.dishBuffer.slice(sliceFrom, sliceTo)); - - document.getElementById("output-text").classList.remove("blur"); - showFileOverlay.style.display = "block"; - this.set(str, "string", new Date().getTime() - startTime, true); -}; - - -/** - * Handler for show file overlay events. - * - * @param {Event} e - */ -OutputWaiter.prototype.showFileOverlayClick = function(e) { - const outputFile = document.getElementById("output-file"), - showFileOverlay = e.target; - - document.getElementById("output-text").classList.add("blur"); - outputFile.style.display = "block"; - showFileOverlay.style.display = "none"; - this.setOutputInfo(this.dishBuffer.byteLength, null, 0); -}; - - -/** - * Displays information about the output. - * - * @param {number} length - The length of the current output string - * @param {number} lines - The number of the lines in the current output string - * @param {number} duration - The length of time (ms) it took to generate the output - */ -OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { - let width = length.toString().length; - width = width < 4 ? 4 : width; - - const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); - const timeStr = (duration.toString() + "ms").padStart(width, " ").replace(/ /g, " "); - - let msg = "time: " + timeStr + "
    length: " + lengthStr; - - if (typeof lines === "number") { - const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); - msg += "
    lines: " + linesStr; - } - - document.getElementById("output-info").innerHTML = msg; - document.getElementById("input-selection-info").innerHTML = ""; - document.getElementById("output-selection-info").innerHTML = ""; -}; - - -/** - * Adjusts the display properties of the output buttons so that they fit within the current width - * without wrapping or overflowing. - */ -OutputWaiter.prototype.adjustWidth = function() { - const output = document.getElementById("output"); - const saveToFile = document.getElementById("save-to-file"); - const copyOutput = document.getElementById("copy-output"); - const switchIO = document.getElementById("switch"); - const undoSwitch = document.getElementById("undo-switch"); - const maximiseOutput = document.getElementById("maximise-output"); - - if (output.clientWidth < 680) { - saveToFile.childNodes[1].nodeValue = ""; - copyOutput.childNodes[1].nodeValue = ""; - switchIO.childNodes[1].nodeValue = ""; - undoSwitch.childNodes[1].nodeValue = ""; - maximiseOutput.childNodes[1].nodeValue = ""; - } else { - saveToFile.childNodes[1].nodeValue = " Save to file"; - copyOutput.childNodes[1].nodeValue = " Copy output"; - switchIO.childNodes[1].nodeValue = " Move output to input"; - undoSwitch.childNodes[1].nodeValue = " Undo"; - maximiseOutput.childNodes[1].nodeValue = - maximiseOutput.getAttribute("title") === "Maximise" ? " Max" : " Restore"; - } -}; - - -/** - * Handler for save click events. - * Saves the current output to a file. - */ -OutputWaiter.prototype.saveClick = function() { - this.downloadFile(); -}; - - -/** - * Handler for copy click events. - * Copies the output to the clipboard. - */ -OutputWaiter.prototype.copyClick = async function() { - await this.getDishStr(); - - // Create invisible textarea to populate with the raw dish string (not the printable version that - // contains dots instead of the actual bytes) - const textarea = document.createElement("textarea"); - textarea.style.position = "fixed"; - textarea.style.top = 0; - textarea.style.left = 0; - textarea.style.width = 0; - textarea.style.height = 0; - textarea.style.border = "none"; - - textarea.value = this.dishStr; - document.body.appendChild(textarea); - - // Select and copy the contents of this textarea - let success = false; - try { - textarea.select(); - success = this.dishStr && document.execCommand("copy"); - } catch (err) { - success = false; - } - - if (success) { - this.app.alert("Copied raw output successfully.", "success", 2000); - } else { - this.app.alert("Sorry, the output could not be copied.", "danger", 2000); - } - - // Clean up - document.body.removeChild(textarea); -}; - - -/** - * Handler for switch click events. - * Moves the current output into the input textarea. - */ -OutputWaiter.prototype.switchClick = async function() { - this.switchOrigData = this.manager.input.get(); - document.getElementById("undo-switch").disabled = false; - if (this.dishBuffer) { - this.manager.input.setFile(new File([this.dishBuffer], "output.dat")); - this.manager.input.handleLoaderMessage({ - data: { - progress: 100, - fileBuffer: this.dishBuffer - } - }); - } else { - await this.getDishStr(); - this.app.setInput(this.dishStr); - } -}; - - -/** - * Handler for undo switch click events. - * Removes the output from the input and replaces the input that was removed. - */ -OutputWaiter.prototype.undoSwitchClick = function() { - this.app.setInput(this.switchOrigData); - document.getElementById("undo-switch").disabled = true; -}; - - -/** - * Handler for maximise output click events. - * Resizes the output frame to be as large as possible, or restores it to its original size. - */ -OutputWaiter.prototype.maximiseOutputClick = function(e) { - const el = e.target.id === "maximise-output" ? e.target : e.target.parentNode; - - if (el.getAttribute("title") === "Maximise") { - this.app.columnSplitter.collapse(0); - this.app.columnSplitter.collapse(1); - this.app.ioSplitter.collapse(0); - - el.setAttribute("title", "Restore"); - el.innerHTML = " Restore"; - this.adjustWidth(); - } else { - el.setAttribute("title", "Maximise"); - el.innerHTML = " Max"; - this.app.resetLayout(); - } -}; - - -/** - * Shows or hides the loading icon. - * - * @param {boolean} value - */ -OutputWaiter.prototype.toggleLoader = function(value) { - const outputLoader = document.getElementById("output-loader"), - outputElement = document.getElementById("output-text"); - - if (value) { - this.manager.controls.hideStaleIndicator(); - this.bakingStatusTimeout = setTimeout(function() { - outputElement.disabled = true; - outputLoader.style.visibility = "visible"; - outputLoader.style.opacity = 1; - this.manager.controls.toggleBakeButtonFunction(true); - }.bind(this), 200); - } else { - clearTimeout(this.bakingStatusTimeout); - outputElement.disabled = false; - outputLoader.style.opacity = 0; - outputLoader.style.visibility = "hidden"; - this.manager.controls.toggleBakeButtonFunction(false); - this.setStatusMsg(""); - } -}; - - -/** - * Sets the baking status message value. - * - * @param {string} msg - */ -OutputWaiter.prototype.setStatusMsg = function(msg) { - const el = document.querySelector("#output-loader .loading-msg"); - - el.textContent = msg; -}; - - -/** - * Returns true if the output contains carriage returns - * - * @returns {boolean} - */ -OutputWaiter.prototype.containsCR = async function() { - await this.getDishStr(); - return this.dishStr.indexOf("\r") >= 0; -}; - - -/** - * Retrieves the current dish as a string, returning the cached version if possible. - * - * @returns {string} - */ -OutputWaiter.prototype.getDishStr = async function() { - if (this.dishStr) return this.dishStr; - - this.dishStr = await new Promise(resolve => { - this.manager.worker.getDishAs(this.app.dish, "string", r => { - resolve(r.value); - }); - }); - return this.dishStr; -}; - - -/** - * Retrieves the current dish as an ArrayBuffer, returning the cached version if possible. - * - * @returns {ArrayBuffer} - */ -OutputWaiter.prototype.getDishBuffer = async function() { - if (this.dishBuffer) return this.dishBuffer; - - this.dishBuffer = await new Promise(resolve => { - this.manager.worker.getDishAs(this.app.dish, "ArrayBuffer", r => { - resolve(r.value); - }); - }); - return this.dishBuffer; -}; - -export default OutputWaiter; diff --git a/src/web/OutputWaiter.mjs b/src/web/OutputWaiter.mjs new file mode 100755 index 00000000..166dde0f --- /dev/null +++ b/src/web/OutputWaiter.mjs @@ -0,0 +1,449 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import Utils from "../core/Utils"; +import FileSaver from "file-saver"; + + +/** + * Waiter to handle events related to the output. + */ +class OutputWaiter { + + /** + * OutputWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + + this.dishBuffer = null; + this.dishStr = null; + } + + + /** + * Gets the output string from the output textarea. + * + * @returns {string} + */ + get() { + return document.getElementById("output-text").value; + } + + + /** + * Sets the output in the output textarea. + * + * @param {string|ArrayBuffer} data - The output string/HTML/ArrayBuffer + * @param {string} type - The data type of the output + * @param {number} duration - The length of time (ms) it took to generate the output + * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer + */ + async set(data, type, duration, preserveBuffer) { + log.debug("Output type: " + type); + const outputText = document.getElementById("output-text"); + const outputHtml = document.getElementById("output-html"); + const outputFile = document.getElementById("output-file"); + const outputHighlighter = document.getElementById("output-highlighter"); + const inputHighlighter = document.getElementById("input-highlighter"); + let scriptElements, lines, length; + + if (!preserveBuffer) { + this.closeFile(); + this.dishStr = null; + document.getElementById("show-file-overlay").style.display = "none"; + } + + switch (type) { + case "html": + outputText.style.display = "none"; + outputHtml.style.display = "block"; + outputFile.style.display = "none"; + outputHighlighter.display = "none"; + inputHighlighter.display = "none"; + + outputText.value = ""; + outputHtml.innerHTML = data; + + // Execute script sections + scriptElements = outputHtml.querySelectorAll("script"); + for (let i = 0; i < scriptElements.length; i++) { + try { + eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval + } catch (err) { + log.error(err); + } + } + + await this.getDishStr(); + length = this.dishStr.length; + lines = this.dishStr.count("\n") + 1; + break; + case "ArrayBuffer": + outputText.style.display = "block"; + outputHtml.style.display = "none"; + outputHighlighter.display = "none"; + inputHighlighter.display = "none"; + + outputText.value = ""; + outputHtml.innerHTML = ""; + length = data.byteLength; + + this.setFile(data); + break; + case "string": + default: + outputText.style.display = "block"; + outputHtml.style.display = "none"; + outputFile.style.display = "none"; + outputHighlighter.display = "block"; + inputHighlighter.display = "block"; + + outputText.value = Utils.printable(data, true); + outputHtml.innerHTML = ""; + + lines = data.count("\n") + 1; + length = data.length; + this.dishStr = data; + break; + } + + this.manager.highlighter.removeHighlights(); + this.setOutputInfo(length, lines, duration); + } + + + /** + * Shows file details. + * + * @param {ArrayBuffer} buf + */ + setFile(buf) { + this.dishBuffer = buf; + const file = new File([buf], "output.dat"); + + // Display file overlay in output area with details + const fileOverlay = document.getElementById("output-file"), + fileSize = document.getElementById("output-file-size"); + + fileOverlay.style.display = "block"; + fileSize.textContent = file.size.toLocaleString() + " bytes"; + + // Display preview slice in the background + const outputText = document.getElementById("output-text"), + fileSlice = this.dishBuffer.slice(0, 4096); + + outputText.classList.add("blur"); + outputText.value = Utils.printable(Utils.arrayBufferToStr(fileSlice)); + } + + + /** + * Removes the output file and nulls its memory. + */ + closeFile() { + this.dishBuffer = null; + document.getElementById("output-file").style.display = "none"; + document.getElementById("output-text").classList.remove("blur"); + } + + + /** + * Handler for file download events. + */ + async downloadFile() { + this.filename = window.prompt("Please enter a filename:", this.filename || "download.dat"); + await this.getDishBuffer(); + const file = new File([this.dishBuffer], this.filename); + if (this.filename) FileSaver.saveAs(file, this.filename, false); + } + + + /** + * Handler for file slice display events. + */ + displayFileSlice() { + const startTime = new Date().getTime(), + showFileOverlay = document.getElementById("show-file-overlay"), + sliceFromEl = document.getElementById("output-file-slice-from"), + sliceToEl = document.getElementById("output-file-slice-to"), + sliceFrom = parseInt(sliceFromEl.value, 10), + sliceTo = parseInt(sliceToEl.value, 10), + str = Utils.arrayBufferToStr(this.dishBuffer.slice(sliceFrom, sliceTo)); + + document.getElementById("output-text").classList.remove("blur"); + showFileOverlay.style.display = "block"; + this.set(str, "string", new Date().getTime() - startTime, true); + } + + + /** + * Handler for show file overlay events. + * + * @param {Event} e + */ + showFileOverlayClick(e) { + const outputFile = document.getElementById("output-file"), + showFileOverlay = e.target; + + document.getElementById("output-text").classList.add("blur"); + outputFile.style.display = "block"; + showFileOverlay.style.display = "none"; + this.setOutputInfo(this.dishBuffer.byteLength, null, 0); + } + + + /** + * Displays information about the output. + * + * @param {number} length - The length of the current output string + * @param {number} lines - The number of the lines in the current output string + * @param {number} duration - The length of time (ms) it took to generate the output + */ + setOutputInfo(length, lines, duration) { + let width = length.toString().length; + width = width < 4 ? 4 : width; + + const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); + const timeStr = (duration.toString() + "ms").padStart(width, " ").replace(/ /g, " "); + + let msg = "time: " + timeStr + "
    length: " + lengthStr; + + if (typeof lines === "number") { + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); + msg += "
    lines: " + linesStr; + } + + document.getElementById("output-info").innerHTML = msg; + document.getElementById("input-selection-info").innerHTML = ""; + document.getElementById("output-selection-info").innerHTML = ""; + } + + + /** + * Adjusts the display properties of the output buttons so that they fit within the current width + * without wrapping or overflowing. + */ + adjustWidth() { + const output = document.getElementById("output"); + const saveToFile = document.getElementById("save-to-file"); + const copyOutput = document.getElementById("copy-output"); + const switchIO = document.getElementById("switch"); + const undoSwitch = document.getElementById("undo-switch"); + const maximiseOutput = document.getElementById("maximise-output"); + + if (output.clientWidth < 680) { + saveToFile.childNodes[1].nodeValue = ""; + copyOutput.childNodes[1].nodeValue = ""; + switchIO.childNodes[1].nodeValue = ""; + undoSwitch.childNodes[1].nodeValue = ""; + maximiseOutput.childNodes[1].nodeValue = ""; + } else { + saveToFile.childNodes[1].nodeValue = " Save to file"; + copyOutput.childNodes[1].nodeValue = " Copy output"; + switchIO.childNodes[1].nodeValue = " Move output to input"; + undoSwitch.childNodes[1].nodeValue = " Undo"; + maximiseOutput.childNodes[1].nodeValue = + maximiseOutput.getAttribute("title") === "Maximise" ? " Max" : " Restore"; + } + } + + + /** + * Handler for save click events. + * Saves the current output to a file. + */ + saveClick() { + this.downloadFile(); + } + + + /** + * Handler for copy click events. + * Copies the output to the clipboard. + */ + async copyClick() { + await this.getDishStr(); + + // Create invisible textarea to populate with the raw dish string (not the printable version that + // contains dots instead of the actual bytes) + const textarea = document.createElement("textarea"); + textarea.style.position = "fixed"; + textarea.style.top = 0; + textarea.style.left = 0; + textarea.style.width = 0; + textarea.style.height = 0; + textarea.style.border = "none"; + + textarea.value = this.dishStr; + document.body.appendChild(textarea); + + // Select and copy the contents of this textarea + let success = false; + try { + textarea.select(); + success = this.dishStr && document.execCommand("copy"); + } catch (err) { + success = false; + } + + if (success) { + this.app.alert("Copied raw output successfully.", "success", 2000); + } else { + this.app.alert("Sorry, the output could not be copied.", "danger", 2000); + } + + // Clean up + document.body.removeChild(textarea); + } + + + /** + * Handler for switch click events. + * Moves the current output into the input textarea. + */ + async switchClick() { + this.switchOrigData = this.manager.input.get(); + document.getElementById("undo-switch").disabled = false; + if (this.dishBuffer) { + this.manager.input.setFile(new File([this.dishBuffer], "output.dat")); + this.manager.input.handleLoaderMessage({ + data: { + progress: 100, + fileBuffer: this.dishBuffer + } + }); + } else { + await this.getDishStr(); + this.app.setInput(this.dishStr); + } + } + + + /** + * Handler for undo switch click events. + * Removes the output from the input and replaces the input that was removed. + */ + undoSwitchClick() { + this.app.setInput(this.switchOrigData); + document.getElementById("undo-switch").disabled = true; + } + + + /** + * Handler for maximise output click events. + * Resizes the output frame to be as large as possible, or restores it to its original size. + */ + maximiseOutputClick(e) { + const el = e.target.id === "maximise-output" ? e.target : e.target.parentNode; + + if (el.getAttribute("title") === "Maximise") { + this.app.columnSplitter.collapse(0); + this.app.columnSplitter.collapse(1); + this.app.ioSplitter.collapse(0); + + el.setAttribute("title", "Restore"); + el.innerHTML = " Restore"; + this.adjustWidth(); + } else { + el.setAttribute("title", "Maximise"); + el.innerHTML = " Max"; + this.app.resetLayout(); + } + } + + + /** + * Shows or hides the loading icon. + * + * @param {boolean} value + */ + toggleLoader(value) { + const outputLoader = document.getElementById("output-loader"), + outputElement = document.getElementById("output-text"); + + if (value) { + this.manager.controls.hideStaleIndicator(); + this.bakingStatusTimeout = setTimeout(function() { + outputElement.disabled = true; + outputLoader.style.visibility = "visible"; + outputLoader.style.opacity = 1; + this.manager.controls.toggleBakeButtonFunction(true); + }.bind(this), 200); + } else { + clearTimeout(this.bakingStatusTimeout); + outputElement.disabled = false; + outputLoader.style.opacity = 0; + outputLoader.style.visibility = "hidden"; + this.manager.controls.toggleBakeButtonFunction(false); + this.setStatusMsg(""); + } + } + + + /** + * Sets the baking status message value. + * + * @param {string} msg + */ + setStatusMsg(msg) { + const el = document.querySelector("#output-loader .loading-msg"); + + el.textContent = msg; + } + + + /** + * Returns true if the output contains carriage returns + * + * @returns {boolean} + */ + async containsCR() { + await this.getDishStr(); + return this.dishStr.indexOf("\r") >= 0; + } + + + /** + * Retrieves the current dish as a string, returning the cached version if possible. + * + * @returns {string} + */ + async getDishStr() { + if (this.dishStr) return this.dishStr; + + this.dishStr = await new Promise(resolve => { + this.manager.worker.getDishAs(this.app.dish, "string", r => { + resolve(r.value); + }); + }); + return this.dishStr; + } + + + /** + * Retrieves the current dish as an ArrayBuffer, returning the cached version if possible. + * + * @returns {ArrayBuffer} + */ + async getDishBuffer() { + if (this.dishBuffer) return this.dishBuffer; + + this.dishBuffer = await new Promise(resolve => { + this.manager.worker.getDishAs(this.app.dish, "ArrayBuffer", r => { + resolve(r.value); + }); + }); + return this.dishBuffer; + } + +} + +export default OutputWaiter; diff --git a/src/web/RecipeWaiter.js b/src/web/RecipeWaiter.js deleted file mode 100755 index 40c4bb08..00000000 --- a/src/web/RecipeWaiter.js +++ /dev/null @@ -1,467 +0,0 @@ -import HTMLOperation from "./HTMLOperation.js"; -import Sortable from "sortablejs"; -import Utils from "../core/Utils"; - - -/** - * Waiter to handle events related to the recipe. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const RecipeWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - this.removeIntent = false; -}; - - -/** - * Sets up the drag and drop capability for operations in the operations and recipe areas. - */ -RecipeWaiter.prototype.initialiseOperationDragNDrop = function() { - const recList = document.getElementById("rec-list"); - - // Recipe list - Sortable.create(recList, { - group: "recipe", - sort: true, - animation: 0, - delay: 0, - filter: ".arg-input,.arg", - preventOnFilter: false, - setData: function(dataTransfer, dragEl) { - dataTransfer.setData("Text", dragEl.querySelector(".arg-title").textContent); - }, - onEnd: function(evt) { - if (this.removeIntent) { - evt.item.remove(); - evt.target.dispatchEvent(this.manager.operationremove); - } - }.bind(this), - onSort: function(evt) { - if (evt.from.id === "rec-list") { - document.dispatchEvent(this.manager.statechange); - } - }.bind(this) - }); - - Sortable.utils.on(recList, "dragover", function() { - this.removeIntent = false; - }.bind(this)); - - Sortable.utils.on(recList, "dragleave", function() { - this.removeIntent = true; - this.app.progress = 0; - }.bind(this)); - - Sortable.utils.on(recList, "touchend", function(e) { - const loc = e.changedTouches[0]; - const target = document.elementFromPoint(loc.clientX, loc.clientY); - - this.removeIntent = !recList.contains(target); - }.bind(this)); - - // Favourites category - document.querySelector("#categories a").addEventListener("dragover", this.favDragover.bind(this)); - document.querySelector("#categories a").addEventListener("dragleave", this.favDragleave.bind(this)); - document.querySelector("#categories a").addEventListener("drop", this.favDrop.bind(this)); -}; - - -/** - * Creates a drag-n-droppable seed list of operations. - * - * @param {element} listEl - The list to initialise - */ -RecipeWaiter.prototype.createSortableSeedList = function(listEl) { - Sortable.create(listEl, { - group: { - name: "recipe", - pull: "clone", - put: false, - }, - sort: false, - setData: function(dataTransfer, dragEl) { - dataTransfer.setData("Text", dragEl.textContent); - }, - onStart: function(evt) { - // Removes popover element and event bindings from the dragged operation but not the - // event bindings from the one left in the operations list. Without manually removing - // these bindings, we cannot re-initialise the popover on the stub operation. - $(evt.item).popover("destroy").removeData("bs.popover").off("mouseenter").off("mouseleave"); - $(evt.clone).off(".popover").removeData("bs.popover"); - evt.item.setAttribute("data-toggle", "popover-disabled"); - }, - onEnd: this.opSortEnd.bind(this) - }); -}; - - -/** - * Handler for operation sort end events. - * Removes the operation from the list if it has been dropped outside. If not, adds it to the list - * at the appropriate place and initialises it. - * - * @fires Manager#operationadd - * @param {event} evt - */ -RecipeWaiter.prototype.opSortEnd = function(evt) { - if (this.removeIntent) { - if (evt.item.parentNode.id === "rec-list") { - evt.item.remove(); - } - return; - } - - // Reinitialise the popover on the original element in the ops list because for some reason it - // gets destroyed and recreated. - this.manager.ops.enableOpsListPopovers(evt.clone); - - if (evt.item.parentNode.id !== "rec-list") { - return; - } - - this.buildRecipeOperation(evt.item); - evt.item.dispatchEvent(this.manager.operationadd); -}; - - -/** - * Handler for favourite dragover events. - * If the element being dragged is an operation, displays a visual cue so that the user knows it can - * be dropped here. - * - * @param {event} e - */ -RecipeWaiter.prototype.favDragover = function(e) { - if (e.dataTransfer.effectAllowed !== "move") - return false; - - e.stopPropagation(); - e.preventDefault(); - if (e.target.className && e.target.className.indexOf("category-title") > -1) { - // Hovering over the a - e.target.classList.add("favourites-hover"); - } else if (e.target.parentNode.className && e.target.parentNode.className.indexOf("category-title") > -1) { - // Hovering over the Edit button - e.target.parentNode.classList.add("favourites-hover"); - } else if (e.target.parentNode.parentNode.className && e.target.parentNode.parentNode.className.indexOf("category-title") > -1) { - // Hovering over the image on the Edit button - e.target.parentNode.parentNode.classList.add("favourites-hover"); - } -}; - - -/** - * Handler for favourite dragleave events. - * Removes the visual cue. - * - * @param {event} e - */ -RecipeWaiter.prototype.favDragleave = function(e) { - e.stopPropagation(); - e.preventDefault(); - document.querySelector("#categories a").classList.remove("favourites-hover"); -}; - - -/** - * Handler for favourite drop events. - * Adds the dragged operation to the favourites list. - * - * @param {event} e - */ -RecipeWaiter.prototype.favDrop = function(e) { - e.stopPropagation(); - e.preventDefault(); - e.target.classList.remove("favourites-hover"); - - const opName = e.dataTransfer.getData("Text"); - this.app.addFavourite(opName); -}; - - -/** - * Handler for ingredient change events. - * - * @fires Manager#statechange - */ -RecipeWaiter.prototype.ingChange = function(e) { - window.dispatchEvent(this.manager.statechange); -}; - - -/** - * Handler for disable click events. - * Updates the icon status. - * - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.disableClick = function(e) { - const icon = e.target; - - if (icon.getAttribute("disabled") === "false") { - icon.setAttribute("disabled", "true"); - icon.classList.add("disable-icon-selected"); - icon.parentNode.parentNode.classList.add("disabled"); - } else { - icon.setAttribute("disabled", "false"); - icon.classList.remove("disable-icon-selected"); - icon.parentNode.parentNode.classList.remove("disabled"); - } - - this.app.progress = 0; - window.dispatchEvent(this.manager.statechange); -}; - - -/** - * Handler for breakpoint click events. - * Updates the icon status. - * - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.breakpointClick = function(e) { - const bp = e.target; - - if (bp.getAttribute("break") === "false") { - bp.setAttribute("break", "true"); - bp.classList.add("breakpoint-selected"); - } else { - bp.setAttribute("break", "false"); - bp.classList.remove("breakpoint-selected"); - } - - window.dispatchEvent(this.manager.statechange); -}; - - -/** - * Handler for operation doubleclick events. - * Removes the operation from the recipe and auto bakes. - * - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.operationDblclick = function(e) { - e.target.remove(); - this.opRemove(e); -}; - - -/** - * Handler for operation child doubleclick events. - * Removes the operation from the recipe. - * - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.operationChildDblclick = function(e) { - e.target.parentNode.remove(); - this.opRemove(e); -}; - - -/** - * Generates a configuration object to represent the current recipe. - * - * @returns {recipeConfig} - */ -RecipeWaiter.prototype.getConfig = function() { - const config = []; - let ingredients, ingList, disabled, bp, item; - const operations = document.querySelectorAll("#rec-list li.operation"); - - for (let i = 0; i < operations.length; i++) { - ingredients = []; - disabled = operations[i].querySelector(".disable-icon"); - bp = operations[i].querySelector(".breakpoint"); - ingList = operations[i].querySelectorAll(".arg"); - - for (let j = 0; j < ingList.length; j++) { - if (ingList[j].getAttribute("type") === "checkbox") { - // checkbox - ingredients[j] = ingList[j].checked; - } else if (ingList[j].classList.contains("toggle-string")) { - // toggleString - ingredients[j] = { - option: ingList[j].previousSibling.children[0].textContent.slice(0, -1), - string: ingList[j].value - }; - } else if (ingList[j].getAttribute("type") === "number") { - // number - ingredients[j] = parseFloat(ingList[j].value, 10); - } else { - // all others - ingredients[j] = ingList[j].value; - } - } - - item = { - op: operations[i].querySelector(".arg-title").textContent, - args: ingredients - }; - - if (disabled && disabled.getAttribute("disabled") === "true") { - item.disabled = true; - } - - if (bp && bp.getAttribute("break") === "true") { - item.breakpoint = true; - } - - config.push(item); - } - - return config; -}; - - -/** - * Moves or removes the breakpoint indicator in the recipe based on the position. - * - * @param {number} position - */ -RecipeWaiter.prototype.updateBreakpointIndicator = function(position) { - const operations = document.querySelectorAll("#rec-list li.operation"); - for (let i = 0; i < operations.length; i++) { - if (i === position) { - operations[i].classList.add("break"); - } else { - operations[i].classList.remove("break"); - } - } -}; - - -/** - * Given an operation stub element, this function converts it into a full recipe element with - * arguments. - * - * @param {element} el - The operation stub element from the operations pane - */ -RecipeWaiter.prototype.buildRecipeOperation = function(el) { - const opName = el.textContent; - const op = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); - el.innerHTML = op.toFullHtml(); - - if (this.app.operations[opName].flowControl) { - el.classList.add("flow-control-op"); - } - - // Disable auto-bake if this is a manual op - if (op.manualBake && this.app.autoBake_) { - this.manager.controls.setAutoBake(false); - this.app.alert("Auto-Bake is disabled by default when using this operation.", "info", 5000); - } -}; - -/** - * Adds the specified operation to the recipe. - * - * @fires Manager#operationadd - * @param {string} name - The name of the operation to add - * @returns {element} - */ -RecipeWaiter.prototype.addOperation = function(name) { - const item = document.createElement("li"); - - item.classList.add("operation"); - item.innerHTML = name; - this.buildRecipeOperation(item); - document.getElementById("rec-list").appendChild(item); - - item.dispatchEvent(this.manager.operationadd); - return item; -}; - - -/** - * Removes all operations from the recipe. - * - * @fires Manager#operationremove - */ -RecipeWaiter.prototype.clearRecipe = function() { - const recList = document.getElementById("rec-list"); - while (recList.firstChild) { - recList.removeChild(recList.firstChild); - } - recList.dispatchEvent(this.manager.operationremove); -}; - - -/** - * Handler for operation dropdown events from toggleString arguments. - * Sets the selected option as the name of the button. - * - * @param {event} e - */ -RecipeWaiter.prototype.dropdownToggleClick = function(e) { - const el = e.target; - const button = el.parentNode.parentNode.previousSibling; - - button.innerHTML = el.textContent + " "; - this.ingChange(); -}; - - -/** - * Handler for operationadd events. - * - * @listens Manager#operationadd - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.opAdd = function(e) { - log.debug(`'${e.target.querySelector(".arg-title").textContent}' added to recipe`); - window.dispatchEvent(this.manager.statechange); -}; - - -/** - * Handler for operationremove events. - * - * @listens Manager#operationremove - * @fires Manager#statechange - * @param {event} e - */ -RecipeWaiter.prototype.opRemove = function(e) { - log.debug("Operation removed from recipe"); - window.dispatchEvent(this.manager.statechange); -}; - - -/** - * Sets register values. - * - * @param {number} opIndex - * @param {number} numPrevRegisters - * @param {string[]} registers - */ -RecipeWaiter.prototype.setRegisters = function(opIndex, numPrevRegisters, registers) { - const op = document.querySelector(`#rec-list .operation:nth-child(${opIndex + 1})`), - prevRegList = op.querySelector(".register-list"); - - // Remove previous div - if (prevRegList) prevRegList.remove(); - - const registerList = []; - for (let i = 0; i < registers.length; i++) { - registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`); - } - const registerListEl = `
    - ${registerList.join("
    ")} -
    `; - - op.insertAdjacentHTML("beforeend", registerListEl); -}; - -export default RecipeWaiter; diff --git a/src/web/RecipeWaiter.mjs b/src/web/RecipeWaiter.mjs new file mode 100755 index 00000000..60589766 --- /dev/null +++ b/src/web/RecipeWaiter.mjs @@ -0,0 +1,475 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +import HTMLOperation from "./HTMLOperation"; +import Sortable from "sortablejs"; +import Utils from "../core/Utils"; + + +/** + * Waiter to handle events related to the recipe. + */ +class RecipeWaiter { + + /** + * RecipeWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + this.removeIntent = false; + } + + + /** + * Sets up the drag and drop capability for operations in the operations and recipe areas. + */ + initialiseOperationDragNDrop() { + const recList = document.getElementById("rec-list"); + + // Recipe list + Sortable.create(recList, { + group: "recipe", + sort: true, + animation: 0, + delay: 0, + filter: ".arg-input,.arg", + preventOnFilter: false, + setData: function(dataTransfer, dragEl) { + dataTransfer.setData("Text", dragEl.querySelector(".arg-title").textContent); + }, + onEnd: function(evt) { + if (this.removeIntent) { + evt.item.remove(); + evt.target.dispatchEvent(this.manager.operationremove); + } + }.bind(this), + onSort: function(evt) { + if (evt.from.id === "rec-list") { + document.dispatchEvent(this.manager.statechange); + } + }.bind(this) + }); + + Sortable.utils.on(recList, "dragover", function() { + this.removeIntent = false; + }.bind(this)); + + Sortable.utils.on(recList, "dragleave", function() { + this.removeIntent = true; + this.app.progress = 0; + }.bind(this)); + + Sortable.utils.on(recList, "touchend", function(e) { + const loc = e.changedTouches[0]; + const target = document.elementFromPoint(loc.clientX, loc.clientY); + + this.removeIntent = !recList.contains(target); + }.bind(this)); + + // Favourites category + document.querySelector("#categories a").addEventListener("dragover", this.favDragover.bind(this)); + document.querySelector("#categories a").addEventListener("dragleave", this.favDragleave.bind(this)); + document.querySelector("#categories a").addEventListener("drop", this.favDrop.bind(this)); + } + + + /** + * Creates a drag-n-droppable seed list of operations. + * + * @param {element} listEl - The list to initialise + */ + createSortableSeedList(listEl) { + Sortable.create(listEl, { + group: { + name: "recipe", + pull: "clone", + put: false, + }, + sort: false, + setData: function(dataTransfer, dragEl) { + dataTransfer.setData("Text", dragEl.textContent); + }, + onStart: function(evt) { + // Removes popover element and event bindings from the dragged operation but not the + // event bindings from the one left in the operations list. Without manually removing + // these bindings, we cannot re-initialise the popover on the stub operation. + $(evt.item).popover("destroy").removeData("bs.popover").off("mouseenter").off("mouseleave"); + $(evt.clone).off(".popover").removeData("bs.popover"); + evt.item.setAttribute("data-toggle", "popover-disabled"); + }, + onEnd: this.opSortEnd.bind(this) + }); + } + + + /** + * Handler for operation sort end events. + * Removes the operation from the list if it has been dropped outside. If not, adds it to the list + * at the appropriate place and initialises it. + * + * @fires Manager#operationadd + * @param {event} evt + */ + opSortEnd(evt) { + if (this.removeIntent) { + if (evt.item.parentNode.id === "rec-list") { + evt.item.remove(); + } + return; + } + + // Reinitialise the popover on the original element in the ops list because for some reason it + // gets destroyed and recreated. + this.manager.ops.enableOpsListPopovers(evt.clone); + + if (evt.item.parentNode.id !== "rec-list") { + return; + } + + this.buildRecipeOperation(evt.item); + evt.item.dispatchEvent(this.manager.operationadd); + } + + + /** + * Handler for favourite dragover events. + * If the element being dragged is an operation, displays a visual cue so that the user knows it can + * be dropped here. + * + * @param {event} e + */ + favDragover(e) { + if (e.dataTransfer.effectAllowed !== "move") + return false; + + e.stopPropagation(); + e.preventDefault(); + if (e.target.className && e.target.className.indexOf("category-title") > -1) { + // Hovering over the a + e.target.classList.add("favourites-hover"); + } else if (e.target.parentNode.className && e.target.parentNode.className.indexOf("category-title") > -1) { + // Hovering over the Edit button + e.target.parentNode.classList.add("favourites-hover"); + } else if (e.target.parentNode.parentNode.className && e.target.parentNode.parentNode.className.indexOf("category-title") > -1) { + // Hovering over the image on the Edit button + e.target.parentNode.parentNode.classList.add("favourites-hover"); + } + } + + + /** + * Handler for favourite dragleave events. + * Removes the visual cue. + * + * @param {event} e + */ + favDragleave(e) { + e.stopPropagation(); + e.preventDefault(); + document.querySelector("#categories a").classList.remove("favourites-hover"); + } + + + /** + * Handler for favourite drop events. + * Adds the dragged operation to the favourites list. + * + * @param {event} e + */ + favDrop(e) { + e.stopPropagation(); + e.preventDefault(); + e.target.classList.remove("favourites-hover"); + + const opName = e.dataTransfer.getData("Text"); + this.app.addFavourite(opName); + } + + + /** + * Handler for ingredient change events. + * + * @fires Manager#statechange + */ + ingChange(e) { + window.dispatchEvent(this.manager.statechange); + } + + + /** + * Handler for disable click events. + * Updates the icon status. + * + * @fires Manager#statechange + * @param {event} e + */ + disableClick(e) { + const icon = e.target; + + if (icon.getAttribute("disabled") === "false") { + icon.setAttribute("disabled", "true"); + icon.classList.add("disable-icon-selected"); + icon.parentNode.parentNode.classList.add("disabled"); + } else { + icon.setAttribute("disabled", "false"); + icon.classList.remove("disable-icon-selected"); + icon.parentNode.parentNode.classList.remove("disabled"); + } + + this.app.progress = 0; + window.dispatchEvent(this.manager.statechange); + } + + + /** + * Handler for breakpoint click events. + * Updates the icon status. + * + * @fires Manager#statechange + * @param {event} e + */ + breakpointClick(e) { + const bp = e.target; + + if (bp.getAttribute("break") === "false") { + bp.setAttribute("break", "true"); + bp.classList.add("breakpoint-selected"); + } else { + bp.setAttribute("break", "false"); + bp.classList.remove("breakpoint-selected"); + } + + window.dispatchEvent(this.manager.statechange); + } + + + /** + * Handler for operation doubleclick events. + * Removes the operation from the recipe and auto bakes. + * + * @fires Manager#statechange + * @param {event} e + */ + operationDblclick(e) { + e.target.remove(); + this.opRemove(e); + } + + + /** + * Handler for operation child doubleclick events. + * Removes the operation from the recipe. + * + * @fires Manager#statechange + * @param {event} e + */ + operationChildDblclick(e) { + e.target.parentNode.remove(); + this.opRemove(e); + } + + + /** + * Generates a configuration object to represent the current recipe. + * + * @returns {recipeConfig} + */ + getConfig() { + const config = []; + let ingredients, ingList, disabled, bp, item; + const operations = document.querySelectorAll("#rec-list li.operation"); + + for (let i = 0; i < operations.length; i++) { + ingredients = []; + disabled = operations[i].querySelector(".disable-icon"); + bp = operations[i].querySelector(".breakpoint"); + ingList = operations[i].querySelectorAll(".arg"); + + for (let j = 0; j < ingList.length; j++) { + if (ingList[j].getAttribute("type") === "checkbox") { + // checkbox + ingredients[j] = ingList[j].checked; + } else if (ingList[j].classList.contains("toggle-string")) { + // toggleString + ingredients[j] = { + option: ingList[j].previousSibling.children[0].textContent.slice(0, -1), + string: ingList[j].value + }; + } else if (ingList[j].getAttribute("type") === "number") { + // number + ingredients[j] = parseFloat(ingList[j].value, 10); + } else { + // all others + ingredients[j] = ingList[j].value; + } + } + + item = { + op: operations[i].querySelector(".arg-title").textContent, + args: ingredients + }; + + if (disabled && disabled.getAttribute("disabled") === "true") { + item.disabled = true; + } + + if (bp && bp.getAttribute("break") === "true") { + item.breakpoint = true; + } + + config.push(item); + } + + return config; + } + + + /** + * Moves or removes the breakpoint indicator in the recipe based on the position. + * + * @param {number} position + */ + updateBreakpointIndicator(position) { + const operations = document.querySelectorAll("#rec-list li.operation"); + for (let i = 0; i < operations.length; i++) { + if (i === position) { + operations[i].classList.add("break"); + } else { + operations[i].classList.remove("break"); + } + } + } + + + /** + * Given an operation stub element, this function converts it into a full recipe element with + * arguments. + * + * @param {element} el - The operation stub element from the operations pane + */ + buildRecipeOperation(el) { + const opName = el.textContent; + const op = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager); + el.innerHTML = op.toFullHtml(); + + if (this.app.operations[opName].flowControl) { + el.classList.add("flow-control-op"); + } + + // Disable auto-bake if this is a manual op + if (op.manualBake && this.app.autoBake_) { + this.manager.controls.setAutoBake(false); + this.app.alert("Auto-Bake is disabled by default when using this operation.", "info", 5000); + } + } + + /** + * Adds the specified operation to the recipe. + * + * @fires Manager#operationadd + * @param {string} name - The name of the operation to add + * @returns {element} + */ + addOperation(name) { + const item = document.createElement("li"); + + item.classList.add("operation"); + item.innerHTML = name; + this.buildRecipeOperation(item); + document.getElementById("rec-list").appendChild(item); + + item.dispatchEvent(this.manager.operationadd); + return item; + } + + + /** + * Removes all operations from the recipe. + * + * @fires Manager#operationremove + */ + clearRecipe() { + const recList = document.getElementById("rec-list"); + while (recList.firstChild) { + recList.removeChild(recList.firstChild); + } + recList.dispatchEvent(this.manager.operationremove); + } + + + /** + * Handler for operation dropdown events from toggleString arguments. + * Sets the selected option as the name of the button. + * + * @param {event} e + */ + dropdownToggleClick(e) { + const el = e.target; + const button = el.parentNode.parentNode.previousSibling; + + button.innerHTML = el.textContent + " "; + this.ingChange(); + } + + + /** + * Handler for operationadd events. + * + * @listens Manager#operationadd + * @fires Manager#statechange + * @param {event} e + */ + opAdd(e) { + log.debug(`'${e.target.querySelector(".arg-title").textContent}' added to recipe`); + window.dispatchEvent(this.manager.statechange); + } + + + /** + * Handler for operationremove events. + * + * @listens Manager#operationremove + * @fires Manager#statechange + * @param {event} e + */ + opRemove(e) { + log.debug("Operation removed from recipe"); + window.dispatchEvent(this.manager.statechange); + } + + + /** + * Sets register values. + * + * @param {number} opIndex + * @param {number} numPrevRegisters + * @param {string[]} registers + */ + setRegisters(opIndex, numPrevRegisters, registers) { + const op = document.querySelector(`#rec-list .operation:nth-child(${opIndex + 1})`), + prevRegList = op.querySelector(".register-list"); + + // Remove previous div + if (prevRegList) prevRegList.remove(); + + const registerList = []; + for (let i = 0; i < registers.length; i++) { + registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`); + } + const registerListEl = `
    + ${registerList.join("
    ")} +
    `; + + op.insertAdjacentHTML("beforeend", registerListEl); + } + +} + +export default RecipeWaiter; diff --git a/src/web/SeasonalWaiter.js b/src/web/SeasonalWaiter.js deleted file mode 100755 index fb671024..00000000 --- a/src/web/SeasonalWaiter.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Waiter to handle seasonal events and easter eggs. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const SeasonalWaiter = function(app, manager) { - this.app = app; - this.manager = manager; -}; - - -/** - * Loads all relevant items depending on the current date. - */ -SeasonalWaiter.prototype.load = function() { - // Konami code - this.kkeys = []; - window.addEventListener("keydown", this.konamiCodeListener.bind(this)); -}; - - -/** - * Listen for the Konami code sequence of keys. Turn the page upside down if they are all heard in - * sequence. - * #konamicode - */ -SeasonalWaiter.prototype.konamiCodeListener = function(e) { - this.kkeys.push(e.keyCode); - const konami = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; - for (let i = 0; i < this.kkeys.length; i++) { - if (this.kkeys[i] !== konami[i]) { - this.kkeys = []; - break; - } - if (i === konami.length - 1) { - $("body").children().toggleClass("konami"); - this.kkeys = []; - } - } -}; - -export default SeasonalWaiter; diff --git a/src/web/SeasonalWaiter.mjs b/src/web/SeasonalWaiter.mjs new file mode 100755 index 00000000..e6611a89 --- /dev/null +++ b/src/web/SeasonalWaiter.mjs @@ -0,0 +1,56 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Waiter to handle seasonal events and easter eggs. + */ +class SeasonalWaiter { + + /** + * SeasonalWaiter contructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + } + + + /** + * Loads all relevant items depending on the current date. + */ + load() { + // Konami code + this.kkeys = []; + window.addEventListener("keydown", this.konamiCodeListener.bind(this)); + } + + + /** + * Listen for the Konami code sequence of keys. Turn the page upside down if they are all heard in + * sequence. + * #konamicode + */ + konamiCodeListener(e) { + this.kkeys.push(e.keyCode); + const konami = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; + for (let i = 0; i < this.kkeys.length; i++) { + if (this.kkeys[i] !== konami[i]) { + this.kkeys = []; + break; + } + if (i === konami.length - 1) { + $("body").children().toggleClass("konami"); + this.kkeys = []; + } + } + } + +} + +export default SeasonalWaiter; diff --git a/src/web/WindowWaiter.js b/src/web/WindowWaiter.js deleted file mode 100755 index e0d3944c..00000000 --- a/src/web/WindowWaiter.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Waiter to handle events related to the window object. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - */ -const WindowWaiter = function(app) { - this.app = app; -}; - - -/** - * Handler for window resize events. - * Resets the layout of CyberChef's panes after 200ms (so that continuous resizing doesn't cause - * continuous resetting). - */ -WindowWaiter.prototype.windowResize = function() { - clearTimeout(this.resetLayoutTimeout); - this.resetLayoutTimeout = setTimeout(this.app.resetLayout.bind(this.app), 200); -}; - - -/** - * Handler for window blur events. - * Saves the current time so that we can calculate how long the window was unfocussed for when - * focus is returned. - */ -WindowWaiter.prototype.windowBlur = function() { - this.windowBlurTime = new Date().getTime(); -}; - - -/** - * Handler for window focus events. - * - * When a browser tab is unfocused and the browser has to run lots of dynamic content in other - * tabs, it swaps out the memory for that tab. - * If the CyberChef tab has been unfocused for more than a minute, we run a silent bake which will - * force the browser to load and cache all the relevant JavaScript code needed to do a real bake. - * This will stop baking taking a long time when the CyberChef browser tab has been unfocused for - * a long time and the browser has swapped out all its memory. - */ -WindowWaiter.prototype.windowFocus = function() { - const unfocusedTime = new Date().getTime() - this.windowBlurTime; - if (unfocusedTime > 60000) { - this.app.silentBake(); - } -}; - -export default WindowWaiter; diff --git a/src/web/WindowWaiter.mjs b/src/web/WindowWaiter.mjs new file mode 100755 index 00000000..a8e124f5 --- /dev/null +++ b/src/web/WindowWaiter.mjs @@ -0,0 +1,62 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + */ + +/** + * Waiter to handle events related to the window object. + */ +class WindowWaiter { + + /** + * WindowWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + */ + constructor(app) { + this.app = app; + } + + + /** + * Handler for window resize events. + * Resets the layout of CyberChef's panes after 200ms (so that continuous resizing doesn't cause + * continuous resetting). + */ + windowResize() { + clearTimeout(this.resetLayoutTimeout); + this.resetLayoutTimeout = setTimeout(this.app.resetLayout.bind(this.app), 200); + } + + + /** + * Handler for window blur events. + * Saves the current time so that we can calculate how long the window was unfocussed for when + * focus is returned. + */ + windowBlur() { + this.windowBlurTime = new Date().getTime(); + } + + + /** + * Handler for window focus events. + * + * When a browser tab is unfocused and the browser has to run lots of dynamic content in other + * tabs, it swaps out the memory for that tab. + * If the CyberChef tab has been unfocused for more than a minute, we run a silent bake which will + * force the browser to load and cache all the relevant JavaScript code needed to do a real bake. + * This will stop baking taking a long time when the CyberChef browser tab has been unfocused for + * a long time and the browser has swapped out all its memory. + */ + windowFocus() { + const unfocusedTime = new Date().getTime() - this.windowBlurTime; + if (unfocusedTime > 60000) { + this.app.silentBake(); + } + } + +} + +export default WindowWaiter; diff --git a/src/web/WorkerWaiter.js b/src/web/WorkerWaiter.js deleted file mode 100755 index 4f3bad1b..00000000 --- a/src/web/WorkerWaiter.js +++ /dev/null @@ -1,231 +0,0 @@ -import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js"; - -/** - * Waiter to handle conversations with the ChefWorker. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @constructor - * @param {App} app - The main view object for CyberChef. - * @param {Manager} manager - The CyberChef event manager. - */ -const WorkerWaiter = function(app, manager) { - this.app = app; - this.manager = manager; - - this.callbacks = {}; - this.callbackID = 0; -}; - - -/** - * Sets up the ChefWorker and associated listeners. - */ -WorkerWaiter.prototype.registerChefWorker = function() { - log.debug("Registering new ChefWorker"); - this.chefWorker = new ChefWorker(); - this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this)); - this.setLogLevel(); - - let docURL = document.location.href.split(/[#?]/)[0]; - const index = docURL.lastIndexOf("/"); - if (index > 0) { - docURL = docURL.substring(0, index); - } - this.chefWorker.postMessage({"action": "docURL", "data": docURL}); -}; - - -/** - * Handler for messages sent back by the ChefWorker. - * - * @param {MessageEvent} e - */ -WorkerWaiter.prototype.handleChefMessage = function(e) { - const r = e.data; - log.debug("Receiving '" + r.action + "' from ChefWorker"); - - switch (r.action) { - case "bakeComplete": - this.bakingComplete(r.data); - break; - case "bakeError": - this.app.handleError(r.data); - this.setBakingStatus(false); - break; - case "dishReturned": - this.callbacks[r.data.id](r.data); - break; - case "silentBakeComplete": - break; - case "workerLoaded": - this.app.workerLoaded = true; - log.debug("ChefWorker loaded"); - this.app.loaded(); - break; - case "statusMessage": - this.manager.output.setStatusMsg(r.data); - break; - case "optionUpdate": - log.debug(`Setting ${r.data.option} to ${r.data.value}`); - this.app.options[r.data.option] = r.data.value; - break; - case "setRegisters": - this.manager.recipe.setRegisters(r.data.opIndex, r.data.numPrevRegisters, r.data.registers); - break; - case "highlightsCalculated": - this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction); - break; - default: - log.error("Unrecognised message from ChefWorker", e); - break; - } -}; - - -/** - * Updates the UI to show if baking is in process or not. - * - * @param {bakingStatus} - */ -WorkerWaiter.prototype.setBakingStatus = function(bakingStatus) { - this.app.baking = bakingStatus; - - this.manager.output.toggleLoader(bakingStatus); -}; - - -/** - * Cancels the current bake by terminating the ChefWorker and creating a new one. - */ -WorkerWaiter.prototype.cancelBake = function() { - this.chefWorker.terminate(); - this.registerChefWorker(); - this.setBakingStatus(false); - this.manager.controls.showStaleIndicator(); -}; - - -/** - * Handler for completed bakes. - * - * @param {Object} response - */ -WorkerWaiter.prototype.bakingComplete = function(response) { - this.setBakingStatus(false); - - if (!response) return; - - if (response.error) { - this.app.handleError(response.error); - } - - this.app.progress = response.progress; - this.app.dish = response.dish; - this.manager.recipe.updateBreakpointIndicator(response.progress); - this.manager.output.set(response.result, response.type, response.duration); - log.debug("--- Bake complete ---"); -}; - - -/** - * Asks the ChefWorker to bake the current input using the current recipe. - * - * @param {string} input - * @param {Object[]} recipeConfig - * @param {Object} options - * @param {number} progress - * @param {boolean} step - */ -WorkerWaiter.prototype.bake = function(input, recipeConfig, options, progress, step) { - this.setBakingStatus(true); - - this.chefWorker.postMessage({ - action: "bake", - data: { - input: input, - recipeConfig: recipeConfig, - options: options, - progress: progress, - step: step - } - }); -}; - - -/** - * Asks the ChefWorker to run a silent bake, forcing the browser to load and cache all the relevant - * JavaScript code needed to do a real bake. - * - * @param {Object[]} [recipeConfig] - */ -WorkerWaiter.prototype.silentBake = function(recipeConfig) { - this.chefWorker.postMessage({ - action: "silentBake", - data: { - recipeConfig: recipeConfig - } - }); -}; - - -/** - * Asks the ChefWorker to calculate highlight offsets if possible. - * - * @param {Object[]} recipeConfig - * @param {string} direction - * @param {Object} pos - The position object for the highlight. - * @param {number} pos.start - The start offset. - * @param {number} pos.end - The end offset. - */ -WorkerWaiter.prototype.highlight = function(recipeConfig, direction, pos) { - this.chefWorker.postMessage({ - action: "highlight", - data: { - recipeConfig: recipeConfig, - direction: direction, - pos: pos - } - }); -}; - - -/** - * Asks the ChefWorker to return the dish as the specified type - * - * @param {Dish} dish - * @param {string} type - * @param {Function} callback - */ -WorkerWaiter.prototype.getDishAs = function(dish, type, callback) { - const id = this.callbackID++; - this.callbacks[id] = callback; - this.chefWorker.postMessage({ - action: "getDishAs", - data: { - dish: dish, - type: type, - id: id - } - }); -}; - - -/** - * Sets the console log level in the worker. - * - * @param {string} level - */ -WorkerWaiter.prototype.setLogLevel = function(level) { - if (!this.chefWorker) return; - - this.chefWorker.postMessage({ - action: "setLogLevel", - data: log.getLevel() - }); -}; - - -export default WorkerWaiter; diff --git a/src/web/WorkerWaiter.mjs b/src/web/WorkerWaiter.mjs new file mode 100755 index 00000000..7ef72263 --- /dev/null +++ b/src/web/WorkerWaiter.mjs @@ -0,0 +1,239 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + +import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker"; + +/** + * Waiter to handle conversations with the ChefWorker. + */ +class WorkerWaiter { + + /** + * WorkerWaiter constructor. + * + * @param {App} app - The main view object for CyberChef. + * @param {Manager} manager - The CyberChef event manager. + */ + constructor(app, manager) { + this.app = app; + this.manager = manager; + + this.callbacks = {}; + this.callbackID = 0; + } + + + /** + * Sets up the ChefWorker and associated listeners. + */ + registerChefWorker() { + log.debug("Registering new ChefWorker"); + this.chefWorker = new ChefWorker(); + this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this)); + this.setLogLevel(); + + let docURL = document.location.href.split(/[#?]/)[0]; + const index = docURL.lastIndexOf("/"); + if (index > 0) { + docURL = docURL.substring(0, index); + } + this.chefWorker.postMessage({"action": "docURL", "data": docURL}); + } + + + /** + * Handler for messages sent back by the ChefWorker. + * + * @param {MessageEvent} e + */ + handleChefMessage(e) { + const r = e.data; + log.debug("Receiving '" + r.action + "' from ChefWorker"); + + switch (r.action) { + case "bakeComplete": + this.bakingComplete(r.data); + break; + case "bakeError": + this.app.handleError(r.data); + this.setBakingStatus(false); + break; + case "dishReturned": + this.callbacks[r.data.id](r.data); + break; + case "silentBakeComplete": + break; + case "workerLoaded": + this.app.workerLoaded = true; + log.debug("ChefWorker loaded"); + this.app.loaded(); + break; + case "statusMessage": + this.manager.output.setStatusMsg(r.data); + break; + case "optionUpdate": + log.debug(`Setting ${r.data.option} to ${r.data.value}`); + this.app.options[r.data.option] = r.data.value; + break; + case "setRegisters": + this.manager.recipe.setRegisters(r.data.opIndex, r.data.numPrevRegisters, r.data.registers); + break; + case "highlightsCalculated": + this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction); + break; + default: + log.error("Unrecognised message from ChefWorker", e); + break; + } + } + + + /** + * Updates the UI to show if baking is in process or not. + * + * @param {bakingStatus} + */ + setBakingStatus(bakingStatus) { + this.app.baking = bakingStatus; + + this.manager.output.toggleLoader(bakingStatus); + } + + + /** + * Cancels the current bake by terminating the ChefWorker and creating a new one. + */ + cancelBake() { + this.chefWorker.terminate(); + this.registerChefWorker(); + this.setBakingStatus(false); + this.manager.controls.showStaleIndicator(); + } + + + /** + * Handler for completed bakes. + * + * @param {Object} response + */ + bakingComplete(response) { + this.setBakingStatus(false); + + if (!response) return; + + if (response.error) { + this.app.handleError(response.error); + } + + this.app.progress = response.progress; + this.app.dish = response.dish; + this.manager.recipe.updateBreakpointIndicator(response.progress); + this.manager.output.set(response.result, response.type, response.duration); + log.debug("--- Bake complete ---"); + } + + + /** + * Asks the ChefWorker to bake the current input using the current recipe. + * + * @param {string} input + * @param {Object[]} recipeConfig + * @param {Object} options + * @param {number} progress + * @param {boolean} step + */ + bake(input, recipeConfig, options, progress, step) { + this.setBakingStatus(true); + + this.chefWorker.postMessage({ + action: "bake", + data: { + input: input, + recipeConfig: recipeConfig, + options: options, + progress: progress, + step: step + } + }); + } + + + /** + * Asks the ChefWorker to run a silent bake, forcing the browser to load and cache all the relevant + * JavaScript code needed to do a real bake. + * + * @param {Object[]} [recipeConfig] + */ + silentBake(recipeConfig) { + this.chefWorker.postMessage({ + action: "silentBake", + data: { + recipeConfig: recipeConfig + } + }); + } + + + /** + * Asks the ChefWorker to calculate highlight offsets if possible. + * + * @param {Object[]} recipeConfig + * @param {string} direction + * @param {Object} pos - The position object for the highlight. + * @param {number} pos.start - The start offset. + * @param {number} pos.end - The end offset. + */ + highlight(recipeConfig, direction, pos) { + this.chefWorker.postMessage({ + action: "highlight", + data: { + recipeConfig: recipeConfig, + direction: direction, + pos: pos + } + }); + } + + + /** + * Asks the ChefWorker to return the dish as the specified type + * + * @param {Dish} dish + * @param {string} type + * @param {Function} callback + */ + getDishAs(dish, type, callback) { + const id = this.callbackID++; + this.callbacks[id] = callback; + this.chefWorker.postMessage({ + action: "getDishAs", + data: { + dish: dish, + type: type, + id: id + } + }); + } + + + /** + * Sets the console log level in the worker. + * + * @param {string} level + */ + setLogLevel(level) { + if (!this.chefWorker) return; + + this.chefWorker.postMessage({ + action: "setLogLevel", + data: log.getLevel() + }); + } + +} + + +export default WorkerWaiter; diff --git a/src/web/html/index.html b/src/web/html/index.html index 41b74c72..5575999a 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -42,7 +42,7 @@ } // Define loading messages - const loadingMsgs = [ + var loadingMsgs = [ "Proving P = NP...", "Computing 6 x 9...", "Mining bitcoin...", @@ -66,18 +66,18 @@ // Shuffle array using Durstenfeld algorithm for (let i = loadingMsgs.length - 1; i > 0; --i) { - const j = Math.floor(Math.random() * (i + 1)); - const temp = loadingMsgs[i]; + var j = Math.floor(Math.random() * (i + 1)); + var temp = loadingMsgs[i]; loadingMsgs[i] = loadingMsgs[j]; loadingMsgs[j] = temp; } // Show next loading message and move it to the end of the array function changeLoadingMsg() { - const msg = loadingMsgs.shift(); + var msg = loadingMsgs.shift(); loadingMsgs.push(msg); try { - const el = document.getElementById("preloader-msg"); + var el = document.getElementById("preloader-msg"); if (!el.classList.contains("loading")) el.classList.add("loading"); // Causes CSS transition on first message el.innerHTML = msg; @@ -86,6 +86,46 @@ changeLoadingMsg(); window.loadingMsgsInt = setInterval(changeLoadingMsg, (Math.random() * 2000) + 1500); + + // If any errors are thrown during loading, handle them here + function loadingErrorHandler(e) { + function escapeHtml(str) { + var HTML_CHARS = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", // ' not recommended because it's not in the HTML spec + "/": "/", // forward slash is included as it helps end an HTML entity + "`": "`" + }; + + return str.replace(/[&<>"'/`]/g, function (match) { + return HTML_CHARS[match]; + }); + } + + var msg = e.message + + (e.filename ? "\nFilename: " + e.filename : "") + + (e.lineno ? "\nLine: " + e.lineno : "") + + (e.colno ? "\nColumn: " + e.colno : "") + + (e.error ? "\nError: " + e.error : "") + + "\nUser-Agent: " + navigator.userAgent + + "\nCyberChef version: <%= htmlWebpackPlugin.options.version %>"; + + clearInterval(window.loadingMsgsInt); + document.getElementById("preloader").remove(); + document.getElementById("preloader-msg").remove(); + document.getElementById("preloader-error").innerHTML = + "CyberChef encountered an error while loading.

    " + + "The following browser versions are supported:" + + "
    • Google Chrome 40+
    • Mozilla Firefox 35+
    • Microsoft Edge 14+
    " + + "Your user agent is:
    " + escapeHtml(navigator.userAgent) + "

    " + + "If your browser is supported, please " + + "raise an issue including the following details:

    " + + "
    " + escapeHtml(msg) + "
    "; + }; + window.addEventListener("error", loadingErrorHandler); <% if (htmlWebpackPlugin.options.inline) { %> @@ -100,6 +140,7 @@
    +
    Edit diff --git a/src/web/index.js b/src/web/index.js index 2dfc1c45..1daf36fa 100755 --- a/src/web/index.js +++ b/src/web/index.js @@ -13,11 +13,11 @@ import "bootstrap"; import "bootstrap-switch"; import "bootstrap-colorpicker"; import moment from "moment-timezone"; -import CanvasComponents from "../core/vendor/canvascomponents.js"; +import * as CanvasComponents from "../core/lib/CanvasComponents"; // CyberChef -import App from "./App.js"; -import Categories from "../core/config/Categories.js"; +import App from "./App"; +import Categories from "../core/config/Categories.json"; import OperationConfig from "../core/config/OperationConfig.json"; @@ -35,7 +35,8 @@ function main() { "URL Decode", "Regular expression", "Entropy", - "Fork" + "Fork", + "Magic" ]; const defaultOptions = { @@ -64,3 +65,4 @@ window.compileMessage = COMPILE_MSG; window.CanvasComponents = CanvasComponents; document.addEventListener("DOMContentLoaded", main, false); + diff --git a/src/web/stylesheets/preloader.css b/src/web/stylesheets/preloader.css index 0f3b070d..702d04a6 100755 --- a/src/web/stylesheets/preloader.css +++ b/src/web/stylesheets/preloader.css @@ -74,6 +74,14 @@ transition: all 0.1s ease-in; } +.loading-error { + display: block; + position: relative; + width: 600px; + left: calc(50% - 300px); + top: 10%; +} + /* Loaded */ .loaded .loading-msg { diff --git a/test/index.mjs b/test/index.mjs index 9714df95..428980e3 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -1,7 +1,7 @@ /* eslint no-console: 0 */ /** - * TestRunner.js + * Test Runner * * For running the tests in the test register. * @@ -24,36 +24,42 @@ global.ENVIRONMENT_IS_WEB = function() { }; import TestRegister from "./TestRegister"; -// import "./tests/operations/Base58.js"; +import "./tests/operations/Base58"; import "./tests/operations/Base64"; -// import "./tests/operations/BCD.js"; -// import "./tests/operations/BitwiseOp.js"; -// import "./tests/operations/BSON.js"; -// import "./tests/operations/ByteRepr.js"; -// import "./tests/operations/CharEnc.js"; -// import "./tests/operations/Cipher.js"; -// import "./tests/operations/Code.js"; -// import "./tests/operations/Compress.js"; -// import "./tests/operations/DateTime.js"; -// import "./tests/operations/FlowControl.js"; -// import "./tests/operations/Hash.js"; -// import "./tests/operations/Hexdump.js"; -// import "./tests/operations/Image.js"; -// import "./tests/operations/MorseCode.js"; -// import "./tests/operations/MS.js"; -// import "./tests/operations/PHP.js"; -// import "./tests/operations/NetBIOS.js"; -// import "./tests/operations/OTP.js"; -// import "./tests/operations/Regex.js"; -import "./tests/operations/Rotate.mjs"; -// import "./tests/operations/StrUtils.js"; -// import "./tests/operations/SeqUtils.js"; -import "./tests/operations/SetUnion"; -import "./tests/operations/SetIntersection"; -import "./tests/operations/SetDifference"; -import "./tests/operations/SymmetricDifference"; +import "./tests/operations/BCD"; +// import "./tests/operations/BitwiseOp"; +import "./tests/operations/BSON"; +import "./tests/operations/ByteRepr"; import "./tests/operations/CartesianProduct"; +import "./tests/operations/CharEnc"; +import "./tests/operations/Ciphers"; +import "./tests/operations/Checksum"; +// import "./tests/operations/Code"; +import "./tests/operations/Compress"; +// import "./tests/operations/Crypt"; +import "./tests/operations/DateTime"; +import "./tests/operations/Fork"; +import "./tests/operations/Jump"; +import "./tests/operations/ConditionalJump"; +import "./tests/operations/Register"; +import "./tests/operations/Comment"; +import "./tests/operations/Hash"; +import "./tests/operations/Hexdump"; +// import "./tests/operations/Image"; +import "./tests/operations/MorseCode"; +import "./tests/operations/MS"; +import "./tests/operations/PHP"; +import "./tests/operations/NetBIOS"; +import "./tests/operations/OTP"; import "./tests/operations/PowerSet"; +// import "./tests/operations/Regex"; +import "./tests/operations/Rotate"; +// import "./tests/operations/StrUtils"; +import "./tests/operations/SeqUtils"; +import "./tests/operations/SetDifference"; +import "./tests/operations/SetIntersection"; +import "./tests/operations/SetUnion"; +import "./tests/operations/SymmetricDifference"; import "./tests/nodeApi/nodeApi"; diff --git a/test/tests/operations/BCD.js b/test/tests/operations/BCD.mjs old mode 100755 new mode 100644 similarity index 98% rename from test/tests/operations/BCD.js rename to test/tests/operations/BCD.mjs index 427f64d2..6f00abe4 --- a/test/tests/operations/BCD.js +++ b/test/tests/operations/BCD.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/BSON.js b/test/tests/operations/BSON.mjs old mode 100755 new mode 100644 similarity index 96% rename from test/tests/operations/BSON.js rename to test/tests/operations/BSON.mjs index 61ee10c4..2b99d845 --- a/test/tests/operations/BSON.js +++ b/test/tests/operations/BSON.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2018 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Base58.js b/test/tests/operations/Base58.mjs old mode 100755 new mode 100644 similarity index 97% rename from test/tests/operations/Base58.js rename to test/tests/operations/Base58.mjs index d09a3fc4..ccb7a26c --- a/test/tests/operations/Base58.js +++ b/test/tests/operations/Base58.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/BitwiseOp.js b/test/tests/operations/BitwiseOp.mjs old mode 100755 new mode 100644 similarity index 97% rename from test/tests/operations/BitwiseOp.js rename to test/tests/operations/BitwiseOp.mjs index ba196be2..7fdedded --- a/test/tests/operations/BitwiseOp.js +++ b/test/tests/operations/BitwiseOp.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/ByteRepr.js b/test/tests/operations/ByteRepr.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/ByteRepr.js rename to test/tests/operations/ByteRepr.mjs index 13fbd4cc..913755b8 --- a/test/tests/operations/ByteRepr.js +++ b/test/tests/operations/ByteRepr.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; const ALL_BYTES = [ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", diff --git a/test/tests/operations/CharEnc.js b/test/tests/operations/CharEnc.mjs old mode 100755 new mode 100644 similarity index 97% rename from test/tests/operations/CharEnc.js rename to test/tests/operations/CharEnc.mjs index f5e07507..c7c5f0c0 --- a/test/tests/operations/CharEnc.js +++ b/test/tests/operations/CharEnc.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Checksum.mjs b/test/tests/operations/Checksum.mjs new file mode 100644 index 00000000..eac94038 --- /dev/null +++ b/test/tests/operations/Checksum.mjs @@ -0,0 +1,120 @@ +/** + * Checksum tests. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +const BASIC_STRING = "The ships hung in the sky in much the same way that bricks don't."; +const UTF8_STR = "ნუ პანიკას"; +const ALL_BYTES = [ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f", + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f", + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", +].join(""); + +TestRegister.addTests([ + { + name: "CRC-16: nothing", + input: "", + expectedOutput: "0000", + recipeConfig: [ + { + "op": "CRC-16 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16: basic string", + input: BASIC_STRING, + expectedOutput: "0c70", + recipeConfig: [ + { + "op": "CRC-16 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16: UTF-8", + input: UTF8_STR, + expectedOutput: "dcf6", + recipeConfig: [ + { + "op": "CRC-16 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16: all bytes", + input: ALL_BYTES, + expectedOutput: "bad3", + recipeConfig: [ + { + "op": "CRC-16 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-32: nothing", + input: "", + expectedOutput: "00000000", + recipeConfig: [ + { + "op": "CRC-32 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-32: basic string", + input: BASIC_STRING, + expectedOutput: "bf4b739c", + recipeConfig: [ + { + "op": "CRC-32 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-32: UTF-8", + input: UTF8_STR, + expectedOutput: "87553290", + recipeConfig: [ + { + "op": "CRC-32 Checksum", + "args": [] + } + ] + }, + { + name: "CRC-32: all bytes", + input: ALL_BYTES, + expectedOutput: "29058c73", + recipeConfig: [ + { + "op": "CRC-32 Checksum", + "args": [] + } + ] + }, +]); diff --git a/test/tests/operations/Ciphers.mjs b/test/tests/operations/Ciphers.mjs new file mode 100644 index 00000000..553216ef --- /dev/null +++ b/test/tests/operations/Ciphers.mjs @@ -0,0 +1,355 @@ +/** + * Cipher tests. + * + * @author Matt C [matt@artemisbot.uk] + * @author n1474335 [n1474335@gmail.com] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + + +TestRegister.addTests([ + { + name: "Affine Encode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Affine Cipher Encode", + args: [1, 0] + } + ], + }, + { + name: "Affine Encode: invalid a & b (non-integer)", + input: "some keys are shaped as locks. index[me]", + expectedOutput: "The values of a and b can only be integers.", + recipeConfig: [ + { + op: "Affine Cipher Encode", + args: [0.1, 0.00001] + } + ], + }, + { + name: "Affine Encode: no effect", + input: "some keys are shaped as locks. index[me]", + expectedOutput: "some keys are shaped as locks. index[me]", + recipeConfig: [ + { + op: "Affine Cipher Encode", + args: [1, 0] + } + ], + }, + { + name: "Affine Encode: normal", + input: "some keys are shaped as locks. index[me]", + expectedOutput: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + recipeConfig: [ + { + op: "Affine Cipher Encode", + args: [23, 23] + } + ], + }, + { + name: "Affine Decode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Affine Cipher Decode", + args: [1, 0] + } + ], + }, + { + name: "Affine Decode: invalid a & b (non-integer)", + input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + expectedOutput: "The values of a and b can only be integers.", + recipeConfig: [ + { + op: "Affine Cipher Decode", + args: [0.1, 0.00001] + } + ], + }, + { + name: "Affine Decode: invalid a (coprime)", + input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + expectedOutput: "The value of `a` must be coprime to 26.", + recipeConfig: [ + { + op: "Affine Cipher Decode", + args: [8, 23] + } + ], + }, + { + name: "Affine Decode: no effect", + input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + expectedOutput: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + recipeConfig: [ + { + op: "Affine Cipher Decode", + args: [1, 0] + } + ], + }, + { + name: "Affine Decode: normal", + input: "vhnl tldv xyl vcxelo xv qhrtv. zkolg[nl]", + expectedOutput: "some keys are shaped as locks. index[me]", + recipeConfig: [ + { + op: "Affine Cipher Decode", + args: [23, 23] + } + ], + }, + { + name: "Atbash: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Atbash Cipher", + args: [] + } + ], + }, + { + name: "Atbash: normal", + input: "old slow slim horn", + expectedOutput: "low hold horn slim", + recipeConfig: [ + { + op: "Atbash Cipher", + args: [] + } + ], + }, + { + name: "Bifid Cipher Encode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Bifid Cipher Encode", + "args": ["nothing"] + } + ], + }, + { + name: "Bifid Cipher Encode: no key", + input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", + expectedOutput: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.", + recipeConfig: [ + { + "op": "Bifid Cipher Encode", + "args": [""] + } + ], + }, + { + name: "Bifid Cipher Encode: invalid key (non-alphabetic)", + input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", + expectedOutput: "The key must consist only of letters in the English alphabet", + recipeConfig: [ + { + "op": "Bifid Cipher Encode", + "args": ["abc123"] + } + ], + }, + { + name: "Bifid Cipher Encode: normal", + input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", + expectedOutput: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.", + recipeConfig: [ + { + "op": "Bifid Cipher Encode", + "args": ["Schrodinger"] + } + ], + }, + { + name: "Bifid Cipher Decode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Bifid Cipher Decode", + "args": ["nothing"] + } + ], + }, + { + name: "Bifid Cipher Decode: no key", + input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.", + expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", + recipeConfig: [ + { + "op": "Bifid Cipher Decode", + "args": [""] + } + ], + }, + { + name: "Bifid Cipher Decode: invalid key (non-alphabetic)", + input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.", + expectedOutput: "The key must consist only of letters in the English alphabet", + recipeConfig: [ + { + "op": "Bifid Cipher Decode", + "args": ["abc123"] + } + ], + }, + { + name: "Bifid Cipher Decode: normal", + input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.", + expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", + recipeConfig: [ + { + "op": "Bifid Cipher Decode", + "args": ["Schrodinger"] + } + ], + }, + { + name: "Vigenère Encode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Vigenère Encode", + "args": ["nothing"] + } + ], + }, + { + name: "Vigenère Encode: no key", + input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID", + expectedOutput: "No key entered", + recipeConfig: [ + { + "op": "Vigenère Encode", + "args": [""] + } + ], + }, + { + name: "Vigenère Encode: invalid key", + input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID", + expectedOutput: "The key must consist only of letters", + recipeConfig: [ + { + "op": "Vigenère Encode", + "args": ["abc123"] + } + ], + }, + { + name: "Vigenère Encode: normal", + input: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID", + expectedOutput: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED", + recipeConfig: [ + { + "op": "Vigenère Encode", + "args": ["Edward"] + } + ], + }, + { + name: "Vigenère Decode: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Vigenère Decode", + "args": ["nothing"] + } + ], + }, + { + name: "Vigenère Decode: no key", + input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED", + expectedOutput: "No key entered", + recipeConfig: [ + { + "op": "Vigenère Decode", + "args": [""] + } + ], + }, + { + name: "Vigenère Decode: invalid key", + input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED", + expectedOutput: "The key must consist only of letters", + recipeConfig: [ + { + "op": "Vigenère Decode", + "args": ["abc123"] + } + ], + }, + { + name: "Vigenère Decode: normal", + input: "PXCGRJIEWSVPIQPVRUIQJEJDPOEEJFEQXETOSWDEUDWHJEDLIVANVPMHOCRQFHYLFWLHZAJDPOEEJDPZWYJXWHED", + expectedOutput: "LUGGAGEBASEMENTVARENNESALLIESCANBECLOTHEDASENEMIESENEMIESCANBECLOTHEDASALLIESALWAYSUSEID", + recipeConfig: [ + { + "op": "Vigenère Decode", + "args": ["Edward"] + } + ], + }, + { + name: "Substitute: no pt/ct", + input: "flee at once. we are discovered!", + expectedOutput: "flee at once. we are discovered!", + recipeConfig: [ + { + "op": "Substitute", + "args": ["", ""] + } + ], + }, + { + name: "Substitute: no input", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Substitute", + "args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwxy"] + } + ], + }, + { + name: "Substitute: uneven pt/ct", + input: "flee at once. we are discovered!", + expectedOutput: "Warning: Plaintext and Ciphertext lengths differ\n\nsiaa zq lkba. va zoa rfpbluaoar!", + recipeConfig: [ + { + "op": "Substitute", + "args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwx"] + } + ], + }, + { + name: "Substitute: normal", + input: "flee at once. we are discovered!", + expectedOutput: "siaa zq lkba. va zoa rfpbluaoar!", + recipeConfig: [ + { + "op": "Substitute", + "args": ["abcdefghijklmnopqrstuvwxyz", "zebrascdfghijklmnopqtuvwxy"] + } + ], + }, +]); diff --git a/test/tests/operations/Code.js b/test/tests/operations/Code.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/Code.js rename to test/tests/operations/Code.mjs index b13dcfd9..3b282b67 --- a/test/tests/operations/Code.js +++ b/test/tests/operations/Code.mjs @@ -7,7 +7,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; const JPATH_TEST_DATA = { "store": { diff --git a/test/tests/operations/Comment.mjs b/test/tests/operations/Comment.mjs new file mode 100644 index 00000000..109fd761 --- /dev/null +++ b/test/tests/operations/Comment.mjs @@ -0,0 +1,76 @@ +/** + * Flow Control tests. + * + * @author tlwr [toby@toby.codes] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +const ALL_BYTES = [ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f", + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f", + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", +].join(""); + +TestRegister.addTests([ + { + name: "Comment: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "Comment", + "args": [""] + } + ] + }, + { + name: "Fork, Comment, Base64", + input: "cat\nsat\nmat", + expectedOutput: "Y2F0\nc2F0\nbWF0\n", + recipeConfig: [ + { + "op": "Fork", + "args": ["\\n", "\\n", false] + }, + { + "op": "Comment", + "args": ["Testing 123"] + }, + { + "op": "To Base64", + "args": ["A-Za-z0-9+/="] + } + ] + }, + { + name: "Label, Comment: Complex content", + input: ALL_BYTES, + expectedOutput: ALL_BYTES, + recipeConfig: [ + { + op: "Label", + args: [""] + }, + { + op: "Comment", + args: [""] + } + ] + } +]); diff --git a/test/tests/operations/Compress.js b/test/tests/operations/Compress.mjs old mode 100755 new mode 100644 similarity index 92% rename from test/tests/operations/Compress.js rename to test/tests/operations/Compress.mjs index 48f1de81..03a041ac --- a/test/tests/operations/Compress.js +++ b/test/tests/operations/Compress.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/ConditionalJump.mjs b/test/tests/operations/ConditionalJump.mjs new file mode 100644 index 00000000..556440b2 --- /dev/null +++ b/test/tests/operations/ConditionalJump.mjs @@ -0,0 +1,93 @@ +/** + * Conditional Jump tests + * + * @author tlwr [toby@toby.codes] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Conditional Jump: Skips 0", + input: [ + "should be changed", + ].join("\n"), + expectedOutput: [ + "YzJodmRXeGtJR0psSUdOb1lXNW5aV1E9" + ].join("\n"), + recipeConfig: [ + { + op: "Conditional Jump", + args: ["match", false, "", 0], + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="], + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="], + }, + ], + }, + { + name: "Conditional Jump: Skips 1", + input: [ + "should be changed", + ].join("\n"), + // Expecting base32, not base64 output + expectedOutput: [ + "ONUG65LMMQQGEZJAMNUGC3THMVSA====", + ].join("\n"), + recipeConfig: [ + { + op: "Conditional Jump", + args: ["should", false, "skip match", 10], + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="], + }, + { + op: "Label", args: ["skip match"], + }, + { + op: "To Base32", + args: ["A-Z2-7="], + }, + ], + }, + { + name: "Conditional Jump: Skips backwards", + input: [ + "match", + ].join("\n"), + expectedOutput: [ + "f7cf556f7f4fc6635db8c314f7a81f2a", + ].join("\n"), + recipeConfig: [ + { + op: "Label", + args: ["back to the beginning"], + }, + { + op: "Jump", + args: ["skip replace"], + }, + { + op: "MD2", + args: [], + }, + { + op: "Label", + args: ["skip replace"], + }, + { + op: "Conditional Jump", + args: ["match", false, "back to the beginning", 10], + }, + ], + } +]); diff --git a/test/tests/operations/Cipher.js b/test/tests/operations/Crypt.mjs old mode 100755 new mode 100644 similarity index 96% rename from test/tests/operations/Cipher.js rename to test/tests/operations/Crypt.mjs index 6b21debc..5e2a3321 --- a/test/tests/operations/Cipher.js +++ b/test/tests/operations/Crypt.mjs @@ -1,82 +1,14 @@ /** - * Cipher tests. + * Crypt tests. * - * @author Matt C [matt@artemisbot.uk] * @author n1474335 [n1474335@gmail.com] * - * @copyright Crown Copyright 2017 + * @copyright Crown Copyright 2018 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ - { - name: "Bifid Cipher Encode: no input", - input: "", - expectedOutput: "", - recipeConfig: [ - { - "op": "Bifid Cipher Encode", - "args": ["nothing"] - } - ], - }, - { - name: "Bifid Cipher Encode: no key", - input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", - expectedOutput: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.", - recipeConfig: [ - { - "op": "Bifid Cipher Encode", - "args": [""] - } - ], - }, - { - name: "Bifid Cipher Encode: normal", - input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", - expectedOutput: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.", - recipeConfig: [ - { - "op": "Bifid Cipher Encode", - "args": ["Schrodinger"] - } - ], - }, - { - name: "Bifid Cipher Decode: no input", - input: "", - expectedOutput: "", - recipeConfig: [ - { - "op": "Bifid Cipher Decode", - "args": ["nothing"] - } - ], - }, - { - name: "Bifid Cipher Decode: no key", - input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.", - expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", - recipeConfig: [ - { - "op": "Bifid Cipher Decode", - "args": [""] - } - ], - }, - { - name: "Bifid Cipher Decode: normal", - input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.", - expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.", - recipeConfig: [ - { - "op": "Bifid Cipher Decode", - "args": ["Schrodinger"] - } - ], - }, - /** * Ciphers * diff --git a/test/tests/operations/DateTime.js b/test/tests/operations/DateTime.mjs old mode 100755 new mode 100644 similarity index 94% rename from test/tests/operations/DateTime.js rename to test/tests/operations/DateTime.mjs index f8226ac6..fa19d4d9 --- a/test/tests/operations/DateTime.js +++ b/test/tests/operations/DateTime.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/FlowControl.js b/test/tests/operations/FlowControl.js deleted file mode 100755 index 49b13026..00000000 --- a/test/tests/operations/FlowControl.js +++ /dev/null @@ -1,391 +0,0 @@ -/** - * Flow Control tests. - * - * @author tlwr [toby@toby.codes] - * - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - */ -import TestRegister from "../../TestRegister.js"; - -const ALL_BYTES = [ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f", - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f", - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f", - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f", - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f", - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", - "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", -].join(""); - -TestRegister.addTests([ - { - name: "Fork: nothing", - input: "", - expectedOutput: "", - recipeConfig: [ - { - op: "Fork", - args: ["\n", "\n", false], - }, - ], - }, - { - name: "Fork, Merge: nothing", - input: "", - expectedOutput: "", - recipeConfig: [ - { - op: "Fork", - args: ["\n", "\n", false], - }, - { - op: "Merge", - args: [], - }, - ], - }, - { - name: "Fork, (expect) Error, Merge", - input: "1.1\n2.5\na\n3.4", - expectedError: true, - recipeConfig: [ - { - op: "Fork", - args: ["\n", "\n", false], - }, - { - op: "Object Identifier to Hex", - args: [], - }, - { - op: "Merge", - args: [], - }, - ], - }, - { - name: "Fork, Conditional Jump, Encodings", - input: "Some data with a 1 in it\nSome data with a 2 in it", - expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n", - recipeConfig: [ - {"op": "Fork", "args": ["\\n", "\\n", false]}, - {"op": "Conditional Jump", "args": ["1", false, "skipReturn", "10"]}, - {"op": "To Hex", "args": ["Space"]}, - {"op": "Return", "args": []}, - {"op": "Label", "args": ["skipReturn"]}, - {"op": "To Base64", "args": ["A-Za-z0-9+/="]} - ] - }, - { - name: "Jump: Empty Label", - input: [ - "should be changed", - ].join("\n"), - expectedOutput: [ - "should be changed was changed", - ].join("\n"), - recipeConfig: [ - { - op: "Jump", - args: ["", 10], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "should be changed" - }, - "should be changed was changed", - true, - true, - true, - ], - }, - ], - }, - { - name: "Jump: skips 1", - input: [ - "shouldnt be changed", - ].join("\n"), - expectedOutput: [ - "shouldnt be changed", - ].join("\n"), - recipeConfig: [ - { - op: "Jump", - args: ["skipReplace", 10], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "shouldnt be changed" - }, - "shouldnt be changed was changed", - true, - true, - true, - ], - }, - { - op: "Label", - args: ["skipReplace"] - }, - ], - }, - { - name: "Conditional Jump: Skips 0", - input: [ - "match", - "should be changed 1", - "should be changed 2", - ].join("\n"), - expectedOutput: [ - "match", - "should be changed 1 was changed", - "should be changed 2 was changed" - ].join("\n"), - recipeConfig: [ - { - op: "Conditional Jump", - args: ["match", false, "", 0], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "should be changed 1" - }, - "should be changed 1 was changed", - true, - true, - true, - ], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "should be changed 2" - }, - "should be changed 2 was changed", - true, - true, - true, - ], - }, - ], - }, - { - name: "Comment: nothing", - input: "", - expectedOutput: "", - recipeConfig: [ - { - "op": "Comment", - "args": [""] - } - ] - }, - { - name: "Fork, Comment, Base64", - input: "cat\nsat\nmat", - expectedOutput: "Y2F0\nc2F0\nbWF0\n", - recipeConfig: [ - { - "op": "Fork", - "args": ["\\n", "\\n", false] - }, - { - "op": "Comment", - "args": ["Testing 123"] - }, - { - "op": "To Base64", - "args": ["A-Za-z0-9+/="] - } - ] - }, - { - name: "Conditional Jump: Skips 1", - input: [ - "match", - "should not be changed", - "should be changed", - ].join("\n"), - expectedOutput: [ - "match", - "should not be changed", - "should be changed was changed" - ].join("\n"), - recipeConfig: [ - { - op: "Conditional Jump", - args: ["match", false, "skip match", 10], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "should not be changed" - }, - "should not be changed was changed", - true, - true, - true, - ], - }, - { - op: "Label", args: ["skip match"], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "should be changed" - }, - "should be changed was changed", - true, - true, - true, - ], - }, - ], - }, - { - name: "Conditional Jump: Skips backwards", - input: [ - "match", - ].join("\n"), - expectedOutput: [ - "replaced", - ].join("\n"), - recipeConfig: [ - { - op: "Label", - args: ["back to the beginning"], - }, - { - op: "Jump", - args: ["skip replace"], - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": "match" - }, - "replaced", - true, - true, - true, - ], - }, - { - op: "Label", - args: ["skip replace"], - }, - { - op: "Conditional Jump", - args: ["match", false, "back to the beginning", 10], - }, - ], - }, - { - name: "Register: RC4 key", - input: "http://malwarez.biz/beacon.php?key=0e932a5c&data=8db7d5ebe38663a54ecbb334e3db11", - expectedOutput: "All the secrets", - recipeConfig: [ - { - op: "Register", - args: ["key=([\\da-f]*)", true, false] - }, - { - op: "Find / Replace", - args: [ - { - "option": "Regex", - "string": ".*data=(.*)" - }, "$1", true, false, true - ] - }, - { - op: "RC4", - args: [ - { - "option": "Hex", - "string": "$R0" - }, "Hex", "Latin1" - ] - } - ] - }, - { - name: "Register: AES key", - input: "51e201d463698ef5f717f71f5b4712af20be674b3bff53d38546396ee61daac4908e319ca3fcf7089bfb6b38ea99e781d26e577ba9dd6f311a39420b8978e93014b042d44726caedf5436eaf652429c0df94b521676c7c2ce812097c277273c7c72cd89aec8d9fb4a27586ccf6aa0aee224c34ba3bfdf7aeb1ddd477622b91e72c9e709ab60f8daf731ec0cc85ce0f746ff1554a5a3ec291ca40f9e629a872592d988fdd834534aba79c1ad1676769a7c010bf04739ecdb65d95302371d629d9e37e7b4a361da468f1ed5358922d2ea752dd11c366f3017b14aa011d2af03c44f95579098a15e3cf9b4486f8ffe9c239f34de7151f6ca6500fe4b850c3f1c02e801caf3a24464614e42801615b8ffaa07ac8251493ffda7de5ddf3368880c2b95b030f41f8f15066add071a66cf60e5f46f3a230d397b652963a21a53f", - expectedOutput: `"You know," said Arthur, "it's at times like this, when I'm trapped in a Vogon airlock with a man from Betelgeuse, and about to die of asphyxiation in deep space that I really wish I'd listened to what my mother told me when I was young." -"Why, what did she tell you?" -"I don't know, I didn't listen."`, - recipeConfig: [ - { - op: "Register", - args: ["(.{32})", true, false] - }, - { - op: "Drop bytes", - args: [0, 32, false] - }, - { - op: "AES Decrypt", - args: [ - { - "option": "Hex", - "string": "1748e7179bd56570d51fa4ba287cc3e5" - }, - { - "option": "Hex", - "string": "$R0" - }, - "CTR", "Hex", "Raw", - { - "option": "Hex", - "string": "" - } - ] - } - ] - }, - { - name: "Label, Comment: Complex content", - input: ALL_BYTES, - expectedOutput: ALL_BYTES, - recipeConfig: [ - { - op: "Label", - args: [""] - }, - { - op: "Comment", - args: [""] - } - ] - }, -]); diff --git a/test/tests/operations/Fork.mjs b/test/tests/operations/Fork.mjs new file mode 100644 index 00000000..de6adf04 --- /dev/null +++ b/test/tests/operations/Fork.mjs @@ -0,0 +1,70 @@ +/** + * Fork tests + * + * @author tlwr [toby@toby.codes] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Fork: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Fork", + args: ["\n", "\n", false], + }, + ], + }, + { + name: "Fork, Merge: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Fork", + args: ["\n", "\n", false], + }, + { + op: "Merge", + args: [], + }, + ], + }, + { + name: "Fork, (expect) Error, Merge", + input: "1,2,3,4\n\n3,4,5,6", + expectedOutput: "Incorrect number of sets, perhaps you need to modify the sample delimiter or add more samples?", + recipeConfig: [ + { + op: "Fork", + args: ["\n\n", "\n\n", false], + }, + { + op: "Set Union", + args: ["\n\n", ","], + }, + { + op: "Merge", + args: [], + }, + ], + }, + { + name: "Fork, Conditional Jump, Encodings", + input: "Some data with a 1 in it\nSome data with a 2 in it", + expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n", + recipeConfig: [ + {"op": "Fork", "args": ["\\n", "\\n", false]}, + {"op": "Conditional Jump", "args": ["1", false, "skipReturn", "10"]}, + {"op": "To Hex", "args": ["Space"]}, + {"op": "Return", "args": []}, + {"op": "Label", "args": ["skipReturn"]}, + {"op": "To Base64", "args": ["A-Za-z0-9+/="]} + ] + } +]); diff --git a/test/tests/operations/Hash.js b/test/tests/operations/Hash.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/Hash.js rename to test/tests/operations/Hash.mjs index b1f27479..7105945c --- a/test/tests/operations/Hash.js +++ b/test/tests/operations/Hash.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Hexdump.js b/test/tests/operations/Hexdump.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/Hexdump.js rename to test/tests/operations/Hexdump.mjs index 842e1fd9..7dff3f81 --- a/test/tests/operations/Hexdump.js +++ b/test/tests/operations/Hexdump.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2018 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; const ALL_BYTES = [ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", diff --git a/test/tests/operations/Image.js b/test/tests/operations/Image.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/Image.js rename to test/tests/operations/Image.mjs index be822c8b..4cb405e3 --- a/test/tests/operations/Image.js +++ b/test/tests/operations/Image.mjs @@ -7,7 +7,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Jump.mjs b/test/tests/operations/Jump.mjs new file mode 100644 index 00000000..929432af --- /dev/null +++ b/test/tests/operations/Jump.mjs @@ -0,0 +1,54 @@ +/** + * Jump tests + * + * @author tlwr [toby@toby.codes] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Jump: Empty Label", + input: [ + "should be changed", + ].join("\n"), + expectedOutput: [ + "c2hvdWxkIGJlIGNoYW5nZWQ=", + ].join("\n"), + recipeConfig: [ + { + op: "Jump", + args: ["", 10], + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="], + }, + ], + }, + { + name: "Jump: skips 1", + input: [ + "shouldnt be changed", + ].join("\n"), + expectedOutput: [ + "shouldnt be changed", + ].join("\n"), + recipeConfig: [ + { + op: "Jump", + args: ["skipReplace", 10], + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="], + }, + { + op: "Label", + args: ["skipReplace"] + }, + ], + } +]); diff --git a/test/tests/operations/MS.js b/test/tests/operations/MS.mjs old mode 100755 new mode 100644 similarity index 91% rename from test/tests/operations/MS.js rename to test/tests/operations/MS.mjs index acf0f085..f6018832 --- a/test/tests/operations/MS.js +++ b/test/tests/operations/MS.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/MorseCode.js b/test/tests/operations/MorseCode.mjs old mode 100755 new mode 100644 similarity index 93% rename from test/tests/operations/MorseCode.js rename to test/tests/operations/MorseCode.mjs index 4f4d59fa..ea8278ea --- a/test/tests/operations/MorseCode.js +++ b/test/tests/operations/MorseCode.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/NetBIOS.js b/test/tests/operations/NetBIOS.mjs old mode 100755 new mode 100644 similarity index 93% rename from test/tests/operations/NetBIOS.js rename to test/tests/operations/NetBIOS.mjs index 2994b79e..291412fe --- a/test/tests/operations/NetBIOS.js +++ b/test/tests/operations/NetBIOS.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/OTP.js b/test/tests/operations/OTP.mjs old mode 100755 new mode 100644 similarity index 91% rename from test/tests/operations/OTP.js rename to test/tests/operations/OTP.mjs index b321e7cf..ccb215a4 --- a/test/tests/operations/OTP.js +++ b/test/tests/operations/OTP.mjs @@ -6,7 +6,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/PHP.js b/test/tests/operations/PHP.mjs old mode 100755 new mode 100644 similarity index 96% rename from test/tests/operations/PHP.js rename to test/tests/operations/PHP.mjs index a42ee430..19a5bc86 --- a/test/tests/operations/PHP.js +++ b/test/tests/operations/PHP.mjs @@ -7,7 +7,7 @@ * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Regex.js b/test/tests/operations/Regex.mjs old mode 100755 new mode 100644 similarity index 96% rename from test/tests/operations/Regex.js rename to test/tests/operations/Regex.mjs index dc16910f..a987bbeb --- a/test/tests/operations/Regex.js +++ b/test/tests/operations/Regex.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/Register.mjs b/test/tests/operations/Register.mjs new file mode 100644 index 00000000..a66a5832 --- /dev/null +++ b/test/tests/operations/Register.mjs @@ -0,0 +1,71 @@ +/** + * Register tests + * + * @author tlwr [toby@toby.codes] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "Register: RC4 key", + input: "http://malwarez.biz/beacon.php?key=0e932a5c&data=8db7d5ebe38663a54ecbb334e3db11", + expectedOutput: "zNu5y53uBoU2rm7qhq9ijjnVHSlJ9PJ/zpp+xL/to8qIBzkDwKzUNQ==", + recipeConfig: [ + { + op: "Register", + args: ["key=([\\da-f]*)", true, false] + }, + { + op: "RC4", + args: [ + { + "option": "Hex", + "string": "$R0" + }, "Hex", "Latin1" + ] + }, + { + op: "To Base64", + args: ["A-Za-z0-9+/="] + } + ] + }, + { + name: "Register: AES key", + input: "51e201d463698ef5f717f71f5b4712af20be674b3bff53d38546396ee61daac4908e319ca3fcf7089bfb6b38ea99e781d26e577ba9dd6f311a39420b8978e93014b042d44726caedf5436eaf652429c0df94b521676c7c2ce812097c277273c7c72cd89aec8d9fb4a27586ccf6aa0aee224c34ba3bfdf7aeb1ddd477622b91e72c9e709ab60f8daf731ec0cc85ce0f746ff1554a5a3ec291ca40f9e629a872592d988fdd834534aba79c1ad1676769a7c010bf04739ecdb65d95302371d629d9e37e7b4a361da468f1ed5358922d2ea752dd11c366f3017b14aa011d2af03c44f95579098a15e3cf9b4486f8ffe9c239f34de7151f6ca6500fe4b850c3f1c02e801caf3a24464614e42801615b8ffaa07ac8251493ffda7de5ddf3368880c2b95b030f41f8f15066add071a66cf60e5f46f3a230d397b652963a21a53f", + expectedOutput: `"You know," said Arthur, "it's at times like this, when I'm trapped in a Vogon airlock with a man from Betelgeuse, and about to die of asphyxiation in deep space that I really wish I'd listened to what my mother told me when I was young." +"Why, what did she tell you?" +"I don't know, I didn't listen."`, + recipeConfig: [ + { + op: "Register", + args: ["(.{32})", true, false] + }, + { + op: "Drop bytes", + args: [0, 32, false] + }, + { + op: "AES Decrypt", + args: [ + { + "option": "Hex", + "string": "1748e7179bd56570d51fa4ba287cc3e5" + }, + { + "option": "Hex", + "string": "$R0" + }, + "CTR", "Hex", "Raw", + { + "option": "Hex", + "string": "" + } + ] + } + ] + } +]); diff --git a/test/tests/operations/SeqUtils.js b/test/tests/operations/SeqUtils.mjs old mode 100755 new mode 100644 similarity index 95% rename from test/tests/operations/SeqUtils.js rename to test/tests/operations/SeqUtils.mjs index 52fbaf32..88acde8f --- a/test/tests/operations/SeqUtils.js +++ b/test/tests/operations/SeqUtils.mjs @@ -5,7 +5,7 @@ * @copyright Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/test/tests/operations/StrUtils.js b/test/tests/operations/StrUtils.mjs old mode 100755 new mode 100644 similarity index 99% rename from test/tests/operations/StrUtils.js rename to test/tests/operations/StrUtils.mjs index 4777fd10..433593fc --- a/test/tests/operations/StrUtils.js +++ b/test/tests/operations/StrUtils.mjs @@ -5,7 +5,7 @@ * @copyright Crown Copyright 2017 * @license Apache-2.0 */ -import TestRegister from "../../TestRegister.js"; +import TestRegister from "../../TestRegister"; TestRegister.addTests([ { diff --git a/webpack.config.js b/webpack.config.js index cfdf8802..99552a9b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,5 @@ const webpack = require("webpack"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); -const WebpackSyncShellPlugin = require("webpack-synchronizable-shell-plugin"); /** * Webpack configuration details for use with Grunt. @@ -43,18 +42,7 @@ module.exports = { raw: true, entryOnly: true }), - new ExtractTextPlugin("styles.css"), - new WebpackSyncShellPlugin({ - onBuildStart: { - scripts: [ - "node --experimental-modules src/core/config/scripts/generateOpsIndex.mjs", - "node --experimental-modules src/core/config/scripts/generateConfig.mjs", - "echo ---\nConfig scripts finished.\n---\n" - ], - blocking: true, - parallel: false - } - }) + new ExtractTextPlugin("styles.css") ], resolve: { alias: { @@ -65,9 +53,14 @@ module.exports = { rules: [ { test: /\.m?js$/, - exclude: /node_modules/, + exclude: /node_modules\/(?!jsesc|crypto-api)/, + type: "javascript/auto", loader: "babel-loader?compact=false" }, + { + test: /forge.min.js$/, + loader: "imports-loader?jQuery=>null" + }, { test: /\.css$/, use: ExtractTextPlugin.extract({ @@ -117,7 +110,7 @@ module.exports = { chunks: false, modules: false, entrypoints: false, - warningsFilter: /source-map/, + warningsFilter: [/source-map/, /dependency is an expression/], }, node: { fs: "empty"