From cfd9b16f8b16c399e057cfd39c9e45f86af845b7 Mon Sep 17 00:00:00 2001 From: slurdge Date: Mon, 9 Oct 2017 15:43:37 +0200 Subject: [PATCH 001/124] Factorize all CryptoApi.hash calls and pass string directly. Fixes #193 --- src/core/operations/Hash.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/core/operations/Hash.js b/src/core/operations/Hash.js index 6d1d3a16..d297c624 100755 --- a/src/core/operations/Hash.js +++ b/src/core/operations/Hash.js @@ -16,6 +16,14 @@ import Checksum from "./Checksum.js"; */ const Hash = { + runHash: function(name, input) { + var hasher = CryptoApi.hasher(name); + hasher.state.message = input; + hasher.state.length += input.length; + hasher.process(); + return hasher.finalize().stringify('hex'); + }, + /** * MD2 operation. * @@ -24,7 +32,7 @@ const Hash = { * @returns {string} */ runMD2: function (input, args) { - return CryptoApi.hash("md2", input, {}).stringify("hex"); + return Hash.runHash("md2", input); }, @@ -36,7 +44,7 @@ const Hash = { * @returns {string} */ runMD4: function (input, args) { - return CryptoApi.hash("md4", input, {}).stringify("hex"); + return Hash.runHash("md4", input); }, @@ -48,7 +56,7 @@ const Hash = { * @returns {string} */ runMD5: function (input, args) { - return CryptoApi.hash("md5", input, {}).stringify("hex"); + return Hash.runHash("md5", input); }, @@ -92,7 +100,7 @@ const Hash = { * @returns {string} */ runSHA0: function (input, args) { - return CryptoApi.hash("sha0", input, {}).stringify("hex"); + return Hash.runHash("sha0", input); }, @@ -104,7 +112,7 @@ const Hash = { * @returns {string} */ runSHA1: function (input, args) { - return CryptoApi.hash("sha1", input, {}).stringify("hex"); + return Hash.runHash("sha1", input); }, @@ -123,7 +131,7 @@ const Hash = { */ runSHA2: function (input, args) { const size = args[0]; - return CryptoApi.hash("sha" + size, input, {}).stringify("hex"); + return Hash.runHash("sha" + size, input); }, @@ -259,7 +267,7 @@ const Hash = { */ runRIPEMD: function (input, args) { const size = args[0]; - return CryptoApi.hash("ripemd" + size, input, {}).stringify("hex"); + return Hash.runHash("ripemd" + size, input); }, @@ -271,7 +279,7 @@ const Hash = { * @returns {string} */ runHAS: function (input, args) { - return CryptoApi.hash("has160", input, {}).stringify("hex"); + return Hash.runHash("has160", input); }, @@ -290,7 +298,7 @@ const Hash = { */ runWhirlpool: function (input, args) { const variant = args[0].toLowerCase(); - return CryptoApi.hash(variant, input, {}).stringify("hex"); + return Hash.runHash(variant, input); }, @@ -315,7 +323,7 @@ const Hash = { runSnefru: function (input, args) { const rounds = args[0], size = args[1]; - return CryptoApi.hash(`snefru-${rounds}-${size}`, input, {}).stringify("hex"); + return Hash.runHash(`snefru-${rounds}-${size}`, input); }, From 7feafbf0e77d48c825ec56de9d63314602a03586 Mon Sep 17 00:00:00 2001 From: slurdge Date: Mon, 9 Oct 2017 16:02:12 +0200 Subject: [PATCH 002/124] Fixes the lint problems and add JSDoc --- src/core/operations/Hash.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/operations/Hash.js b/src/core/operations/Hash.js index d297c624..7213cb13 100755 --- a/src/core/operations/Hash.js +++ b/src/core/operations/Hash.js @@ -16,12 +16,18 @@ import Checksum from "./Checksum.js"; */ const Hash = { + /** Generic hash function + * + * @param {string} name + * @param {string} input + * @returns {string} + */ runHash: function(name, input) { - var hasher = CryptoApi.hasher(name); + let hasher = CryptoApi.hasher(name); hasher.state.message = input; hasher.state.length += input.length; hasher.process(); - return hasher.finalize().stringify('hex'); + return hasher.finalize().stringify("hex"); }, /** From 0e3751407b0388466f6a9cbfb41705ee8ca499ef Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 9 Oct 2017 15:17:20 +0000 Subject: [PATCH 003/124] Cleaned lint. --- src/core/operations/Hash.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/operations/Hash.js b/src/core/operations/Hash.js index 7213cb13..b8bd4797 100755 --- a/src/core/operations/Hash.js +++ b/src/core/operations/Hash.js @@ -16,20 +16,22 @@ import Checksum from "./Checksum.js"; */ const Hash = { - /** Generic hash function + /** + * Generic hash function. * * @param {string} name * @param {string} input * @returns {string} */ runHash: function(name, input) { - let hasher = CryptoApi.hasher(name); + const hasher = CryptoApi.hasher(name); hasher.state.message = input; hasher.state.length += input.length; hasher.process(); return hasher.finalize().stringify("hex"); }, + /** * MD2 operation. * From b61a1b4edb418b4c42af58ed525dd50704738612 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 9 Oct 2017 15:39:10 +0000 Subject: [PATCH 004/124] 6.4.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43bbb206..ffe81eb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.0", + "version": "6.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 31042928..76ac8a15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.0", + "version": "6.4.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 390d5927a42211b09776fdb3cfe58ea58a8f4bb6 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 12 Oct 2017 14:22:35 +0200 Subject: [PATCH 005/124] BugFix: compare odd size elements, like empty line --- src/core/operations/SeqUtils.js | 2 +- test/tests/operations/SeqUtils.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/SeqUtils.js b/src/core/operations/SeqUtils.js index 70207e00..3272e706 100755 --- a/src/core/operations/SeqUtils.js +++ b/src/core/operations/SeqUtils.js @@ -249,7 +249,7 @@ const SeqUtils = { } } - return 0; + return a.localeCompare(b); }, }; diff --git a/test/tests/operations/SeqUtils.js b/test/tests/operations/SeqUtils.js index 7fc2c066..52fbaf32 100644 --- a/test/tests/operations/SeqUtils.js +++ b/test/tests/operations/SeqUtils.js @@ -10,8 +10,8 @@ import TestRegister from "../../TestRegister.js"; TestRegister.addTests([ { name: "SeqUtils - Numeric sort photos", - input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg\n", - expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg\n", + input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg", + expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg", recipeConfig: [ { "op": "Sort", From e5a32ac57db77808881575324b7ab54d0ca8c1ed Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 13 Oct 2017 09:19:16 +0000 Subject: [PATCH 006/124] Added links to Gitter chat room --- .github/ISSUE_TEMPLATE.md | 13 +------------ .travis.yml | 8 +++++++- README.md | 2 ++ src/web/html/index.html | 5 +++++ 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 9e029351..8e7dee82 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,21 +5,10 @@ ### Summary - - + ### Example -### Possible solutions - - - -### Environment - - -* CyberChef compile time: -* User-Agent: -* [Link to reproduce]() diff --git a/.travis.yml b/.travis.yml index 521006ec..e02684ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,4 +39,10 @@ deploy: on: tags: true branch: master - +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/83c143a6822e218d5b34 + on_success: change + on_failure: always + on_start: never diff --git a/README.md b/README.md index bd11ebac..aa04fb8c 100755 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ [![npm](http://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef) ![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue) [![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE) +[![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + #### *The Cyber Swiss Army Knife* diff --git a/src/web/html/index.html b/src/web/html/index.html index 42864f1e..9378196c 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -380,6 +380,11 @@

© Crown Copyright 2016.

Released under the Apache Licence, Version 2.0.

+

+ + + +



From 40d8b42478db821cdfd28c6463b73c3245fd2e20 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 13 Oct 2017 09:19:22 +0000 Subject: [PATCH 007/124] 6.4.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ffe81eb4..7e39be63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.1", + "version": "6.4.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 76ac8a15..00c61c30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.1", + "version": "6.4.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From ec7294d7347715840ae8f787d764031bbd0d0375 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 13 Oct 2017 09:35:34 +0000 Subject: [PATCH 008/124] 6.4.3 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e39be63..a2e67f3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.2", + "version": "6.4.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 00c61c30..59b6d46b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.2", + "version": "6.4.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 599fefb39bb4793ca57b133e5a20fe0b369f37b7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 13 Oct 2017 11:29:22 +0000 Subject: [PATCH 009/124] Fixed 'Parse URI' operation and improved error handling from worker --- src/core/Chef.js | 7 +-- src/core/config/OperationConfig.js | 6 +-- src/core/config/modules/Default.js | 4 -- src/core/config/modules/OpModules.js | 4 +- src/core/config/modules/URL.js | 23 +++++++++ src/core/operations/URL.js | 65 +++++++++----------------- src/web/App.js | 5 +- src/web/html/index.html | 2 +- src/web/static/images/gitter-badge.svg | 1 + 9 files changed, 61 insertions(+), 56 deletions(-) create mode 100644 src/core/config/modules/URL.js create mode 100755 src/web/static/images/gitter-badge.svg diff --git a/src/core/Chef.js b/src/core/Chef.js index 7c9817df..4e7c042a 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -68,9 +68,10 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, try { progress = await recipe.execute(this.dish, progress); } catch (err) { - // Return the error in the result so that everything else gets correctly updated - // rather than throwing it here and losing state info. - error = err; + console.log(err); + error = { + displayStr: err.displayStr, + }; progress = err.progress; } diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 06a3a2d8..9caa4f91 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -760,14 +760,14 @@ const OperationConfig = { ] }, "URL Decode": { - module: "Default", + 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: "Default", + module: "URL", description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.

e.g. = becomes %3d", inputType: "string", outputType: "string", @@ -780,7 +780,7 @@ const OperationConfig = { ] }, "Parse URI": { - module: "Default", + 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", diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 6e51367b..682db223 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -26,7 +26,6 @@ import SeqUtils from "../../operations/SeqUtils.js"; import StrUtils from "../../operations/StrUtils.js"; import Tidy from "../../operations/Tidy.js"; import Unicode from "../../operations/Unicode.js"; -import URL_ from "../../operations/URL.js"; import UUID from "../../operations/UUID.js"; @@ -77,9 +76,6 @@ OpModules.Default = { "From HTML Entity": HTML.runFromEntity, "Strip HTML tags": HTML.runStripTags, "Parse colour code": HTML.runParseColourCode, - "URL Encode": URL_.runTo, - "URL Decode": URL_.runFrom, - "Parse URI": URL_.runParse, "Unescape Unicode Characters": Unicode.runUnescape, "To Quoted Printable": QuotedPrintable.runTo, "From Quoted Printable": QuotedPrintable.runFrom, diff --git a/src/core/config/modules/OpModules.js b/src/core/config/modules/OpModules.js index 2d79753e..3f3963c3 100644 --- a/src/core/config/modules/OpModules.js +++ b/src/core/config/modules/OpModules.js @@ -19,6 +19,7 @@ import ImageModule from "./Image.js"; import JSBNModule from "./JSBN.js"; import PublicKeyModule from "./PublicKey.js"; import ShellcodeModule from "./Shellcode.js"; +import URLModule from "./URL.js"; Object.assign( OpModules, @@ -33,7 +34,8 @@ Object.assign( ImageModule, JSBNModule, PublicKeyModule, - ShellcodeModule + ShellcodeModule, + URLModule ); export default OpModules; diff --git a/src/core/config/modules/URL.js b/src/core/config/modules/URL.js new file mode 100644 index 00000000..54bceb7c --- /dev/null +++ b/src/core/config/modules/URL.js @@ -0,0 +1,23 @@ +import URL_ from "../../operations/URL.js"; + + +/** + * URL module. + * + * Libraries: + * - Utils.js + * - url + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +let OpModules = typeof self === "undefined" ? {} : self.OpModules || {}; + +OpModules.URL = { + "URL Encode": URL_.runTo, + "URL Decode": URL_.runFrom, + "Parse URI": URL_.runParse, +}; + +export default OpModules; diff --git a/src/core/operations/URL.js b/src/core/operations/URL.js index 9e00ebf8..25526f0e 100755 --- a/src/core/operations/URL.js +++ b/src/core/operations/URL.js @@ -1,5 +1,6 @@ /* globals unescape */ import Utils from "../Utils.js"; +import url from "url"; /** @@ -58,56 +59,36 @@ const URL_ = { * @returns {string} */ runParse: function(input, args) { - if (!document) { - throw "This operation only works in a browser."; - } + const uri = url.parse(input, true); - const a = document.createElement("a"); + let output = ""; - // Overwrite base href which will be the current CyberChef URL to reduce confusion. - a.href = "http://example.com/"; - a.href = input; + 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; - if (a.protocol) { - let output = ""; - if (a.hostname !== window.location.hostname) { - output = "Protocol:\t" + a.protocol + "\n"; - if (a.hostname) output += "Hostname:\t" + a.hostname + "\n"; - if (a.port) output += "Port:\t\t" + a.port + "\n"; - } + keys.forEach(k => { + padding = (k.length > padding) ? k.length : padding; + }); - if (a.pathname && a.pathname !== window.location.pathname) { - let pathname = a.pathname; - if (pathname.indexOf(window.location.pathname) === 0) - pathname = pathname.replace(window.location.pathname, ""); - if (pathname) - output += "Path name:\t" + pathname + "\n"; - } - - if (a.hash && a.hash !== window.location.hash) { - output += "Hash:\t\t" + a.hash + "\n"; - } - - if (a.search && a.search !== window.location.search) { - output += "Arguments:\n"; - const args_ = (a.search.slice(1, a.search.length)).split("&"); - let splitArgs = [], padding = 0, i; - for (i = 0; i < args_.length; i++) { - splitArgs.push(args_[i].split("=")); - padding = (splitArgs[i][0].length > padding) ? splitArgs[i][0].length : padding; - } - for (i = 0; i < splitArgs.length; i++) { - output += "\t" + Utils.padRight(splitArgs[i][0], padding); - if (splitArgs[i].length > 1 && splitArgs[i][1].length) - output += " = " + splitArgs[i][1] + "\n"; - else output += "\n"; + output += "Arguments:\n"; + for (let key in uri.query) { + output += "\t" + Utils.padRight(key, padding); + if (uri.query[key].length) { + output += " = " + uri.query[key] + "\n"; + } else { + output += "\n"; } } - - return output; } + if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n"; - return "Invalid URI"; + return output; }, diff --git a/src/web/App.js b/src/web/App.js index ff57a7ed..036a4fb9 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -88,9 +88,10 @@ App.prototype.loaded = function() { * An error handler for displaying the error to the user. * * @param {Error} err + * @param {boolean} [logToConsole=false] */ -App.prototype.handleError = function(err) { - console.error(err); +App.prototype.handleError = function(err, logToConsole) { + if (logToConsole) console.error(err); const msg = err.displayStr || err.toString(); this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); }; diff --git a/src/web/html/index.html b/src/web/html/index.html index 9378196c..5df6682c 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -382,7 +382,7 @@

Released under the Apache Licence, Version 2.0.

- +


diff --git a/src/web/static/images/gitter-badge.svg b/src/web/static/images/gitter-badge.svg new file mode 100755 index 00000000..7064d7f4 --- /dev/null +++ b/src/web/static/images/gitter-badge.svg @@ -0,0 +1 @@ +chatchaton gitteron gitter \ No newline at end of file From 8afd77b32d18cb31f5decb58ac242cc07219e265 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 13 Oct 2017 11:29:45 +0000 Subject: [PATCH 010/124] 6.4.4 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2e67f3b..5db94b05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.3", + "version": "6.4.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 59b6d46b..5b317938 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.3", + "version": "6.4.4", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 638e03856b8e1d1b73a80127825672b4744cf699 Mon Sep 17 00:00:00 2001 From: Matt C Date: Tue, 17 Oct 2017 19:36:51 +0100 Subject: [PATCH 011/124] Initial keybinding functionality + documentation Todo: - allow user to specify whether to use alt or meta key (relatively easy to implement) - keybinding icon for about pane --- src/web/BindingsWaiter.js | 118 ++++++++++++++++++++++++++++++++++++ src/web/Manager.js | 4 +- src/web/html/index.html | 124 +++++++++++++++++++++++++++++++------- 3 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 src/web/BindingsWaiter.js diff --git a/src/web/BindingsWaiter.js b/src/web/BindingsWaiter.js new file mode 100644 index 00000000..8c06e18a --- /dev/null +++ b/src/web/BindingsWaiter.js @@ -0,0 +1,118 @@ +/** + * 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) { + if (e.ctrlKey && e.altKey) { + let elem; + switch (e.code) { + case "KeyF": + e.preventDefault(); + document.getElementById("search").focus(); // Focus search + break; + case "KeyI": + e.preventDefault(); + document.getElementById("input-text").focus(); // Focus input + break; + case "KeyO": + e.preventDefault(); + document.getElementById("output-text").focus(); // Focus output + break; + case "Period": + try { + elem = document.activeElement.closest(".operation"); + if (elem.parentNode.lastChild === elem) { + elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus(); // if operation is last in recipe, loop around to the top operation's first argument + } else { + elem.nextSibling.querySelectorAll(".arg")[0].focus(); //focus first argument of next operation + } + } catch (e) { + // do nothing, just don't throw an error + } + break; + case "KeyB": + 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": + 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": + this.app.bake(); // bake the recipe + break; + case "Quote": + this.app.bake(true); // step through the recipe + break; + case "KeyC": + this.manager.recipe.clearRecipe(); // clear recipe + break; + case "KeyS": + this.manager.output.saveClick(); // save output to file + break; + case "KeyL": + this.manager.controls.loadClick(); // load a recipe + break; + case "KeyM": + this.manager.controls.switchClick(); // switch input & output + break; + default: + if (e.code.match(/Digit[0-9]/g)) { + e.preventDefault(); + try { + document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus(); // select the first argument of the operation corresponding to the number pressed + } catch (e) { + // do nothing, just don't throw an error + } + } + break; + } + } +}; + +export default BindingsWaiter; diff --git a/src/web/Manager.js b/src/web/Manager.js index 1d32758c..de1df8e4 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -8,6 +8,7 @@ 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"; /** @@ -60,6 +61,7 @@ const Manager = function(app) { this.options = new OptionsWaiter(this.app); 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 = {}; @@ -89,7 +91,7 @@ Manager.prototype.initialiseEventListeners = function() { 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)); - + window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); // Controls document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls)); document.getElementById("auto-bake").addEventListener("change", this.controls.autoBakeChange.bind(this.controls)); diff --git a/src/web/html/index.html b/src/web/html/index.html index 8d23aed4..e1f300e7 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -1,17 +1,17 @@ + + Keybindings +
@@ -448,20 +453,20 @@
What

A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.


- +
Why

Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.


- +
How

The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.

For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.


- +
Who

It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.


- +
Aim

It is hoped that by releasing CyberChef through GitHub, contributions can be added which can be rolled out into future versions of the tool.


@@ -470,6 +475,79 @@

There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.

It’s the Cyber Swiss Army Knife.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandShortcut (Win/Linux)Shortcut (Mac)
Place cursor in search fieldCtrl+Alt+fCtrl+Opt+f
Place cursor in input boxCtrl+Alt+iCtrl+Opt+i
Place cursor in output boxCtrl+Alt+oCtrl+Opt+o
Place cursor in first argument field
of the next operation in the recipe
Ctrl+Alt+.Ctrl+Opt+.
Place cursor in first argument field
of the nth operation in the recipe
Ctrl+Alt+[1-9]Ctrl+Opt+[1-9]
Disable current operationCtrl+Alt+dCtrl+Opt+d
Set/clear breakpointCtrl+Alt+bCtrl+Opt+b
BakeCtrl+Alt+SpaceCtrl+Opt+Space
StepCtrl+Alt+'Ctrl+Opt+'
Clear recipeCtrl+Alt+cCtrl+Opt+c
Save to fileCtrl+Alt+sCtrl+Opt+s
Load recipeCtrl+Alt+lCtrl+Opt+l
Move output to inputCtrl+Alt+mCtrl+Opt+m
+
@@ -482,7 +560,7 @@ - + - + From 2ddd2e0a6013dce49daadd1da728c7e00eaf5e5f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 23 Oct 2017 17:31:53 +0000 Subject: [PATCH 012/124] Added 'Copy output' button. Closes #198. --- src/web/static/images/copy-16x16.png | Bin 0 -> 432 bytes src/web/static/images/fork_me.png | Bin 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 src/web/static/images/copy-16x16.png mode change 100644 => 100755 src/web/static/images/fork_me.png diff --git a/src/web/static/images/copy-16x16.png b/src/web/static/images/copy-16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..0a5553bef058d05515aae7456ce3a7b1427e17cc GIT binary patch literal 432 zcmV;h0Z;ykP)(5k}Bh6#WCyP*G4r&=L(!DM1!N7={WB zfrg+3rb{Rl^6tH-;bqU~d$%uqmwV3robNqw8FaZ|FRnQM69a(AeUALz9!oJ2jo+*< z&dmUze<_c-cdBz~@pZaDTl?p?jX_E!o=fyu7Z#U4z9{`tq437ek?O7s0Jsp)ggIrQ zTt)4>4geS!9+@7W3WflnT6)dqvzZ4|b39X|N=-94n#_}s(&D?Pq6~%>=1mDSZcV_Y zw44Eef3TM=h1X7;j5#8wd&ds_2@+h8$%5;ERy$oz^mcb(d1dtw0CWHs(1bLbb6Y@X zdmBc59yplOVLZWRiJa@H?8P7?89N{XWJ|AV2gU$l0AjJrt5nj{)!g9m2F5f&ZWTZi z(f}N6hi6+GHh0ewnxF|KpgDnU#NVZ<>rDyl#F!)^HK0*bev-bSz@*#V?^D% Date: Mon, 23 Oct 2017 17:32:36 +0000 Subject: [PATCH 013/124] Fixed lint --- src/web/Manager.js | 1 + src/web/OutputWaiter.js | 41 +++++++++++++++++++++++++++++++++++++++++ src/web/html/index.html | 1 + 3 files changed, 43 insertions(+) diff --git a/src/web/Manager.js b/src/web/Manager.js index 1d32758c..5b8c98f0 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -142,6 +142,7 @@ Manager.prototype.initialiseEventListeners = function() { // 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)); diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 0b16c0f2..a5576f31 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -105,17 +105,20 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { 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 = @@ -147,6 +150,44 @@ OutputWaiter.prototype.saveClick = function() { }; +/** + * Handler for copy click events. + * Copies the output to the clipboard. + */ +OutputWaiter.prototype.copyClick = function() { + // Create invisible textarea to populate with the raw dishStr (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.app.dishStr; + document.body.appendChild(textarea); + + // Select and copy the contents of this textarea + let success = false; + try { + textarea.select(); + success = 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. diff --git a/src/web/html/index.html b/src/web/html/index.html index 5df6682c..6f7c878d 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -189,6 +189,7 @@
+ From c6a65c468616e483e848f87a1cc5d5c7fec47248 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 23 Oct 2017 17:32:47 +0000 Subject: [PATCH 014/124] 6.4.5 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5db94b05..24022f18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.4", + "version": "6.4.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5b317938..7661038e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.4", + "version": "6.4.5", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 2cd4256ece8f4dd8a6e3dca2a20209d0782f2235 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 26 Oct 2017 17:00:13 +0000 Subject: [PATCH 015/124] Updated dependencies --- package-lock.json | 466 ++++++++++++++++++++++++++++++++-------------- package.json | 22 +-- 2 files changed, 336 insertions(+), 152 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24022f18..028c7481 100644 --- a/package-lock.json +++ b/package-lock.json @@ -903,9 +903,9 @@ } }, "babel-preset-env": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.0.tgz", - "integrity": "sha512-OVgtQRuOZKckrILgMA5rvctvFZPv72Gua9Rt006AiPoB0DJKGN07UmaQA+qRrYgK71MVct8fFhT0EyNWYorVew==", + "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==", "dev": true, "requires": { "babel-plugin-check-es2015-constants": "6.22.0", @@ -935,7 +935,7 @@ "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.4.0", + "browserslist": "2.5.1", "invariant": "2.2.2", "semver": "5.4.1" } @@ -1164,9 +1164,9 @@ "dev": true }, "browserify-aes": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", - "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "dev": true, "requires": { "buffer-xor": "1.0.3", @@ -1183,7 +1183,7 @@ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "dev": true, "requires": { - "browserify-aes": "1.0.8", + "browserify-aes": "1.1.1", "browserify-des": "1.0.0", "evp_bytestokey": "1.0.3" } @@ -1234,12 +1234,12 @@ } }, "browserslist": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.4.0.tgz", - "integrity": "sha512-aM2Gt4x9bVlCUteADBS6JP0F+2tMWKM1jQzUulVROtdFWFIcIVvY76AJbr7GDqy0eDhn+PcnpzzivGxY4qiaKQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz", + "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000741", + "caniuse-lite": "1.0.30000751", "electron-to-chromium": "1.3.24" } }, @@ -1356,9 +1356,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000741", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000741.tgz", - "integrity": "sha1-vFJrwgRua8OHN8/XfTAm7wS49GQ=", + "version": "1.0.30000751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000751.tgz", + "integrity": "sha1-KYrTQYLKQ1l1e0qTr8aBt7kX41g=", "dev": true }, "caseless": { @@ -1594,9 +1594,9 @@ "dev": true }, "compressible": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz", - "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", + "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", "dev": true, "requires": { "mime-db": "1.30.0" @@ -1610,7 +1610,7 @@ "requires": { "accepts": "1.3.4", "bytes": "3.0.0", - "compressible": "2.0.11", + "compressible": "2.0.12", "debug": "2.6.9", "on-headers": "1.0.1", "safe-buffer": "5.1.1", @@ -1635,9 +1635,9 @@ } }, "connect-history-api-fallback": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz", - "integrity": "sha1-5R0X+PDvDbkKZP20feMFFVbp8Wk=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.4.0.tgz", + "integrity": "sha1-PbJPlz9LkjsOgvYZzg3wJBHKYj0=", "dev": true }, "console-browserify": { @@ -1976,7 +1976,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.30" + "es5-ext": "0.10.35" } }, "dashdash": { @@ -2139,9 +2139,9 @@ "dev": true }, "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==" }, "diffie-hellman": { "version": "5.0.2", @@ -2400,23 +2400,23 @@ } }, "es5-ext": { - "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "version": "0.10.35", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", + "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", "dev": true, "requires": { - "es6-iterator": "2.0.1", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "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.30", + "es5-ext": "0.10.35", "es6-symbol": "3.1.1" } }, @@ -2427,8 +2427,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -2447,8 +2447,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" } @@ -2460,7 +2460,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.30" + "es5-ext": "0.10.35" } }, "es6-weak-map": { @@ -2470,8 +2470,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, @@ -2832,7 +2832,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.30" + "es5-ext": "0.10.35" } }, "eventemitter2": { @@ -2927,9 +2927,9 @@ } }, "express": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.1.tgz", - "integrity": "sha512-STB7LZ4N0L+81FJHGla2oboUHTk4PaN1RsOkoRh9OSeEKylvF5hwKYVX1xCLFaCT7MD0BNG/gX2WFMLqY6EMBw==", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", "dev": true, "requires": { "accepts": "1.3.4", @@ -2999,9 +2999,9 @@ } }, "extract-text-webpack-plugin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.1.tgz", - "integrity": "sha512-zv0/Cg2mU8uMzeQQ3oyfJvZU4Iv/GbQYUIr/HU+8pZetT/0W3xj6XAbxoG4gsp8SbnYcFd4BOsCAZPl9NvplPw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", "dev": true, "requires": { "async": "2.5.0", @@ -3109,9 +3109,9 @@ } }, "file-loader": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.4.tgz", - "integrity": "sha512-E4mCBrAVk8pB6VmuCW/rbHvtQDy2sknh0G4c2c449Q5qC7fCkL1P6sZGxQXWPaAxXBdU8WsTzPEB973Ei8vkxg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.5.tgz", + "integrity": "sha512-RzGHDatcVNpGISTvCpfUfOGpYuSR7HSsSg87ki+wF6rw1Hm0RALPTiAdsxAq1UwLf0RRhbe22/eHK6nhXspiOQ==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -4000,9 +4000,9 @@ } }, "http-parser-js": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.8.tgz", - "integrity": "sha512-jmHp99g6/fLx0pRNJqzsQgjsclCHAY7NhIeA3/U+bsGNvgbvUCQFQY9m5AYpqpAxY/2VcikfbKpjQozSTiz0jA==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", + "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", "dev": true }, "http-proxy": { @@ -4149,6 +4149,16 @@ "dev": true, "optional": true }, + "import-local": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-0.1.1.tgz", + "integrity": "sha1-sReVcqrNwRxqkQCftDDbyrX2aKg=", + "dev": true, + "requires": { + "pkg-dir": "2.0.0", + "resolve-cwd": "2.0.0" + } + }, "imports-loader": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz", @@ -4214,7 +4224,7 @@ "integrity": "sha1-6QBeW7kCXMmpvo5ErYf4rViIyB0=", "dev": true, "requires": { - "moment": "2.18.1", + "moment": "2.19.1", "sanitize-html": "1.14.1" } }, @@ -4356,9 +4366,9 @@ } }, "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-builtin-module": { @@ -4843,13 +4853,13 @@ "dev": true }, "jsonpath": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-0.2.12.tgz", - "integrity": "sha1-W/nZEftGFsHjNwvs658NskrjTNI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.0.tgz", + "integrity": "sha1-Rc2dTE0NaCXZC9fkD4PxGCsT3Qc=", "requires": { "esprima": "1.2.2", "jison": "0.4.13", - "static-eval": "0.2.3", + "static-eval": "2.0.0", "underscore": "1.7.0" }, "dependencies": { @@ -4889,7 +4899,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -4917,9 +4927,9 @@ } }, "less": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.2.tgz", - "integrity": "sha1-No1sxz4fsDmBGDKAkYdDxdz5s98=", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", + "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", "dev": true, "requires": { "errno": "0.1.4", @@ -4928,8 +4938,170 @@ "mime": "1.4.1", "mkdirp": "0.5.1", "promise": "7.3.1", - "request": "2.83.0", + "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" + } + } } }, "less-loader": { @@ -5035,9 +5207,9 @@ "dev": true }, "loglevel": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.0.tgz", - "integrity": "sha512-OQ2jhWI5G2qsvO0UFNyCQWgKl/tFiwuPIXxELzACeUO2FqstN/R7mmL09+nhv6xOWVPPojQO1A90sCEoJSgBcQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.1.tgz", + "integrity": "sha1-GJB4yUq5BT7iFaCs2/JCROoPZQI=", "dev": true }, "longest": { @@ -5300,16 +5472,16 @@ } }, "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", + "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=" }, "moment-timezone": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz", "integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A=", "requires": { - "moment": "2.18.1" + "moment": "2.19.1" } }, "ms": { @@ -5729,7 +5901,7 @@ "dev": true, "requires": { "asn1.js": "4.9.1", - "browserify-aes": "1.0.8", + "browserify-aes": "1.1.1", "create-hash": "1.1.3", "evp_bytestokey": "1.0.3", "pbkdf2": "3.0.14" @@ -6324,13 +6496,13 @@ } }, "postcss-loader": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.6.tgz", - "integrity": "sha512-HIq7yy1hh9KI472Y38iSRV4WupZUNy6zObkxQM/ZuInoaE2+PyX4NcO6jjP5HG5mXL7j5kcNEl0fAG4Kva7O9w==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz", + "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==", "dev": true, "requires": { "loader-utils": "1.1.0", - "postcss": "6.0.12", + "postcss": "6.0.13", "postcss-load-config": "1.2.0", "schema-utils": "0.3.0" }, @@ -6345,14 +6517,14 @@ } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6362,20 +6534,26 @@ "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.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", + "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -7010,7 +7188,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -7021,7 +7199,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -7418,6 +7596,23 @@ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", @@ -7872,33 +8067,11 @@ } }, "static-eval": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-0.2.3.tgz", - "integrity": "sha1-Aj8XrJ/uQm6niMEuo5IG3Bdfiyo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz", + "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==", "requires": { - "escodegen": "0.0.28" - }, - "dependencies": { - "escodegen": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.28.tgz", - "integrity": "sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=", - "requires": { - "esprima": "1.0.4", - "estraverse": "1.3.2", - "source-map": "0.5.7" - } - }, - "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" - }, - "estraverse": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz", - "integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI=" - } + "escodegen": "1.9.0" } }, "statuses": { @@ -8650,9 +8823,9 @@ "dev": true }, "webpack": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.6.0.tgz", - "integrity": "sha512-OsHT3D0W0KmPPh60tC7asNnOmST6bKTiR90UyEdT9QYoaJ4OYN4Gg7WK1k3VxHK07ZoiYWPsKvlS/gAjwL/vRA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", + "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==", "dev": true, "requires": { "acorn": "5.1.2", @@ -8671,7 +8844,7 @@ "mkdirp": "0.5.1", "node-libs-browser": "2.0.0", "source-map": "0.5.7", - "supports-color": "4.4.0", + "supports-color": "4.5.0", "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", "watchpack": "1.4.0", @@ -8704,9 +8877,9 @@ "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -8728,9 +8901,9 @@ } }, "webpack-dev-server": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.1.tgz", - "integrity": "sha512-qFKs4Wg6JI6FkAQ6WFqeDCCxXEBLsDHkqJB3f9tmlqx8C68Y9vQWwcaMT4Q9H8WF32Q6QUNmgK4qQkdHfXvj/g==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.3.tgz", + "integrity": "sha512-bwq7sj452FRH+oVfgOA8xXKkLYPTNsYB4dQ0Jhz3ydjNJ9MvhpGJtehFW8Z0cEcwNkRRiF4aYbReiSGQ4pbS1w==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -8738,14 +8911,16 @@ "bonjour": "3.5.0", "chokidar": "1.7.0", "compression": "1.7.1", - "connect-history-api-fallback": "1.3.0", + "connect-history-api-fallback": "1.4.0", + "debug": "3.1.0", "del": "3.0.0", - "express": "4.16.1", + "express": "4.16.2", "html-entities": "1.2.1", "http-proxy-middleware": "0.17.4", + "import-local": "0.1.1", "internal-ip": "1.2.0", "ip": "1.1.5", - "loglevel": "1.5.0", + "loglevel": "1.5.1", "opn": "5.1.0", "portfinder": "1.0.13", "selfsigned": "1.10.1", @@ -8754,7 +8929,7 @@ "sockjs-client": "1.1.4", "spdy": "3.4.7", "strip-ansi": "3.0.1", - "supports-color": "4.4.0", + "supports-color": "4.5.0", "webpack-dev-middleware": "1.12.0", "yargs": "6.6.0" }, @@ -8776,6 +8951,15 @@ "wrap-ansi": "2.1.0" } }, + "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" + } + }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -8853,9 +9037,9 @@ } }, "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -8921,7 +9105,7 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.4.8", + "http-parser-js": "0.4.9", "websocket-extensions": "0.1.2" } }, @@ -8999,9 +9183,9 @@ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.0.0.tgz", - "integrity": "sha512-dUwgs4Rdi1qG3VciM1+EPgAoO8m9USpCXxE3xmpWrnHJSMKGkzpCUNeYLjBRgYcSkf2A5xnXpR450Wqtu+pq0w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.0.tgz", + "integrity": "sha512-W91q8Wi1JxbzFQZuLJlFK4x8UuWjKgeOX9IMMyng007K0UkP6I8lOejckoCWY61QmnJq2x9qZ/Viru+uF8g6nA==", "dev": true, "requires": { "loader-utils": "1.1.0", diff --git a/package.json b/package.json index 7661038e..c2d7fd7d 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", - "babel-preset-env": "^1.6.0", + "babel-preset-env": "^1.6.1", "css-loader": "^0.28.7", "exports-loader": "^0.6.4", - "extract-text-webpack-plugin": "^3.0.1", - "file-loader": "^1.1.4", + "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^1.1.5", "grunt": ">=1.0.1", "grunt-accessibility": "~5.0.0", "grunt-chmod": "~1.1.1", @@ -52,19 +52,19 @@ "imports-loader": "^0.7.1", "ink-docstrap": "^1.3.0", "jsdoc-babel": "^0.3.0", - "less": "^2.7.2", + "less": "^2.7.3", "less-loader": "^4.0.5", "postcss-css-variables": "^0.8.0", "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.6", + "postcss-loader": "^2.0.8", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "val-loader": "^1.0.2", "web-resource-inliner": "^4.2.0", - "webpack": "^3.6.0", - "webpack-dev-server": "^2.9.1", + "webpack": "^3.8.1", + "webpack-dev-server": "^2.9.3", "webpack-node-externals": "^1.6.0", - "worker-loader": "^1.0.0" + "worker-loader": "^1.1.0" }, "dependencies": { "babel-polyfill": "^6.26.0", @@ -73,7 +73,7 @@ "bootstrap-switch": "^3.3.4", "crypto-api": "^0.7.5", "crypto-js": "^3.1.9-1", - "diff": "^3.3.1", + "diff": "^3.4.0", "escodegen": "^1.9.0", "esmangle": "^1.0.1", "esprima": "^4.0.0", @@ -83,10 +83,10 @@ "js-crc": "^0.2.0", "js-sha3": "^0.6.1", "jsbn": "^1.1.0", - "jsonpath": "^0.2.12", + "jsonpath": "^1.0.0", "jsrsasign": "8.0.4", "lodash": "^4.17.4", - "moment": "^2.18.1", + "moment": "^2.19.1", "moment-timezone": "^0.5.13", "node-md6": "^0.1.0", "otp": "^0.1.3", From 8b30fdf7f1d33943ddfeedf9b4adc259d852fee1 Mon Sep 17 00:00:00 2001 From: Matt C Date: Sat, 4 Nov 2017 12:55:28 +0000 Subject: [PATCH 016/124] Adds ability for user to use Meta key instead of alt for keybindings - includes dynamically updating keybinding list --- src/web/BindingsWaiter.js | 88 ++++++++++++++++++++++++++++++++++++++- src/web/Manager.js | 6 ++- src/web/html/index.html | 79 +++-------------------------------- src/web/index.js | 1 + 4 files changed, 99 insertions(+), 75 deletions(-) diff --git a/src/web/BindingsWaiter.js b/src/web/BindingsWaiter.js index 8c06e18a..2454ed59 100644 --- a/src/web/BindingsWaiter.js +++ b/src/web/BindingsWaiter.js @@ -23,7 +23,9 @@ const BindingsWaiter = function (app, manager) { * @param {event} e */ BindingsWaiter.prototype.parseInput = function(e) { - if (e.ctrlKey && e.altKey) { + let modKey = e.altKey; + if (this.app.options.useMetaKey) modKey = e.metaKey; + if (e.ctrlKey && modKey) { let elem; switch (e.code) { case "KeyF": @@ -115,4 +117,88 @@ BindingsWaiter.prototype.parseInput = function(e) { } }; +/** + * 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/Manager.js b/src/web/Manager.js index de1df8e4..e0a0ef37 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -78,6 +78,7 @@ Manager.prototype.setup = function() { this.recipe.initialiseOperationDragNDrop(); this.controls.autoBakeChange(); this.seasonal.load(); + this.bindings.updateKeybList(); }; @@ -91,7 +92,6 @@ Manager.prototype.initialiseEventListeners = function() { 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)); - window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); // Controls document.getElementById("bake").addEventListener("click", this.controls.bakeClick.bind(this.controls)); document.getElementById("auto-bake").addEventListener("change", this.controls.autoBakeChange.bind(this.controls)); @@ -166,6 +166,10 @@ Manager.prototype.initialiseEventListeners = function() { this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options); document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options)); + //Keybindings + window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); + $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings)); + // Misc document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app)); }; diff --git a/src/web/html/index.html b/src/web/html/index.html index c968ebfe..0bf52c53 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -325,6 +325,10 @@
+
+ + +
@@ -402,8 +406,7 @@ About
  • - - + Keybindings
  • @@ -482,77 +485,7 @@

    It’s the Cyber Swiss Army Knife.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CommandShortcut (Win/Linux)Shortcut (Mac)
    Place cursor in search fieldCtrl+Alt+fCtrl+Opt+f
    Place cursor in input boxCtrl+Alt+iCtrl+Opt+i
    Place cursor in output boxCtrl+Alt+oCtrl+Opt+o
    Place cursor in first argument field
    of the next operation in the recipe
    Ctrl+Alt+.Ctrl+Opt+.
    Place cursor in first argument field
    of the nth operation in the recipe
    Ctrl+Alt+[1-9]Ctrl+Opt+[1-9]
    Disable current operationCtrl+Alt+dCtrl+Opt+d
    Set/clear breakpointCtrl+Alt+bCtrl+Opt+b
    BakeCtrl+Alt+SpaceCtrl+Opt+Space
    StepCtrl+Alt+'Ctrl+Opt+'
    Clear recipeCtrl+Alt+cCtrl+Opt+c
    Save to fileCtrl+Alt+sCtrl+Opt+s
    Load recipeCtrl+Alt+lCtrl+Opt+l
    Move output to inputCtrl+Alt+mCtrl+Opt+m
    +
    diff --git a/src/web/index.js b/src/web/index.js index 80da5733..5964b1e8 100755 --- a/src/web/index.js +++ b/src/web/index.js @@ -46,6 +46,7 @@ function main() { errorTimeout: 4000, attemptHighlight: true, theme: "classic", + useMetaKey: false }; document.removeEventListener("DOMContentLoaded", main, false); From 4be7f89fd8a6e43e18c65fc57b54e94f60e0f3f9 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Sun, 12 Nov 2017 21:37:29 -0500 Subject: [PATCH 017/124] Add PHP Deserialization. --- src/core/config/Categories.js | 1 + src/core/config/OperationConfig.js | 14 +++ src/core/config/modules/Default.js | 3 +- src/core/operations/PhpSerialization.js | 128 ++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/PhpSerialization.js diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index f04b5fd9..09f0187c 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -66,6 +66,7 @@ const Categories = [ "Encode text", "Decode text", "Swap endianness", + "PHP Deserialize", ] }, { diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 9caa4f91..469a98c1 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -35,6 +35,7 @@ import StrUtils from "../operations/StrUtils.js"; import Tidy from "../operations/Tidy.js"; import Unicode from "../operations/Unicode.js"; import URL_ from "../operations/URL.js"; +import PhpSerialization from "../operations/PhpSerialization.js"; /** @@ -3845,6 +3846,19 @@ const OperationConfig = { } ] }, + "PHP Deserialize": { + module: "Default", + description: "PHP Deserialize a given input.

    This function does not support object tags.

    Output valid JSON: JSON doesn't support integers as keys, where as 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: PhpSerialization.OUTPUT_VALID_JSON + } + ] + }, }; diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 682db223..8c13cfd2 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -27,7 +27,7 @@ import StrUtils from "../../operations/StrUtils.js"; import Tidy from "../../operations/Tidy.js"; import Unicode from "../../operations/Unicode.js"; import UUID from "../../operations/UUID.js"; - +import PhpSerialization from "../../operations/PhpSerialization"; /** * Default module. @@ -155,6 +155,7 @@ OpModules.Default = { "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, + "PHP Deserialize": PhpSerialization.PhpDeserialize, /* diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js new file mode 100644 index 00000000..1d4394c8 --- /dev/null +++ b/src/core/operations/PhpSerialization.js @@ -0,0 +1,128 @@ +/** + * Php Serialization operations. + * This Javascript implementation is based on the Python + * implementation by Armin Ronacher (2016). + * See: https://github.com/mitsuhiko/phpserialize/ + * + * @author Jarmo van Lenthe [github.com/jarmovanlenthe] + * @copyright Crown Copyright 2017 + * @license BSD-3-Clause + * + * @namespace + */ + +const PhpSerialization = { + + /** + * @constant + * @default + */ + OUTPUT_VALID_JSON: true, + + PhpDeserialize: function (input, args) { + function handleInput() { + function read(length) { + let result = ""; + for (let idx = 0; idx < length; idx++) { + let char = inputPart.shift(); + if (char === undefined) { + throw "End of input reached before end of script"; + } + result += char; + } + return result; + } + + function readUntil(until) { + let result = ""; + while (true) { + let char = read(1); + if (char === until) { + break; + } + else { + result += char; + } + } + return result; + + } + + function expect(expect) { + let result = read(expect.length); + if (result !== expect) { + throw "Unexpected input found"; + } + return result; + } + + function handleArray() { + let items = parseInt(readUntil(':')) * 2; + expect('{'); + let result = []; + let isKey = true; + let last_item = null; + for (let idx = 0; idx < items; idx++) { + let item = handleInput(); + if (isKey) { + last_item = item; + isKey = false; + } else { + let numberCheck = last_item.match(/[0-9]+/); + if (args[0] && numberCheck && numberCheck[0].length === last_item.length) + { + result.push('"' + last_item + '": ' + item); + } else { + result.push(last_item + ': ' + item); + } + isKey = true; + } + } + expect('}'); + return result; + } + + + let kind = read(1).toLowerCase(); + + switch (kind) { + case 'n': + expect(';'); + return ''; + + case 'i': + case 'd': + case 'b': + expect(':'); + let data = readUntil(';'); + if (kind === 'b') + return (parseInt(data) !== 0); + return data; + + + case 'a': + expect(':'); + return '{' + handleArray() + '}'; + + case 's': + expect(':'); + let length = readUntil(':'); + expect('"'); + let value = read(length); + expect('";'); + if (args[0]) + return '"' + value.replace(/"/g, '\\"') + '"'; + else + return '"' + value + '"'; + + default: + throw "Unknown type: " + kind; + } + } + + let inputPart = input.split(''); + return handleInput(); + } +}; + +export default PhpSerialization; From f596fe8404ec40d498601646b97acbefbe7c63c9 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Sun, 12 Nov 2017 22:10:28 -0500 Subject: [PATCH 018/124] Add tests for PHP deserialization --- test/index.js | 1 + test/tests/operations/PhpSerialization.js | 68 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/tests/operations/PhpSerialization.js diff --git a/test/index.js b/test/index.js index 773a5b14..9fa4dcdc 100644 --- a/test/index.js +++ b/test/index.js @@ -27,6 +27,7 @@ import "./tests/operations/MorseCode.js"; import "./tests/operations/MS.js"; import "./tests/operations/StrUtils.js"; import "./tests/operations/SeqUtils.js"; +import "./tests/operations/PhpSerialization.js"; let allTestsPassing = true; diff --git a/test/tests/operations/PhpSerialization.js b/test/tests/operations/PhpSerialization.js new file mode 100644 index 00000000..a38379cd --- /dev/null +++ b/test/tests/operations/PhpSerialization.js @@ -0,0 +1,68 @@ +/** + * PHP Serialization tests. + * + * @author Jarmo van Lenthe + * + * @copyright Crown Copyright 2017 + * @license BSD-3-Clause + */ + +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "PHP Deserialize empty array", + input: "a:0:{}", + expectedOutput: "{}", + recipeConfig: [ + { + op: "PHP Deserialize", + args: [true], + }, + ], + }, + { + name: "PHP Deserialize integer", + input: "i:10;", + expectedOutput: "10", + recipeConfig: [ + { + op: "PHP Deserialize", + args: [true], + }, + ], + }, + { + name: "PHP Deserialize string", + input: "s:17:\"PHP Serialization\";", + expectedOutput: "\"PHP Serialization\"", + recipeConfig: [ + { + op: "PHP Deserialize", + args: [true], + }, + ], + }, + { + name: "PHP Deserialize array (JSON)", + input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}", + expectedOutput: "{\"a\": 10,\"0\": {\"ab\": true}}", + recipeConfig: [ + { + op: "PHP Deserialize", + args: [true], + }, + ], + }, + { + name: "PHP Deserialize array (non-JSON)", + input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}", + expectedOutput: "{\"a\": 10,0: {\"ab\": true}}", + recipeConfig: [ + { + op: "PHP Deserialize", + args: [false], + }, + ], + }, +]); From 50a32e90d922129439b6f44a852544fd7408c2fe Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Sun, 12 Nov 2017 22:11:16 -0500 Subject: [PATCH 019/124] Reformatted PHP deserialization. --- src/core/operations/PhpSerialization.js | 79 ++++++++++++++----------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js index 1d4394c8..7b4298c2 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PhpSerialization.js @@ -19,6 +19,12 @@ const PhpSerialization = { */ OUTPUT_VALID_JSON: true, + /** + * Deserializes a PHP serialized input + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ PhpDeserialize: function (input, args) { function handleInput() { function read(length) { @@ -39,8 +45,7 @@ const PhpSerialization = { let char = read(1); if (char === until) { break; - } - else { + } else { result += char; } } @@ -57,28 +62,27 @@ const PhpSerialization = { } function handleArray() { - let items = parseInt(readUntil(':')) * 2; - expect('{'); + let items = parseInt(readUntil(":"), 10) * 2; + expect("{"); let result = []; let isKey = true; - let last_item = null; + let lastItem = null; for (let idx = 0; idx < items; idx++) { let item = handleInput(); if (isKey) { - last_item = item; + lastItem = item; isKey = false; } else { - let numberCheck = last_item.match(/[0-9]+/); - if (args[0] && numberCheck && numberCheck[0].length === last_item.length) - { - result.push('"' + last_item + '": ' + item); + let numberCheck = lastItem.match(/[0-9]+/); + if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) { + result.push("\"" + lastItem + "\": " + item); } else { - result.push(last_item + ': ' + item); + result.push(lastItem + ": " + item); } isKey = true; } } - expect('}'); + expect("}"); return result; } @@ -86,41 +90,44 @@ const PhpSerialization = { let kind = read(1).toLowerCase(); switch (kind) { - case 'n': - expect(';'); - return ''; + case "n": + expect(";"); + return ""; - case 'i': - case 'd': - case 'b': - expect(':'); - let data = readUntil(';'); - if (kind === 'b') - return (parseInt(data) !== 0); + case "i": + case "d": + case "b": { + expect(":"); + let data = readUntil(";"); + if (kind === "b") { + return (parseInt(data, 10) !== 0); + } return data; + } + case "a": + expect(":"); + return "{" + handleArray() + "}"; - case 'a': - expect(':'); - return '{' + handleArray() + '}'; - - case 's': - expect(':'); - let length = readUntil(':'); - expect('"'); + case "s": { + expect(":"); + let length = readUntil(":"); + expect("\""); let value = read(length); - expect('";'); - if (args[0]) - return '"' + value.replace(/"/g, '\\"') + '"'; - else - return '"' + value + '"'; + expect("\";"); + if (args[0]) { + return "\"" + value.replace(/"/g, "\\\"") + "\""; + } else { + return "\"" + value + "\""; + } + } default: throw "Unknown type: " + kind; } } - let inputPart = input.split(''); + let inputPart = input.split(""); return handleInput(); } }; From 29047c248162d1044373e962d61b22f3271ddfa2 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Sun, 12 Nov 2017 22:20:16 -0500 Subject: [PATCH 020/124] Add JSDoc to helper functions and reformat while true. --- src/core/operations/PhpSerialization.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js index 7b4298c2..adaa049a 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PhpSerialization.js @@ -26,7 +26,16 @@ const PhpSerialization = { * @returns {string} */ PhpDeserialize: function (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++) { @@ -39,9 +48,14 @@ const PhpSerialization = { return result; } + /** + * Read characters from the input until `until` is found. + * @param until + * @returns {string} + */ function readUntil(until) { let result = ""; - while (true) { + for(;;) { let char = read(1); if (char === until) { break; @@ -53,6 +67,11 @@ const PhpSerialization = { } + /** + * Read characters from the input that must be equal to `expect` + * @param expect + * @returns {string} + */ function expect(expect) { let result = read(expect.length); if (result !== expect) { @@ -61,6 +80,10 @@ const PhpSerialization = { return result; } + /** + * Helper function to handle deserialized arrays. + * @returns {Array} + */ function handleArray() { let items = parseInt(readUntil(":"), 10) * 2; expect("{"); From 5399d278751a859f3a8f31dacfb0839878f7791a Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Sun, 12 Nov 2017 22:23:38 -0500 Subject: [PATCH 021/124] Add space after for --- src/core/operations/PhpSerialization.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js index adaa049a..6fc92913 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PhpSerialization.js @@ -55,7 +55,7 @@ const PhpSerialization = { */ function readUntil(until) { let result = ""; - for(;;) { + for (;;) { let char = read(1); if (char === until) { break; From 305956cbe310926e33897967ab38776c8a8d5969 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Mon, 13 Nov 2017 07:15:06 -0500 Subject: [PATCH 022/124] Fix copyright statement --- src/core/operations/PhpSerialization.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js index 6fc92913..eb98a403 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PhpSerialization.js @@ -5,7 +5,7 @@ * See: https://github.com/mitsuhiko/phpserialize/ * * @author Jarmo van Lenthe [github.com/jarmovanlenthe] - * @copyright Crown Copyright 2017 + * @copyright Armin Ronacher 2016 some rights reserved / Jarmo van Lenthe * @license BSD-3-Clause * * @namespace From ea352e05f0412051bb22ce63dfb4394a319e66a7 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Wed, 15 Nov 2017 16:00:53 -0500 Subject: [PATCH 023/124] Change PHP Serialization operation to Apache-2.0 license. --- src/core/operations/PhpSerialization.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PhpSerialization.js index eb98a403..3b2d8a20 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PhpSerialization.js @@ -1,12 +1,12 @@ /** * Php Serialization operations. - * This Javascript implementation is based on the Python - * implementation by Armin Ronacher (2016). + * This Javascript implementation is based on the Python implementation by + * Armin Ronacher (2016), who released it under the 3-Clause BSD license. * See: https://github.com/mitsuhiko/phpserialize/ * * @author Jarmo van Lenthe [github.com/jarmovanlenthe] - * @copyright Armin Ronacher 2016 some rights reserved / Jarmo van Lenthe - * @license BSD-3-Clause + * @copyright Jarmo van Lenthe + * @license Apache-2.0 * * @namespace */ From 00074f914fecd17757d635a26ab4176867f7b819 Mon Sep 17 00:00:00 2001 From: Jarmo van Lenthe Date: Thu, 16 Nov 2017 07:37:11 -0500 Subject: [PATCH 024/124] Change test to Apache-2.0 license --- test/tests/operations/PhpSerialization.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests/operations/PhpSerialization.js b/test/tests/operations/PhpSerialization.js index a38379cd..8d745df9 100644 --- a/test/tests/operations/PhpSerialization.js +++ b/test/tests/operations/PhpSerialization.js @@ -4,7 +4,7 @@ * @author Jarmo van Lenthe * * @copyright Crown Copyright 2017 - * @license BSD-3-Clause + * @license Apache-2.0 */ import TestRegister from "../../TestRegister.js"; From 7a2b75c86160498c2ed0fbefa8782e6fc46200af Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 20 Nov 2017 16:57:04 +0000 Subject: [PATCH 025/124] Updated dependencies --- package-lock.json | 120 ++++++++++++++++++++++++++-------------------- package.json | 12 ++--- 2 files changed, 75 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 028c7481..8fe63ec1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1099,7 +1099,7 @@ "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", - "multicast-dns": "6.1.1", + "multicast-dns": "6.2.0", "multicast-dns-service-types": "1.1.0" } }, @@ -1635,9 +1635,9 @@ } }, "connect-history-api-fallback": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.4.0.tgz", - "integrity": "sha1-PbJPlz9LkjsOgvYZzg3wJBHKYj0=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", "dev": true }, "console-browserify": { @@ -4219,13 +4219,13 @@ "dev": true }, "ink-docstrap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.0.tgz", - "integrity": "sha1-6QBeW7kCXMmpvo5ErYf4rViIyB0=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.2.tgz", + "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", "dev": true, "requires": { - "moment": "2.19.1", - "sanitize-html": "1.14.1" + "moment": "2.19.2", + "sanitize-html": "1.15.0" } }, "inquirer": { @@ -4893,6 +4893,12 @@ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", "dev": true }, + "killable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", + "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5188,6 +5194,12 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -5207,9 +5219,9 @@ "dev": true }, "loglevel": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.1.tgz", - "integrity": "sha1-GJB4yUq5BT7iFaCs2/JCROoPZQI=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.0.tgz", + "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ=", "dev": true }, "longest": { @@ -5472,16 +5484,16 @@ } }, "moment": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", - "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=" + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.2.tgz", + "integrity": "sha512-Rf6jiHPEfxp9+dlzxPTmRHbvoFXsh2L/U8hOupUMpnuecHQmI6cF6lUbJl3QqKPko1u6ujO+FxtcajLVfLpAtA==" }, "moment-timezone": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz", - "integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A=", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", + "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", "requires": { - "moment": "2.19.1" + "moment": "2.19.2" } }, "ms": { @@ -5491,9 +5503,9 @@ "dev": true }, "multicast-dns": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.1.1.tgz", - "integrity": "sha1-bn3oalcIcqsXBYrepxYLvsqBTd4=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.0.tgz", + "integrity": "sha512-tnQqWkuWYHCOVRveiWQf+5KjHUnEmtxUycTy1esL4prQjXoT4qpndIS4fH63zObmHNxIHke3YHRnQrXYpXHf2A==", "dev": true, "requires": { "dns-packet": "1.2.2", @@ -7406,12 +7418,6 @@ "is-equal-shallow": "0.1.3" } }, - "regexp-quote": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz", - "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI=", - "dev": true - }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -7685,13 +7691,14 @@ "dev": true }, "sanitize-html": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.14.1.tgz", - "integrity": "sha1-cw/6Ikm98YMz7/5FsoYXPJxa0Lg=", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.15.0.tgz", + "integrity": "sha512-1jWLToWx8ZV53Z1Jg+2fHl8dNFsxvQt2Cmrk4o/z1+MUdB5EXSU0QVuzlGGhfp7cQrYbEEfMO/TUWHfkBUqujQ==", "dev": true, "requires": { "htmlparser2": "3.9.2", - "regexp-quote": "0.0.0", + "lodash.escaperegexp": "4.1.2", + "srcset": "1.0.0", "xtend": "4.0.1" }, "dependencies": { @@ -7923,7 +7930,7 @@ "faye-websocket": "0.11.1", "inherits": "2.0.3", "json3": "3.3.2", - "url-parse": "1.1.9" + "url-parse": "1.2.0" }, "dependencies": { "faye-websocket": { @@ -7947,9 +7954,9 @@ } }, "sortablejs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.6.1.tgz", - "integrity": "sha1-0SDRA/u59gx9sngUoThAcubG4IM=" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.7.0.tgz", + "integrity": "sha1-gKKyNwq9Vo4c7IwnETHvMKkE+ig=" }, "source-list-map": { "version": "2.0.0", @@ -8041,6 +8048,16 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "srcset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", + "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", + "dev": true, + "requires": { + "array-uniq": "1.0.3", + "number-is-nan": "1.0.1" + } + }, "sshpk": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", @@ -8629,9 +8646,9 @@ } }, "url-parse": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz", - "integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=", + "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==", "dev": true, "requires": { "querystringify": "1.0.0", @@ -8688,9 +8705,9 @@ "dev": true }, "val-loader": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/val-loader/-/val-loader-1.0.2.tgz", - "integrity": "sha1-eQkZgJOzfLoKlr9PbSnelw0JnT0=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/val-loader/-/val-loader-1.1.0.tgz", + "integrity": "sha512-8m62XF42FcfrBBl02rtDY9hQhDcDczrEcr60/aSMxlzJiXAcbAimRPvsDoDa5QcGAusOgOmVTpFtK5EbfZdDwA==", "dev": true, "requires": { "loader-utils": "1.1.0" @@ -8901,9 +8918,9 @@ } }, "webpack-dev-server": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.3.tgz", - "integrity": "sha512-bwq7sj452FRH+oVfgOA8xXKkLYPTNsYB4dQ0Jhz3ydjNJ9MvhpGJtehFW8Z0cEcwNkRRiF4aYbReiSGQ4pbS1w==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz", + "integrity": "sha512-thrqC0EQEoSjXeYgP6pUXcUCZ+LNrKsDPn+mItLnn5VyyNZOJKd06hUP5vqkYwL8nWWXsii0loSF9NHNccT6ow==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -8911,7 +8928,7 @@ "bonjour": "3.5.0", "chokidar": "1.7.0", "compression": "1.7.1", - "connect-history-api-fallback": "1.4.0", + "connect-history-api-fallback": "1.5.0", "debug": "3.1.0", "del": "3.0.0", "express": "4.16.2", @@ -8920,7 +8937,8 @@ "import-local": "0.1.1", "internal-ip": "1.2.0", "ip": "1.1.5", - "loglevel": "1.5.1", + "killable": "1.0.0", + "loglevel": "1.6.0", "opn": "5.1.0", "portfinder": "1.0.13", "selfsigned": "1.10.1", @@ -9106,13 +9124,13 @@ "dev": true, "requires": { "http-parser-js": "0.4.9", - "websocket-extensions": "0.1.2" + "websocket-extensions": "0.1.3" } }, "websocket-extensions": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz", - "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0=", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, "whatwg-encoding": { diff --git a/package.json b/package.json index c2d7fd7d..6962cfee 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "grunt-webpack": "^3.0.2", "html-webpack-plugin": "^2.30.1", "imports-loader": "^0.7.1", - "ink-docstrap": "^1.3.0", + "ink-docstrap": "^1.3.2", "jsdoc-babel": "^0.3.0", "less": "^2.7.3", "less-loader": "^4.0.5", @@ -59,10 +59,10 @@ "postcss-loader": "^2.0.8", "style-loader": "^0.19.0", "url-loader": "^0.6.2", - "val-loader": "^1.0.2", + "val-loader": "^1.1.0", "web-resource-inliner": "^4.2.0", "webpack": "^3.8.1", - "webpack-dev-server": "^2.9.3", + "webpack-dev-server": "^2.9.4", "webpack-node-externals": "^1.6.0", "worker-loader": "^1.1.0" }, @@ -86,12 +86,12 @@ "jsonpath": "^1.0.0", "jsrsasign": "8.0.4", "lodash": "^4.17.4", - "moment": "^2.19.1", - "moment-timezone": "^0.5.13", + "moment": "^2.19.2", + "moment-timezone": "^0.5.14", "node-md6": "^0.1.0", "otp": "^0.1.3", "sladex-blowfish": "^0.8.1", - "sortablejs": "^1.6.1", + "sortablejs": "^1.7.0", "split.js": "^1.3.5", "vkbeautify": "^0.99.3", "xmldom": "^0.1.27", From 7a2f68e14a6e1071855f3dbd57cb436da0b09b6b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 20 Nov 2017 17:45:50 +0000 Subject: [PATCH 026/124] Cosmetic changes to keybindings code --- src/web/BindingsWaiter.js | 73 +++++++++++++++++++++++---------------- src/web/Manager.js | 9 +++-- src/web/html/index.html | 4 +-- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/web/BindingsWaiter.js b/src/web/BindingsWaiter.js index 2454ed59..802590b8 100644 --- a/src/web/BindingsWaiter.js +++ b/src/web/BindingsWaiter.js @@ -23,36 +23,40 @@ const BindingsWaiter = function (app, manager) { * @param {event} e */ BindingsWaiter.prototype.parseInput = function(e) { - let modKey = e.altKey; - if (this.app.options.useMetaKey) modKey = e.metaKey; + const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey; + if (e.ctrlKey && modKey) { let elem; switch (e.code) { - case "KeyF": + case "KeyF": // Focus search e.preventDefault(); - document.getElementById("search").focus(); // Focus search + document.getElementById("search").focus(); break; - case "KeyI": + case "KeyI": // Focus input e.preventDefault(); - document.getElementById("input-text").focus(); // Focus input + document.getElementById("input-text").focus(); break; - case "KeyO": + case "KeyO": // Focus output e.preventDefault(); - document.getElementById("output-text").focus(); // Focus output + document.getElementById("output-text").focus(); break; - case "Period": + case "Period": // Focus next operation + e.preventDefault(); try { - elem = document.activeElement.closest(".operation"); + elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation"); if (elem.parentNode.lastChild === elem) { - elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus(); // if operation is last in recipe, loop around to the top operation's first argument + // If operation is last in recipe, loop around to the top operation's first argument + elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus(); } else { - elem.nextSibling.querySelectorAll(".arg")[0].focus(); //focus first argument of next operation + // 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": + case "KeyB": // Set breakpoint + e.preventDefault(); try { elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0]; if (elem.getAttribute("break") === "false") { @@ -67,7 +71,8 @@ BindingsWaiter.prototype.parseInput = function(e) { // do nothing, just don't throw an error } break; - case "KeyD": + case "KeyD": // Disable operation + e.preventDefault(); try { elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0]; if (elem.getAttribute("disabled") === "false") { @@ -85,29 +90,36 @@ BindingsWaiter.prototype.parseInput = function(e) { // do nothing, just don't throw an error } break; - case "Space": - this.app.bake(); // bake the recipe + case "Space": // Bake + e.preventDefault(); + this.app.bake(); break; - case "Quote": - this.app.bake(true); // step through the recipe + case "Quote": // Step through + e.preventDefault(); + this.app.bake(true); break; - case "KeyC": - this.manager.recipe.clearRecipe(); // clear recipe + case "KeyC": // Clear recipe + e.preventDefault(); + this.manager.recipe.clearRecipe(); break; - case "KeyS": - this.manager.output.saveClick(); // save output to file + case "KeyS": // Save output to file + e.preventDefault(); + this.manager.output.saveClick(); break; - case "KeyL": - this.manager.controls.loadClick(); // load a recipe + case "KeyL": // Load recipe + e.preventDefault(); + this.manager.controls.loadClick(); break; - case "KeyM": - this.manager.controls.switchClick(); // switch input & output + case "KeyM": // Switch input and output + e.preventDefault(); + this.manager.output.switchClick(); break; default: - if (e.code.match(/Digit[0-9]/g)) { + if (e.code.match(/Digit[0-9]/g)) { // Select nth operation e.preventDefault(); try { - document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus(); // select the first argument of the operation corresponding to the number pressed + // 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 } @@ -117,6 +129,7 @@ BindingsWaiter.prototype.parseInput = function(e) { } }; + /** * Updates keybinding list when metaKey option is toggled * @@ -149,12 +162,12 @@ BindingsWaiter.prototype.updateKeybList = function() { Ctrl+${modMac}+o - Place cursor in first argument field
    of the next operation in the recipe + 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 + Place cursor in first argument field of the nth operation in the recipe Ctrl+${modWinLin}+[1-9] Ctrl+${modMac}+[1-9] diff --git a/src/web/Manager.js b/src/web/Manager.js index c9ae1eb5..2b44e6d2 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -77,8 +77,8 @@ Manager.prototype.setup = function() { this.worker.registerChefWorker(); this.recipe.initialiseOperationDragNDrop(); this.controls.autoBakeChange(); - this.seasonal.load(); this.bindings.updateKeybList(); + this.seasonal.load(); }; @@ -92,6 +92,7 @@ Manager.prototype.initialiseEventListeners = function() { 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)); @@ -162,16 +163,14 @@ Manager.prototype.initialiseEventListeners = function() { 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)); - //Keybindings - window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); - $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings)); - // Misc + window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings)); document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app)); }; diff --git a/src/web/html/index.html b/src/web/html/index.html index b1adfad7..66dfcc80 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -328,7 +328,7 @@
    - +
    @@ -486,7 +486,7 @@

    It’s the Cyber Swiss Army Knife.

    -
    +
    From c23d7fd79cbf4daa73f23ab61d43986cce5402b0 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 20 Nov 2017 17:47:48 +0000 Subject: [PATCH 027/124] 6.4.6 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8fe63ec1..de3bc9bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.5", + "version": "6.4.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6962cfee..1c10572a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.5", + "version": "6.4.6", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 7abda44fd656d91970a51c0b42b9adcdf4233d10 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 24 Nov 2017 05:48:40 -0800 Subject: [PATCH 028/124] Added Negative Matching to conditional jumps so negative lookahead is not required. --- src/core/FlowControl.js | 13 ++++++++----- src/core/config/OperationConfig.js | 5 +++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index 4a94ffdf..da6fe8c5 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -201,8 +201,9 @@ const FlowControl = { let ings = state.opList[state.progress].getIngValues(), dish = state.dish, regexStr = ings[0], - jumpNum = ings[1], - maxJumps = ings[2]; + invert = ings[1], + jumpNum = ings[2], + maxJumps = ings[3]; if (jumpNum < 0) { jumpNum--; @@ -212,9 +213,11 @@ const FlowControl = { return state; } - if (regexStr !== "" && dish.get(Dish.STRING).search(regexStr) > -1) { - state.progress += jumpNum; - state.numJumps++; + if (regexStr !== "") { + let strMatch = dish.get(Dish.STRING).search(regexStr) > -1; + if (!invert && strMatch || invert && !strMatch) { + state.progress += jumpNum; + state.numJumps++; } return state; diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 9caa4f91..87564229 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -165,6 +165,11 @@ const OperationConfig = { type: "string", value: "" }, + { + name: "Negative match (logical NOT)", + type: "boolean", + value: false + }, { name: "Number of operations to jump over if match found", type: "number", From fe8049199a1a08026c52ea6bcba53e00bb604944 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 24 Nov 2017 16:32:11 +0000 Subject: [PATCH 029/124] Moved PhpDeserialize.js to PHP.js to encompass possible future PHP-related ops --- src/core/config/Categories.js | 2 +- src/core/config/OperationConfig.js | 6 +++--- src/core/config/modules/Default.js | 4 ++-- .../{PhpSerialization.js => PHP.js} | 20 ++++++++++--------- test/index.js | 2 +- .../{PhpSerialization.js => PHP.js} | 2 +- 6 files changed, 19 insertions(+), 17 deletions(-) rename src/core/operations/{PhpSerialization.js => PHP.js} (91%) rename test/tests/operations/{PhpSerialization.js => PHP.js} (98%) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 09f0187c..3bc672b7 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -66,7 +66,6 @@ const Categories = [ "Encode text", "Decode text", "Swap endianness", - "PHP Deserialize", ] }, { @@ -289,6 +288,7 @@ const Categories = [ "XPath expression", "JPath expression", "CSS selector", + "PHP Deserialize", "Microsoft Script Decoder", "Strip HTML tags", "Diff", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 469a98c1..43072558 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -26,6 +26,7 @@ import JS from "../operations/JS.js"; import MAC from "../operations/MAC.js"; import MorseCode from "../operations/MorseCode.js"; import NetBIOS from "../operations/NetBIOS.js"; +import PHP from "../operations/PHP.js"; import PublicKey from "../operations/PublicKey.js"; import Punycode from "../operations/Punycode.js"; import Rotate from "../operations/Rotate.js"; @@ -35,7 +36,6 @@ import StrUtils from "../operations/StrUtils.js"; import Tidy from "../operations/Tidy.js"; import Unicode from "../operations/Unicode.js"; import URL_ from "../operations/URL.js"; -import PhpSerialization from "../operations/PhpSerialization.js"; /** @@ -3848,14 +3848,14 @@ const OperationConfig = { }, "PHP Deserialize": { module: "Default", - description: "PHP Deserialize a given input.

    This function does not support object tags.

    Output valid JSON: JSON doesn't support integers as keys, where as PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.", + 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: PhpSerialization.OUTPUT_VALID_JSON + value: PHP.OUTPUT_VALID_JSON } ] }, diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 8c13cfd2..dec015a5 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -20,6 +20,7 @@ import NetBIOS from "../../operations/NetBIOS.js"; import Numberwang from "../../operations/Numberwang.js"; import OS from "../../operations/OS.js"; import OTP from "../../operations/OTP.js"; +import PHP from "../../operations/PHP.js"; import QuotedPrintable from "../../operations/QuotedPrintable.js"; import Rotate from "../../operations/Rotate.js"; import SeqUtils from "../../operations/SeqUtils.js"; @@ -27,7 +28,6 @@ import StrUtils from "../../operations/StrUtils.js"; import Tidy from "../../operations/Tidy.js"; import Unicode from "../../operations/Unicode.js"; import UUID from "../../operations/UUID.js"; -import PhpSerialization from "../../operations/PhpSerialization"; /** * Default module. @@ -155,7 +155,7 @@ OpModules.Default = { "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, - "PHP Deserialize": PhpSerialization.PhpDeserialize, + "PHP Deserialize": PHP.runDeserialize, /* diff --git a/src/core/operations/PhpSerialization.js b/src/core/operations/PHP.js similarity index 91% rename from src/core/operations/PhpSerialization.js rename to src/core/operations/PHP.js index 3b2d8a20..e4bb0b5b 100644 --- a/src/core/operations/PhpSerialization.js +++ b/src/core/operations/PHP.js @@ -1,8 +1,5 @@ /** - * Php Serialization operations. - * This Javascript implementation is based on the Python implementation by - * Armin Ronacher (2016), who released it under the 3-Clause BSD license. - * See: https://github.com/mitsuhiko/phpserialize/ + * PHP operations. * * @author Jarmo van Lenthe [github.com/jarmovanlenthe] * @copyright Jarmo van Lenthe @@ -10,8 +7,7 @@ * * @namespace */ - -const PhpSerialization = { +const PHP = { /** * @constant @@ -20,12 +16,17 @@ const PhpSerialization = { OUTPUT_VALID_JSON: true, /** - * Deserializes a PHP serialized input + * PHP Deserialize operation. + * + * This Javascript implementation is based on the Python implementation by + * Armin Ronacher (2016), who released it under the 3-Clause BSD license. + * See: https://github.com/mitsuhiko/phpserialize/ + * * @param {string} input * @param {Object[]} args * @returns {string} */ - PhpDeserialize: function (input, args) { + runDeserialize: function (input, args) { /** * Recursive method for deserializing. * @returns {*} @@ -153,6 +154,7 @@ const PhpSerialization = { let inputPart = input.split(""); return handleInput(); } + }; -export default PhpSerialization; +export default PHP; diff --git a/test/index.js b/test/index.js index 9fa4dcdc..748e1103 100644 --- a/test/index.js +++ b/test/index.js @@ -25,9 +25,9 @@ import "./tests/operations/Hash.js"; import "./tests/operations/Image.js"; import "./tests/operations/MorseCode.js"; import "./tests/operations/MS.js"; +import "./tests/operations/PHP.js"; import "./tests/operations/StrUtils.js"; import "./tests/operations/SeqUtils.js"; -import "./tests/operations/PhpSerialization.js"; let allTestsPassing = true; diff --git a/test/tests/operations/PhpSerialization.js b/test/tests/operations/PHP.js similarity index 98% rename from test/tests/operations/PhpSerialization.js rename to test/tests/operations/PHP.js index 8d745df9..a42ee430 100644 --- a/test/tests/operations/PhpSerialization.js +++ b/test/tests/operations/PHP.js @@ -1,5 +1,5 @@ /** - * PHP Serialization tests. + * PHP tests. * * @author Jarmo van Lenthe * From 021cae1a9551eeea611fd2708dbe6891efb60557 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 24 Nov 2017 16:33:46 +0000 Subject: [PATCH 030/124] 6.5.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index de3bc9bb..3f0fddf5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.6", + "version": "6.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1c10572a..f62b95e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.4.6", + "version": "6.5.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From f01c0adee2fce99312c6d75f8c2845c5dde0de37 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 24 Nov 2017 10:12:08 -0800 Subject: [PATCH 031/124] Changed jumps from index based to label base. Updated test. --- src/core/FlowControl.js | 46 +++++++++++++++++++--------- src/core/config/Categories.js | 1 + src/core/config/OperationConfig.js | 26 ++++++++++++---- src/core/config/modules/Default.js | 1 + test/tests/operations/FlowControl.js | 32 ++++++++++++++----- 5 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index da6fe8c5..3cfce77b 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -170,18 +170,14 @@ const FlowControl = { */ runJump: function(state) { let ings = state.opList[state.progress].getIngValues(), - jumpNum = ings[0], + jmpIndex = FlowControl._getLabelIndex(ings[0], state), maxJumps = ings[1]; - if (jumpNum < 0) { - jumpNum--; - } - - if (state.numJumps >= maxJumps) { + if (state.numJumps >= maxJumps || jmpIndex == -1) { return state; } - state.progress += jumpNum; + state.progress = jmpIndex; state.numJumps++; return state; }, @@ -202,27 +198,49 @@ const FlowControl = { dish = state.dish, regexStr = ings[0], invert = ings[1], - jumpNum = ings[2], + jmpIndex = FlowControl._getLabelIndex(ings[2], state), maxJumps = ings[3]; - if (jumpNum < 0) { - jumpNum--; - } - - if (state.numJumps >= maxJumps) { + if (state.numJumps >= maxJumps || jmpIndex == -1) { return state; } if (regexStr !== "") { let strMatch = dish.get(Dish.STRING).search(regexStr) > -1; if (!invert && strMatch || invert && !strMatch) { - state.progress += jumpNum; + state.progress = jmpIndex; state.numJumps++; + } } return state; }, + /** + * Returns the index of a label. + * + * @param {Object} state + * @param {string} name + * @returns {number} + */ + + _getLabelIndex: function(name, state) { + let index = -1; + for (let o = 0; o < state.opList.length; o++) { + let operation = state.opList[o]; + if (operation.getConfig()["op"] === "Label"){ + let ings = operation.getIngValues(); + if (name === ings[0]) { + index = o; + break; + } + } + } + return index; + }, + + + /** * Return operation. diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index f04b5fd9..12bb31c4 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -319,6 +319,7 @@ const Categories = [ "Fork", "Merge", "Register", + "Label", "Jump", "Conditional Jump", "Return", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 87564229..5a7fd839 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -142,9 +142,9 @@ const OperationConfig = { flowControl: true, args: [ { - name: "Number of operations to jump over", - type: "number", - value: 0 + name: "The Label to Jump to", + type: "string", + value: "" }, { name: "Maximum jumps (if jumping backwards)", @@ -171,9 +171,9 @@ const OperationConfig = { value: false }, { - name: "Number of operations to jump over if match found", - type: "number", - value: 0 + name: "The Label to Jump to", + type: "string", + value: "" }, { name: "Maximum jumps (if jumping backwards)", @@ -182,6 +182,20 @@ const OperationConfig = { } ] }, + "Label": { + 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: "Jump Label", + type: "string", + value: "" + } + ] + }, "Return": { module: "Default", description: "End execution of operations at this point in the recipe.", diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 682db223..b6261769 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -151,6 +151,7 @@ OpModules.Default = { "Fork": FlowControl.runFork, "Merge": FlowControl.runMerge, "Register": FlowControl.runRegister, + "Label": FlowControl.runComment, "Jump": FlowControl.runJump, "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, diff --git a/test/tests/operations/FlowControl.js b/test/tests/operations/FlowControl.js index 42a4bfd3..f96a9e4a 100644 --- a/test/tests/operations/FlowControl.js +++ b/test/tests/operations/FlowControl.js @@ -60,14 +60,15 @@ TestRegister.addTests([ 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", "2", "10"]}, + {"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: skips 0", + name: "Jump: Empty Label", input: [ "should be changed", ].join("\n"), @@ -77,7 +78,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Jump", - args: [0, 10], + args: ["", 10], }, { op: "Find / Replace", @@ -105,7 +106,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Jump", - args: [1, 10], + args: ["skipReplace", 10], }, { op: "Find / Replace", @@ -120,6 +121,10 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", + args: ["skipReplace"] + }, ], }, { @@ -137,7 +142,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Conditional Jump", - args: ["match", 0, 0], + args: ["match", false, "", 0], }, { op: "Find / Replace", @@ -212,7 +217,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "Conditional Jump", - args: ["match", 1, 10], + args: ["match", false, "skip match", 10], }, { op: "Find / Replace", @@ -227,6 +232,9 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", args: ["skip match"], + }, { op: "Find / Replace", args: [ @@ -251,9 +259,13 @@ TestRegister.addTests([ "replaced", ].join("\n"), recipeConfig: [ + { + op: "Label", + args: ["back to the beginning"], + }, { op: "Jump", - args: [1], + args: ["skip replace"], }, { op: "Find / Replace", @@ -268,9 +280,13 @@ TestRegister.addTests([ true, ], }, + { + op: "Label", + args: ["skip replace"], + }, { op: "Conditional Jump", - args: ["match", -2, 10], + args: ["match", false, "back to the beginning", 10], }, ], }, From e500cfae757f10b8cd0dcaa2f2524f7457af9997 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 24 Nov 2017 10:31:26 -0800 Subject: [PATCH 032/124] Fixed errors --- src/core/FlowControl.js | 8 +++----- src/core/config/OperationConfig.js | 2 +- test/tests/operations/FlowControl.js | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index 3cfce77b..ea798d7e 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -173,7 +173,7 @@ const FlowControl = { jmpIndex = FlowControl._getLabelIndex(ings[0], state), maxJumps = ings[1]; - if (state.numJumps >= maxJumps || jmpIndex == -1) { + if (state.numJumps >= maxJumps || jmpIndex === -1) { return state; } @@ -201,7 +201,7 @@ const FlowControl = { jmpIndex = FlowControl._getLabelIndex(ings[2], state), maxJumps = ings[3]; - if (state.numJumps >= maxJumps || jmpIndex == -1) { + if (state.numJumps >= maxJumps || jmpIndex === -1) { return state; } @@ -228,7 +228,7 @@ const FlowControl = { let index = -1; for (let o = 0; o < state.opList.length; o++) { let operation = state.opList[o]; - if (operation.getConfig()["op"] === "Label"){ + if (operation.getConfig().op === "Label"){ let ings = operation.getIngValues(); if (name === ings[0]) { index = o; @@ -240,8 +240,6 @@ const FlowControl = { }, - - /** * Return operation. * diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 5a7fd839..e3b871ef 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -184,7 +184,7 @@ const OperationConfig = { }, "Label": { module: "Default", - description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.", + description: "Provides a location for for conditional and fixed jumps to jump.", inputType: "string", outputType: "string", flowControl: true, diff --git a/test/tests/operations/FlowControl.js b/test/tests/operations/FlowControl.js index f96a9e4a..04ed93eb 100644 --- a/test/tests/operations/FlowControl.js +++ b/test/tests/operations/FlowControl.js @@ -260,8 +260,8 @@ TestRegister.addTests([ ].join("\n"), recipeConfig: [ { - op: "Label", - args: ["back to the beginning"], + op: "Label", + args: ["back to the beginning"], }, { op: "Jump", From 9bc6c46dc391f166aaa16477bce8afc7061979ab Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sat, 16 Dec 2017 09:10:52 -0500 Subject: [PATCH 033/124] Fixed HOTP, TOTP and added test for HOTP --- src/core/operations/OTP.js | 5 +++-- test/index.js | 1 + test/tests/operations/OTP.js | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/tests/operations/OTP.js diff --git a/src/core/operations/OTP.js b/src/core/operations/OTP.js index ff67d1c8..20205053 100755 --- a/src/core/operations/OTP.js +++ b/src/core/operations/OTP.js @@ -1,5 +1,6 @@ import otp from "otp"; import Base64 from "./Base64.js"; +import Utils from "../Utils.js"; /** * One-Time Password operations. @@ -24,7 +25,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(input, []), + secret: Base64.runTo32(Utils.strToByteArray(input), []), epoch: args[3], timeSlice: args[4] }); @@ -44,7 +45,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(input, []), + secret: Base64.runTo32(Utils.strToByteArray(input), []), }); const counter = args[3]; return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`; diff --git a/test/index.js b/test/index.js index 773a5b14..d444fc51 100644 --- a/test/index.js +++ b/test/index.js @@ -25,6 +25,7 @@ import "./tests/operations/Hash.js"; import "./tests/operations/Image.js"; import "./tests/operations/MorseCode.js"; import "./tests/operations/MS.js"; +import "./tests/operations/OTP.js"; import "./tests/operations/StrUtils.js"; import "./tests/operations/SeqUtils.js"; diff --git a/test/tests/operations/OTP.js b/test/tests/operations/OTP.js new file mode 100644 index 00000000..b321e7cf --- /dev/null +++ b/test/tests/operations/OTP.js @@ -0,0 +1,23 @@ +/** + * OTP HOTP tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Generate HOTP", + input: "12345678901234567890", + expectedOutput: "URI: otpauth://hotp/OTPAuthentication?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ\n\nPassword: 755224", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["", 32, 6, 0], + }, + ], + }, +]); From ae8d1f21786a5fe2216bb6ebf9d22ff0dd57ce98 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:19:10 -0500 Subject: [PATCH 034/124] start of math operations --- src/core/config/OperationConfig.js | 19 +++++ src/core/operations/Arithmetic.js | 130 +++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/core/operations/Arithmetic.js diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 9caa4f91..81444880 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -1,3 +1,4 @@ +import Arithmetic from "../operations/Arithmetic.js"; import Base from "../operations/Base.js"; import Base58 from "../operations/Base58.js"; import Base64 from "../operations/Base64.js"; @@ -656,6 +657,24 @@ const OperationConfig = { } ] }, + "Arithmetic": { + module: "Default", + description: "Conducts mathamatical operations on a list of numbers", + inputType: "string" + outputType: "string" + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + }, + { + name: "Operation" + type: "option", + value: Arithmetic.OPERATIONS + } + ] + }, "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.", diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js new file mode 100644 index 00000000..8a840a29 --- /dev/null +++ b/src/core/operations/Arithmetic.js @@ -0,0 +1,130 @@ +import Utils from "../Utils.js"; + +/** + * Math operations on numbers. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + * + * @namespace + */ +const Arithmetic = { + + /** + * @constant + * @default + */ + DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], + + /** + * @constant + * @default + */ + OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], + + /** + * A mapping of operation names to their function. + * @constant + */ + opMap: { + "Sub": _sub, + "Sum": _sum, + "Multiply": _multiply, + "Divide": _divide, + "Mean": _mean, + "Median": _median, + "Mode": _mode, + }, + + /** + * + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runOp: function(input, args) { + const delim = Utils.charRep[args[0] || "Space"]; + let splitNumbers = input.split(delim), + numbers = [], + num, + retVal; + for (i = 0; i < splitNumbers.length; i++) { + if splitNumbers[i].indexOf(".") { + num = parseFloat(splitNumbers[i].trim()); + } else { + num = parseInt(splitNumbers[i].trim()); + } + if (num !== "NaN") { + numbers.append(num); + } + } + num = Arithmetic.opMap[args[1] || "Sum"](numbers); + if (num !== null) { + return "The values " + args[1] + "equal: " + num; + } + throw "Error with Arithmetic Operation: " + args[1]; + }, + + + _sum: function(data) { + let total = 0; + for (i = 0; i < data.length; i++) { + total += data[i]; + } + return total; + }, + + _sub: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total -= data[i]; + } + } else { + total = null; + } + return total; + }, + + _multiply: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total *= data[i]; + } + } else { + total = null; + } + return total; + }, + + _divide: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total /= data[i] + } + } else { + total = null; + } + return total; + }, + + _mean: function(data) { + let total = 0; + if (data.length > 1) { + total = Arithmetic._sum(data) / data.length; + } else { + total = null; + } + return total; + }, + +}; + +export default Arithmetic; From 772f9a806e8136ac235a7614136a647151afa1b8 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:20:58 -0500 Subject: [PATCH 035/124] Added additional arithmetic source --- src/core/config/Categories.js | 1 + src/core/config/OperationConfig.js | 6 +-- src/core/config/modules/Default.js | 2 + src/core/operations/Arithmetic.js | 80 +++++++++++++++++++++--------- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index f04b5fd9..7faa75f2 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -159,6 +159,7 @@ const Categories = [ { name: "Utils", ops: [ + "Arithmetic", "Diff", "Remove whitespace", "Remove null bytes", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 81444880..65d1d065 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -660,8 +660,8 @@ const OperationConfig = { "Arithmetic": { module: "Default", description: "Conducts mathamatical operations on a list of numbers", - inputType: "string" - outputType: "string" + inputType: "string", + outputType: "string", args: [ { name: "Delimiter", @@ -669,7 +669,7 @@ const OperationConfig = { value: Arithmetic.DELIM_OPTIONS }, { - name: "Operation" + name: "Operation", type: "option", value: Arithmetic.OPERATIONS } diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 682db223..5f049ac7 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -1,4 +1,5 @@ import FlowControl from "../../FlowControl.js"; +import Arithmetic from "../../operations/Arithmetic.js"; import Base from "../../operations/Base.js"; import Base58 from "../../operations/Base58.js"; import Base64 from "../../operations/Base64.js"; @@ -155,6 +156,7 @@ OpModules.Default = { "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, + "Arithmetic": Arithmetic.runOp, /* diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 8a840a29..ef6643e4 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -23,20 +23,6 @@ const Arithmetic = { */ OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], - /** - * A mapping of operation names to their function. - * @constant - */ - opMap: { - "Sub": _sub, - "Sum": _sum, - "Multiply": _multiply, - "Divide": _divide, - "Mean": _mean, - "Median": _median, - "Mode": _mode, - }, - /** * * @@ -48,13 +34,12 @@ const Arithmetic = { const delim = Utils.charRep[args[0] || "Space"]; let splitNumbers = input.split(delim), numbers = [], - num, - retVal; - for (i = 0; i < splitNumbers.length; i++) { - if splitNumbers[i].indexOf(".") { + num; + for (let i = 0; i < splitNumbers.length; i++) { + if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); } else { - num = parseInt(splitNumbers[i].trim()); + num = parseInt(splitNumbers[i].trim(), 10); } if (num !== "NaN") { numbers.append(num); @@ -68,19 +53,33 @@ const Arithmetic = { }, + /** + * Adds an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _sum: function(data) { let total = 0; - for (i = 0; i < data.length; i++) { + for (let i = 0; i < data.length; i++) { total += data[i]; } return total; }, + /** + * Subtracts an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _sub: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { + for (let i = 1; i < data.length; i++) { total -= data[i]; } } else { @@ -89,11 +88,18 @@ const Arithmetic = { return total; }, + /** + * Multiplies an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _multiply: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { + for (let i = 1; i < data.length; i++) { total *= data[i]; } } else { @@ -102,12 +108,19 @@ const Arithmetic = { return total; }, + /** + * Divides an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _divide: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { - total /= data[i] + for (let i = 1; i < data.length; i++) { + total /= data[i]; } } else { total = null; @@ -115,6 +128,13 @@ const Arithmetic = { return total; }, + /** + * Finds the mean of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _mean: function(data) { let total = 0; if (data.length > 1) { @@ -125,6 +145,18 @@ const Arithmetic = { return total; }, + /** + * A mapping of operation names to their function. + * @constant + */ + opMap: { + "Sub": Arithmetic._sum, + "Sum": Arithmetic._sub, + "Multiply": Arithmetic._multiply, + "Divide": Arithmetic._divide, + "Mean": Arithmetic._mean, + }, + }; export default Arithmetic; From 6ad3728314dcfb7caae95cab81b2a4d0a1536b0f Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:29:31 -0500 Subject: [PATCH 036/124] changed op array --- src/core/operations/Arithmetic.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index ef6643e4..1278ac3b 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -150,11 +150,11 @@ const Arithmetic = { * @constant */ opMap: { - "Sub": Arithmetic._sum, - "Sum": Arithmetic._sub, - "Multiply": Arithmetic._multiply, - "Divide": Arithmetic._divide, - "Mean": Arithmetic._mean, + "Sum": function(numArray) { return Arithmetic._sum(numArray); }, + "Sub": function(numArray) { return Arithmetic._sub(numArray); }, + "Multiply": function(numArray) { return Arithmetic._multiply(numArray); }, + "Divide": function(numArray) { return Arithmetic._divide(numArray); }, + "Mean": function(numArray) { return Arithmetic._mean(numArray); }, }, }; From 298e8e849199bd8c4d22b5625abac9a3c1d8184a Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 21:57:09 -0500 Subject: [PATCH 037/124] Inital commit for pull --- src/core/operations/Arithmetic.js | 140 ++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 46 deletions(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 1278ac3b..ffcb6c86 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -21,7 +21,15 @@ const Arithmetic = { * @constant * @default */ - OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], + OPERATIONS: [ + "Sum", + "Sub", + "Multiply", + "Divide", + "Mean", + "Median", + "Standard Deviation" + ], /** * @@ -39,17 +47,17 @@ const Arithmetic = { if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); } else { - num = parseInt(splitNumbers[i].trim(), 10); + num = parseInt(splitNumbers[i].trim(), 0); } - if (num !== "NaN") { - numbers.append(num); + if (!isNaN(num)) { + numbers.push(num); } } num = Arithmetic.opMap[args[1] || "Sum"](numbers); - if (num !== null) { - return "The values " + args[1] + "equal: " + num; + if (num === null) { + return ""; } - throw "Error with Arithmetic Operation: " + args[1]; + return num; }, @@ -61,11 +69,11 @@ const Arithmetic = { * @returns {number} */ _sum: function(data) { - let total = 0; - for (let i = 0; i < data.length; i++) { - total += data[i]; + if (data.length > 0) { + return data.reduce((acc, curr) => acc + curr); + } else { + return null; } - return total; }, /** @@ -76,16 +84,11 @@ const Arithmetic = { * @returns {number} */ _sub: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total -= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc - curr); } else { - total = null; + return null; } - return total; }, /** @@ -96,16 +99,11 @@ const Arithmetic = { * @returns {number} */ _multiply: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total *= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc * curr); } else { - total = null; + return null; } - return total; }, /** @@ -116,16 +114,11 @@ const Arithmetic = { * @returns {number} */ _divide: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total /= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc / curr); } else { - total = null; + return null; } - return total; }, /** @@ -136,27 +129,82 @@ const Arithmetic = { * @returns {number} */ _mean: function(data) { - let total = 0; - if (data.length > 1) { - total = Arithmetic._sum(data) / data.length; + if (data.length > 0) { + return Arithmetic._sum(data) / data.length; } else { - total = null; + return null; + } + }, + + /** + * Finds the median of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _median: function (data) { + if ((data.length % 2) === 0) { + let first, second; + data.sort(function(a, b){ + return a - b; + }); + first = data[Math.floor(data.length / 2)]; + second = data[Math.floor(data.length / 2) - 1]; + return Arithmetic._mean([first, second]); + } else { + return data[Math.floor(data.length / 2)]; + } + }, + + /** + * Finds the standard deviation of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _stdDev: function (data) { + if (data.length > 0) { + let avg = Arithmetic._mean(data); + let devSum = 0; + for (let i = 0; i < data.length; i++) { + devSum += (data[i] - avg) ** 2; + } + return Math.sqrt(devSum / data.length); + } else { + return null; } - return total; }, /** * A mapping of operation names to their function. + * * @constant */ opMap: { - "Sum": function(numArray) { return Arithmetic._sum(numArray); }, - "Sub": function(numArray) { return Arithmetic._sub(numArray); }, - "Multiply": function(numArray) { return Arithmetic._multiply(numArray); }, - "Divide": function(numArray) { return Arithmetic._divide(numArray); }, - "Mean": function(numArray) { return Arithmetic._mean(numArray); }, + "Sum": function(numArray) { + return Arithmetic._sum(numArray); + }, + "Sub": function(numArray) { + return Arithmetic._sub(numArray); + }, + "Multiply": function(numArray) { + return Arithmetic._multiply(numArray); + }, + "Divide": function(numArray) { + return Arithmetic._divide(numArray); + }, + "Mean": function(numArray) { + return Arithmetic._mean(numArray); + }, + "Median": function(numArray) { + return Arithmetic._median(numArray); + }, + "Standard Deviation": function (numArray) { + return Arithmetic._stdDev(numArray); + }, }, - }; export default Arithmetic; From 2b47631f4d9c1174ca841005f4cc04c12df7225c Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 22:15:13 -0500 Subject: [PATCH 038/124] minor fix --- src/core/operations/Arithmetic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index ffcb6c86..1151c28f 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -57,7 +57,7 @@ const Arithmetic = { if (num === null) { return ""; } - return num; + return num.toString(); }, From b9b4147c2fdfab8ed2bf12d9720c765be9cdcc8e Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:19:10 -0500 Subject: [PATCH 039/124] start of math operations --- src/core/config/OperationConfig.js | 19 +++++ src/core/operations/Arithmetic.js | 130 +++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/core/operations/Arithmetic.js diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 43072558..ff609ba2 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -1,3 +1,4 @@ +import Arithmetic from "../operations/Arithmetic.js"; import Base from "../operations/Base.js"; import Base58 from "../operations/Base58.js"; import Base64 from "../operations/Base64.js"; @@ -657,6 +658,24 @@ const OperationConfig = { } ] }, + "Arithmetic": { + module: "Default", + description: "Conducts mathamatical operations on a list of numbers", + inputType: "string" + outputType: "string" + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS + }, + { + name: "Operation" + type: "option", + value: Arithmetic.OPERATIONS + } + ] + }, "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.", diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js new file mode 100644 index 00000000..8a840a29 --- /dev/null +++ b/src/core/operations/Arithmetic.js @@ -0,0 +1,130 @@ +import Utils from "../Utils.js"; + +/** + * Math operations on numbers. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * @copyright Crown Copyright 2016 + * @license Apache-2.0 + * + * @namespace + */ +const Arithmetic = { + + /** + * @constant + * @default + */ + DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], + + /** + * @constant + * @default + */ + OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], + + /** + * A mapping of operation names to their function. + * @constant + */ + opMap: { + "Sub": _sub, + "Sum": _sum, + "Multiply": _multiply, + "Divide": _divide, + "Mean": _mean, + "Median": _median, + "Mode": _mode, + }, + + /** + * + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runOp: function(input, args) { + const delim = Utils.charRep[args[0] || "Space"]; + let splitNumbers = input.split(delim), + numbers = [], + num, + retVal; + for (i = 0; i < splitNumbers.length; i++) { + if splitNumbers[i].indexOf(".") { + num = parseFloat(splitNumbers[i].trim()); + } else { + num = parseInt(splitNumbers[i].trim()); + } + if (num !== "NaN") { + numbers.append(num); + } + } + num = Arithmetic.opMap[args[1] || "Sum"](numbers); + if (num !== null) { + return "The values " + args[1] + "equal: " + num; + } + throw "Error with Arithmetic Operation: " + args[1]; + }, + + + _sum: function(data) { + let total = 0; + for (i = 0; i < data.length; i++) { + total += data[i]; + } + return total; + }, + + _sub: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total -= data[i]; + } + } else { + total = null; + } + return total; + }, + + _multiply: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total *= data[i]; + } + } else { + total = null; + } + return total; + }, + + _divide: function(data) { + let total = 0; + if (data.length > 1) { + total = data[0]; + for (i = 1; i < data.length; i++) { + total /= data[i] + } + } else { + total = null; + } + return total; + }, + + _mean: function(data) { + let total = 0; + if (data.length > 1) { + total = Arithmetic._sum(data) / data.length; + } else { + total = null; + } + return total; + }, + +}; + +export default Arithmetic; From 5368040e83279a7032e4f3d470e62b0db17e11d6 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:20:58 -0500 Subject: [PATCH 040/124] Added additional arithmetic source --- src/core/config/Categories.js | 1 + src/core/config/OperationConfig.js | 6 +-- src/core/config/modules/Default.js | 5 ++ src/core/operations/Arithmetic.js | 80 +++++++++++++++++++++--------- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 3bc672b7..2109ff15 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -159,6 +159,7 @@ const Categories = [ { name: "Utils", ops: [ + "Arithmetic", "Diff", "Remove whitespace", "Remove null bytes", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index ff609ba2..9f41f2f8 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -661,8 +661,8 @@ const OperationConfig = { "Arithmetic": { module: "Default", description: "Conducts mathamatical operations on a list of numbers", - inputType: "string" - outputType: "string" + inputType: "string", + outputType: "string", args: [ { name: "Delimiter", @@ -670,7 +670,7 @@ const OperationConfig = { value: Arithmetic.DELIM_OPTIONS }, { - name: "Operation" + name: "Operation", type: "option", value: Arithmetic.OPERATIONS } diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index dec015a5..5068254e 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -1,4 +1,5 @@ import FlowControl from "../../FlowControl.js"; +import Arithmetic from "../../operations/Arithmetic.js"; import Base from "../../operations/Base.js"; import Base58 from "../../operations/Base58.js"; import Base64 from "../../operations/Base64.js"; @@ -155,7 +156,11 @@ OpModules.Default = { "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, +<<<<<<< HEAD "PHP Deserialize": PHP.runDeserialize, +======= + "Arithmetic": Arithmetic.runOp, +>>>>>>> Added additional arithmetic source /* diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 8a840a29..ef6643e4 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -23,20 +23,6 @@ const Arithmetic = { */ OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], - /** - * A mapping of operation names to their function. - * @constant - */ - opMap: { - "Sub": _sub, - "Sum": _sum, - "Multiply": _multiply, - "Divide": _divide, - "Mean": _mean, - "Median": _median, - "Mode": _mode, - }, - /** * * @@ -48,13 +34,12 @@ const Arithmetic = { const delim = Utils.charRep[args[0] || "Space"]; let splitNumbers = input.split(delim), numbers = [], - num, - retVal; - for (i = 0; i < splitNumbers.length; i++) { - if splitNumbers[i].indexOf(".") { + num; + for (let i = 0; i < splitNumbers.length; i++) { + if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); } else { - num = parseInt(splitNumbers[i].trim()); + num = parseInt(splitNumbers[i].trim(), 10); } if (num !== "NaN") { numbers.append(num); @@ -68,19 +53,33 @@ const Arithmetic = { }, + /** + * Adds an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _sum: function(data) { let total = 0; - for (i = 0; i < data.length; i++) { + for (let i = 0; i < data.length; i++) { total += data[i]; } return total; }, + /** + * Subtracts an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _sub: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { + for (let i = 1; i < data.length; i++) { total -= data[i]; } } else { @@ -89,11 +88,18 @@ const Arithmetic = { return total; }, + /** + * Multiplies an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _multiply: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { + for (let i = 1; i < data.length; i++) { total *= data[i]; } } else { @@ -102,12 +108,19 @@ const Arithmetic = { return total; }, + /** + * Divides an array of numbers and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _divide: function(data) { let total = 0; if (data.length > 1) { total = data[0]; - for (i = 1; i < data.length; i++) { - total /= data[i] + for (let i = 1; i < data.length; i++) { + total /= data[i]; } } else { total = null; @@ -115,6 +128,13 @@ const Arithmetic = { return total; }, + /** + * Finds the mean of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ _mean: function(data) { let total = 0; if (data.length > 1) { @@ -125,6 +145,18 @@ const Arithmetic = { return total; }, + /** + * A mapping of operation names to their function. + * @constant + */ + opMap: { + "Sub": Arithmetic._sum, + "Sum": Arithmetic._sub, + "Multiply": Arithmetic._multiply, + "Divide": Arithmetic._divide, + "Mean": Arithmetic._mean, + }, + }; export default Arithmetic; From ef0d3b73b0db55f343f800bb17eca350866e8a51 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 15:29:31 -0500 Subject: [PATCH 041/124] changed op array --- src/core/operations/Arithmetic.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index ef6643e4..1278ac3b 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -150,11 +150,11 @@ const Arithmetic = { * @constant */ opMap: { - "Sub": Arithmetic._sum, - "Sum": Arithmetic._sub, - "Multiply": Arithmetic._multiply, - "Divide": Arithmetic._divide, - "Mean": Arithmetic._mean, + "Sum": function(numArray) { return Arithmetic._sum(numArray); }, + "Sub": function(numArray) { return Arithmetic._sub(numArray); }, + "Multiply": function(numArray) { return Arithmetic._multiply(numArray); }, + "Divide": function(numArray) { return Arithmetic._divide(numArray); }, + "Mean": function(numArray) { return Arithmetic._mean(numArray); }, }, }; From f9ddee7d806b5fcc091ad6e86a9e04581297d2b4 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 21:57:09 -0500 Subject: [PATCH 042/124] Inital commit for pull --- src/core/operations/Arithmetic.js | 140 ++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 46 deletions(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 1278ac3b..ffcb6c86 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -21,7 +21,15 @@ const Arithmetic = { * @constant * @default */ - OPERATIONS: ["Sum", "Sub", "Multiply", "Divide", "Mean", "Median", "Mode"], + OPERATIONS: [ + "Sum", + "Sub", + "Multiply", + "Divide", + "Mean", + "Median", + "Standard Deviation" + ], /** * @@ -39,17 +47,17 @@ const Arithmetic = { if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); } else { - num = parseInt(splitNumbers[i].trim(), 10); + num = parseInt(splitNumbers[i].trim(), 0); } - if (num !== "NaN") { - numbers.append(num); + if (!isNaN(num)) { + numbers.push(num); } } num = Arithmetic.opMap[args[1] || "Sum"](numbers); - if (num !== null) { - return "The values " + args[1] + "equal: " + num; + if (num === null) { + return ""; } - throw "Error with Arithmetic Operation: " + args[1]; + return num; }, @@ -61,11 +69,11 @@ const Arithmetic = { * @returns {number} */ _sum: function(data) { - let total = 0; - for (let i = 0; i < data.length; i++) { - total += data[i]; + if (data.length > 0) { + return data.reduce((acc, curr) => acc + curr); + } else { + return null; } - return total; }, /** @@ -76,16 +84,11 @@ const Arithmetic = { * @returns {number} */ _sub: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total -= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc - curr); } else { - total = null; + return null; } - return total; }, /** @@ -96,16 +99,11 @@ const Arithmetic = { * @returns {number} */ _multiply: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total *= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc * curr); } else { - total = null; + return null; } - return total; }, /** @@ -116,16 +114,11 @@ const Arithmetic = { * @returns {number} */ _divide: function(data) { - let total = 0; - if (data.length > 1) { - total = data[0]; - for (let i = 1; i < data.length; i++) { - total /= data[i]; - } + if (data.length > 0) { + return data.reduce((acc, curr) => acc / curr); } else { - total = null; + return null; } - return total; }, /** @@ -136,27 +129,82 @@ const Arithmetic = { * @returns {number} */ _mean: function(data) { - let total = 0; - if (data.length > 1) { - total = Arithmetic._sum(data) / data.length; + if (data.length > 0) { + return Arithmetic._sum(data) / data.length; } else { - total = null; + return null; + } + }, + + /** + * Finds the median of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _median: function (data) { + if ((data.length % 2) === 0) { + let first, second; + data.sort(function(a, b){ + return a - b; + }); + first = data[Math.floor(data.length / 2)]; + second = data[Math.floor(data.length / 2) - 1]; + return Arithmetic._mean([first, second]); + } else { + return data[Math.floor(data.length / 2)]; + } + }, + + /** + * Finds the standard deviation of a number array and returns the value. + * + * @private + * @param {number[]} data + * @returns {number} + */ + _stdDev: function (data) { + if (data.length > 0) { + let avg = Arithmetic._mean(data); + let devSum = 0; + for (let i = 0; i < data.length; i++) { + devSum += (data[i] - avg) ** 2; + } + return Math.sqrt(devSum / data.length); + } else { + return null; } - return total; }, /** * A mapping of operation names to their function. + * * @constant */ opMap: { - "Sum": function(numArray) { return Arithmetic._sum(numArray); }, - "Sub": function(numArray) { return Arithmetic._sub(numArray); }, - "Multiply": function(numArray) { return Arithmetic._multiply(numArray); }, - "Divide": function(numArray) { return Arithmetic._divide(numArray); }, - "Mean": function(numArray) { return Arithmetic._mean(numArray); }, + "Sum": function(numArray) { + return Arithmetic._sum(numArray); + }, + "Sub": function(numArray) { + return Arithmetic._sub(numArray); + }, + "Multiply": function(numArray) { + return Arithmetic._multiply(numArray); + }, + "Divide": function(numArray) { + return Arithmetic._divide(numArray); + }, + "Mean": function(numArray) { + return Arithmetic._mean(numArray); + }, + "Median": function(numArray) { + return Arithmetic._median(numArray); + }, + "Standard Deviation": function (numArray) { + return Arithmetic._stdDev(numArray); + }, }, - }; export default Arithmetic; From a9e60d345072b4065861faf6e5b8f4a4badca64f Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 22:15:13 -0500 Subject: [PATCH 043/124] minor fix --- src/core/operations/Arithmetic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index ffcb6c86..1151c28f 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -57,7 +57,7 @@ const Arithmetic = { if (num === null) { return ""; } - return num; + return num.toString(); }, From 81082ea001e4db9948c2e4089c695a389b72d416 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sun, 17 Dec 2017 23:45:15 -0500 Subject: [PATCH 044/124] I really need to learn git --- src/core/config/modules/Default.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 83545221..6f672ce2 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -156,15 +156,8 @@ OpModules.Default = { "Conditional Jump": FlowControl.runCondJump, "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, -<<<<<<< HEAD -<<<<<<< HEAD "PHP Deserialize": PHP.runDeserialize, -======= "Arithmetic": Arithmetic.runOp, ->>>>>>> Added additional arithmetic source -======= - "Arithmetic": Arithmetic.runOp, ->>>>>>> 2b47631f4d9c1174ca841005f4cc04c12df7225c /* From 435ed587a53757ada3a7f00b48ccd8257b95c2f1 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Sat, 16 Dec 2017 09:10:52 -0500 Subject: [PATCH 045/124] Fixed HOTP, TOTP and added test for HOTP --- src/core/operations/OTP.js | 5 +++-- test/index.js | 1 + test/tests/operations/OTP.js | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/tests/operations/OTP.js diff --git a/src/core/operations/OTP.js b/src/core/operations/OTP.js index ff67d1c8..20205053 100755 --- a/src/core/operations/OTP.js +++ b/src/core/operations/OTP.js @@ -1,5 +1,6 @@ import otp from "otp"; import Base64 from "./Base64.js"; +import Utils from "../Utils.js"; /** * One-Time Password operations. @@ -24,7 +25,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(input, []), + secret: Base64.runTo32(Utils.strToByteArray(input), []), epoch: args[3], timeSlice: args[4] }); @@ -44,7 +45,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(input, []), + secret: Base64.runTo32(Utils.strToByteArray(input), []), }); const counter = args[3]; return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`; diff --git a/test/index.js b/test/index.js index 748e1103..7f029b8d 100644 --- a/test/index.js +++ b/test/index.js @@ -26,6 +26,7 @@ import "./tests/operations/Image.js"; import "./tests/operations/MorseCode.js"; import "./tests/operations/MS.js"; import "./tests/operations/PHP.js"; +import "./tests/operations/OTP.js"; import "./tests/operations/StrUtils.js"; import "./tests/operations/SeqUtils.js"; diff --git a/test/tests/operations/OTP.js b/test/tests/operations/OTP.js new file mode 100644 index 00000000..b321e7cf --- /dev/null +++ b/test/tests/operations/OTP.js @@ -0,0 +1,23 @@ +/** + * OTP HOTP tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Generate HOTP", + input: "12345678901234567890", + expectedOutput: "URI: otpauth://hotp/OTPAuthentication?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ\n\nPassword: 755224", + recipeConfig: [ + { + op: "Generate HOTP", + args: ["", 32, 6, 0], + }, + ], + }, +]); From 946d165aa0ffaaeaaf23afc08e143bc500fe5f55 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 15 Dec 2017 00:53:09 -0500 Subject: [PATCH 046/124] fixed decode --- src/core/operations/NetBIOS.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index 0927775a..f97672c9 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -47,8 +47,8 @@ const NetBIOS = { offset = args[0]; for (let i = 0; i < input.length; i += 2) { - output.push(((input[i] - offset) << 4) | - ((input[i + 1] - offset) & 0xf)); + output.push((((input[i] & 0xff) - offset) << 4) | + (((input[i + 1] & 0xff) - offset) & 0xf)); } return output; From 75a5fc0ddc05e451587e5ccfc91fe5c98fd53ec2 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 15 Dec 2017 19:46:21 -0500 Subject: [PATCH 047/124] Added Test, function checks, and cleaned some output. --- src/core/operations/NetBIOS.js | 23 +++++++++++++++------ test/index.js | 1 + test/tests/operations/NetBIOS.js | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 test/tests/operations/NetBIOS.js diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index f97672c9..1ca1f897 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -1,3 +1,5 @@ +import Utils from "../Utils.js"; + /** * NetBIOS operations. * @@ -26,9 +28,15 @@ const NetBIOS = { let output = [], offset = args[0]; - for (let i = 0; i < input.length; i++) { - output.push((input[i] >> 4) + offset); - output.push((input[i] & 0xf) + offset); + if (input.length <= 16) { + for (let i = 0; i < input.length; i++) { + output.push((input[i] >> 4) + offset); + output.push((input[i] & 0xf) + offset); + } + for (let i = input.length; i < 16; i++) { + output.push(67); + output.push(65); + } } return output; @@ -46,9 +54,12 @@ const NetBIOS = { let output = [], offset = args[0]; - for (let i = 0; i < input.length; i += 2) { - output.push((((input[i] & 0xff) - offset) << 4) | - (((input[i + 1] & 0xff) - offset) & 0xf)); + 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)); + } + output = Utils.strToByteArray(Utils.byteArrayToChars(output).trim()); } return output; diff --git a/test/index.js b/test/index.js index 748e1103..9c7e3ca8 100644 --- a/test/index.js +++ b/test/index.js @@ -26,6 +26,7 @@ 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/StrUtils.js"; import "./tests/operations/SeqUtils.js"; diff --git a/test/tests/operations/NetBIOS.js b/test/tests/operations/NetBIOS.js new file mode 100644 index 00000000..2994b79e --- /dev/null +++ b/test/tests/operations/NetBIOS.js @@ -0,0 +1,34 @@ +/** + * NetBIOS tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Encode NetBIOS name", + input: "The NetBIOS name", + expectedOutput: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF", + recipeConfig: [ + { + op: "Encode NetBIOS Name", + args: [65], + }, + ], + }, + { + name: "Decode NetBIOS Name", + input: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF", + expectedOutput: "The NetBIOS name", + recipeConfig: [ + { + op: "Decode NetBIOS Name", + args: [65], + }, + ], + }, +]); From 06c83cb44cf666e43c6cd302bf12a2dfa3acba33 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Fri, 15 Dec 2017 19:53:09 -0500 Subject: [PATCH 048/124] forgot a equal sign --- src/core/operations/NetBIOS.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index 1ca1f897..e3bbf964 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -54,7 +54,7 @@ const NetBIOS = { let output = [], offset = args[0]; - if (input.length <= 32 && (input.length % 2) == 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)); From 4b29a61065ee4d74296a43a9a7a66e011d45282b Mon Sep 17 00:00:00 2001 From: Matt C Date: Mon, 18 Dec 2017 09:53:23 +0000 Subject: [PATCH 049/124] Fixes UUID incompatibility with webworkers --- src/core/operations/UUID.js | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/core/operations/UUID.js b/src/core/operations/UUID.js index 761f245a..b6335e24 100755 --- a/src/core/operations/UUID.js +++ b/src/core/operations/UUID.js @@ -1,3 +1,4 @@ +import crypto from "crypto"; /** * UUID operations. * @@ -17,25 +18,17 @@ const UUID = { * @returns {string} */ runGenerateV4: function(input, args) { - if (window && typeof(window.crypto) !== "undefined" && typeof(window.crypto.getRandomValues) !== "undefined") { - let buf = new Uint32Array(4), - i = 0; - window.crypto.getRandomValues(buf); - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, - v = c === "x" ? r : (r & 0x3 | 0x8); - i++; - return v.toString(16); - }); - } else { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - let r = Math.random() * 16 | 0, - v = c === "x" ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - } - }, - + 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) { + let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, + v = c === "x" ? r : (r & 0x3 | 0x8); + i++; + return v.toString(16); + }); + } }; export default UUID; From 08a31523b26f0a5020ef4d1a1ded66b45d980088 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Mon, 18 Dec 2017 05:04:11 -0800 Subject: [PATCH 050/124] changed the function comment --- src/core/config/Categories.js | 1 + src/core/config/OperationConfig.js | 7 +++++++ src/core/config/modules/Default.js | 1 + src/core/operations/Entropy.js | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 3bc672b7..7a66582e 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -302,6 +302,7 @@ const Categories = [ ops: [ "Entropy", "Frequency distribution", + "Chi Square", "Detect File Type", "Scan for Embedded Files", "Disassemble x86", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 43072558..b914e10d 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3186,6 +3186,13 @@ const OperationConfig = { } ] }, + "Chi Square": { + module: "Default", + description: "Calculates the Chi Square distribution of values.", + inputType: "byteArray", + outputType: "", + args: [] + } "Numberwang": { module: "Default", description: "Based on the popular gameshow by Mitchell and Webb.", diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index dec015a5..f2deb543 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -142,6 +142,7 @@ OpModules.Default = { "Microsoft Script Decoder": MS.runDecodeScript, "Entropy": Entropy.runEntropy, "Frequency distribution": Entropy.runFreqDistrib, + "Chi Square": Entropy.calcChiSq, "Detect File Type": FileType.runDetect, "Scan for Embedded Files": FileType.runScanForEmbeddedFiles, "Generate UUID": UUID.runGenerateV4, diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index 3451914d..7ca87bb3 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -163,6 +163,28 @@ const Entropy = { return -entropy; }, + + /** + * Calculates the Chi Square distribution of values. + * + * @private + * @param {byteArray} data + * @param {Object[]} args + * @returns {number} + */ + calcChiSq: function(input, args) { + let distArray = new Array(256).fill(0), + total = 0; + for (let i = 0; i < input.length; i++) { + distArray[data[i]]++; + } + for (let i = 0; i < distArray.length; i++) { + if (distArray[i] > 0) { + total += Math.pow(distArray[i] - input.length / 256, 2) / (input.length / 256); + } + } + return total; + } }; export default Entropy; From 4ca2a30249ed700e2f9953995cacc18ebbfa8884 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Mon, 18 Dec 2017 05:33:52 -0800 Subject: [PATCH 051/124] Fixed minor errors --- src/core/config/OperationConfig.js | 4 ++-- src/core/operations/Entropy.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index b914e10d..98fff442 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3190,9 +3190,9 @@ const OperationConfig = { module: "Default", description: "Calculates the Chi Square distribution of values.", inputType: "byteArray", - outputType: "", + outputType: "number", args: [] - } + }, "Numberwang": { module: "Default", description: "Based on the popular gameshow by Mitchell and Webb.", diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index 7ca87bb3..6952010f 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -176,7 +176,7 @@ const Entropy = { let distArray = new Array(256).fill(0), total = 0; for (let i = 0; i < input.length; i++) { - distArray[data[i]]++; + distArray[input[i]]++; } for (let i = 0; i < distArray.length; i++) { if (distArray[i] > 0) { @@ -184,7 +184,7 @@ const Entropy = { } } return total; - } + }, }; export default Entropy; From 4e00ac930028390d19297225c689cfbac617fd5a Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 18 Dec 2017 20:39:55 +0000 Subject: [PATCH 052/124] Files are now uploaded in a worker and not displayed in the input by default. Added ArrayBuffer Dish type. --- src/core/Chef.js | 7 +- src/core/Dish.js | 46 ++++++--- src/web/InputWaiter.js | 122 +++++++++++++++-------- src/web/LoaderWorker.js | 50 ++++++++++ src/web/Manager.js | 7 +- src/web/html/index.html | 14 +++ src/web/stylesheets/components/_pane.css | 41 ++++++++ src/web/stylesheets/layout/_io.css | 12 ++- 8 files changed, 232 insertions(+), 67 deletions(-) create mode 100644 src/web/LoaderWorker.js diff --git a/src/core/Chef.js b/src/core/Chef.js index 4e7c042a..d176a36d 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -19,7 +19,7 @@ const Chef = function() { /** * Runs the recipe over the input. * - * @param {string} inputText - The input data as a string + * @param {string|ArrayBuffer} input - The input data as a string or ArrayBuffer * @param {Object[]} recipeConfig - The recipe configuration object * @param {Object} options - The options object storing various user choices * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting @@ -33,7 +33,7 @@ const Chef = function() { * @returns {number} response.duration - The number of ms it took to execute the recipe * @returns {number} response.error - The error object thrown by a failed operation (false if no error) */ -Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) { +Chef.prototype.bake = async function(input, recipeConfig, options, progress, step) { let startTime = new Date().getTime(), recipe = new Recipe(recipeConfig), containsFc = recipe.containsFlowControl(), @@ -62,7 +62,8 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, // If starting from scratch, load data if (progress === 0) { - this.dish.set(inputText, Dish.STRING); + const type = input instanceof ArrayBuffer ? Dish.ARRAY_BUFFER : Dish.STRING; + this.dish.set(input, type); } try { diff --git a/src/core/Dish.js b/src/core/Dish.js index 914188c1..3cd1c6f3 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -8,11 +8,11 @@ import Utils from "./Utils.js"; * @license Apache-2.0 * * @class - * @param {byteArray|string|number} value - The value of the input data. + * @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {number} type - The data type of value, see Dish enums. */ const Dish = function(value, type) { - this.value = value || typeof value == "string" ? value : null; + this.value = value || typeof value === "string" ? value : null; this.type = type || Dish.BYTE_ARRAY; }; @@ -41,6 +41,12 @@ Dish.NUMBER = 2; * @enum */ Dish.HTML = 3; +/** + * Dish data type enum for ArrayBuffers. + * @readonly + * @enum + */ +Dish.ARRAY_BUFFER = 4; /** @@ -64,6 +70,9 @@ Dish.typeEnum = function(typeStr) { case "html": case "HTML": return Dish.HTML; + case "arrayBuffer": + case "ArrayBuffer": + return Dish.ARRAY_BUFFER; default: throw "Invalid data type string. No matching enum."; } @@ -87,6 +96,8 @@ Dish.enumLookup = function(typeEnum) { return "number"; case Dish.HTML: return "html"; + case Dish.ARRAY_BUFFER: + return "ArrayBuffer"; default: throw "Invalid data type enum. No matching type."; } @@ -96,7 +107,7 @@ Dish.enumLookup = function(typeEnum) { /** * Sets the data value and type and then validates them. * - * @param {byteArray|string|number} value - The value of the input data. + * @param {byteArray|string|number|ArrayBuffer} value - The value of the input data. * @param {number} type - The data type of value, see Dish enums. */ Dish.prototype.set = function(value, type) { @@ -114,7 +125,7 @@ Dish.prototype.set = function(value, type) { * Returns the value of the data in the type format specified. * * @param {number} type - The data type of value, see Dish enums. - * @returns {byteArray|string|number} The value of the output data. + * @returns {byteArray|string|number|ArrayBuffer} The value of the output data. */ Dish.prototype.get = function(type) { if (this.type !== type) { @@ -134,20 +145,23 @@ Dish.prototype.translate = function(toType) { switch (this.type) { case Dish.STRING: this.value = this.value ? Utils.strToByteArray(this.value) : []; - this.type = Dish.BYTE_ARRAY; break; case Dish.NUMBER: this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : []; - this.type = Dish.BYTE_ARRAY; break; case Dish.HTML: this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : []; - this.type = Dish.BYTE_ARRAY; + break; + case Dish.ARRAY_BUFFER: + // Array.from() would be nicer here, but it's slightly slower + this.value = Array.prototype.slice.call(new Uint8Array(this.value)); break; default: break; } + this.type = Dish.BYTE_ARRAY; + // Convert from byteArray to toType switch (toType) { case Dish.STRING: @@ -159,6 +173,10 @@ Dish.prototype.translate = function(toType) { this.value = this.value ? parseFloat(Utils.byteArrayToUtf8(this.value)) : 0; this.type = Dish.NUMBER; break; + case Dish.ARRAY_BUFFER: + this.value = new Uint8Array(this.value).buffer; + this.type = Dish.ARRAY_BUFFER; + break; default: break; } @@ -180,7 +198,7 @@ Dish.prototype.valid = function() { // Check that every value is a number between 0 - 255 for (let i = 0; i < this.value.length; i++) { - if (typeof this.value[i] != "number" || + if (typeof this.value[i] !== "number" || this.value[i] < 0 || this.value[i] > 255) { return false; @@ -189,15 +207,11 @@ Dish.prototype.valid = function() { return true; case Dish.STRING: case Dish.HTML: - if (typeof this.value == "string") { - return true; - } - return false; + return typeof this.value === "string"; case Dish.NUMBER: - if (typeof this.value == "number") { - return true; - } - return false; + return typeof this.value === "number"; + case Dish.ARRAY_BUFFER: + return this.value instanceof ArrayBuffer; default: return false; } diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index aba57334..b5748e3f 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -1,4 +1,5 @@ import Utils from "../core/Utils.js"; +import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker.js"; /** @@ -33,6 +34,9 @@ const InputWaiter = function(app, manager) { 144, //Num 145, //Scroll ]; + + this.loaderWorker = null; + this.fileBuffer = null; }; @@ -42,23 +46,49 @@ const InputWaiter = function(app, manager) { * @returns {string} */ InputWaiter.prototype.get = function() { - return document.getElementById("input-text").value; + return this.fileBuffer || document.getElementById("input-text").value; }; /** - * Sets the input in the input textarea. + * Sets the input in the input area. * - * @param {string} input + * @param {string|File} input * * @fires Manager#statechange */ InputWaiter.prototype.set = function(input) { + if (input instanceof File) { + this.setFile(input); + input = ""; + } + document.getElementById("input-text").value = input; window.dispatchEvent(this.manager.statechange); }; +/** + * 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"), + fileUploaded = document.getElementById("input-file-uploaded"); + + fileOverlay.style.display = "block"; + fileName.textContent = file.name; + fileSize.textContent = file.size.toLocaleString() + " bytes"; + fileType.textContent = file.type; + fileUploaded.textContent = "0%"; +}; + + /** * Displays information about the input. * @@ -118,7 +148,7 @@ InputWaiter.prototype.inputDragover = function(e) { e.stopPropagation(); e.preventDefault(); - e.target.classList.add("dropping-file"); + e.target.closest("#input-text,#input-file").classList.add("dropping-file"); }; @@ -131,7 +161,8 @@ InputWaiter.prototype.inputDragover = function(e) { InputWaiter.prototype.inputDragleave = function(e) { e.stopPropagation(); e.preventDefault(); - e.target.classList.remove("dropping-file"); + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); }; @@ -149,55 +180,57 @@ InputWaiter.prototype.inputDrop = function(e) { e.stopPropagation(); e.preventDefault(); - const el = e.target; const file = e.dataTransfer.files[0]; const text = e.dataTransfer.getData("Text"); - const reader = new FileReader(); - let inputCharcode = ""; - let offset = 0; - const CHUNK_SIZE = 20480; // 20KB - const setInput = function() { - const recipeConfig = this.app.getRecipeConfig(); - if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") { - recipeConfig.unshift({op: "From Hex", args: ["Space"]}); - this.app.setRecipeConfig(recipeConfig); - } + document.getElementById("input-text").classList.remove("dropping-file"); + document.getElementById("input-file").classList.remove("dropping-file"); - this.set(inputCharcode); - - el.classList.remove("loadingFile"); - }.bind(this); - - const seek = function() { - if (offset >= file.size) { - setInput(); - return; - } - el.value = "Processing... " + Math.round(offset / file.size * 100) + "%"; - const slice = file.slice(offset, offset + CHUNK_SIZE); - reader.readAsArrayBuffer(slice); - }; - - reader.onload = function(e) { - const data = new Uint8Array(reader.result); - inputCharcode += Utils.toHexFast(data); - offset += CHUNK_SIZE; - seek(); - }; - - - el.classList.remove("dropping-file"); + if (text) { + this.closeFile(); + this.set(text); + return; + } if (file) { - el.classList.add("loadingFile"); - seek(); - } else if (text) { - this.set(text); + 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 fileUploaded = document.getElementById("input-file-uploaded"); + fileUploaded.textContent = r.progress + "%"; + } + + if (r.hasOwnProperty("fileBuffer")) { + this.fileBuffer = r.fileBuffer; + window.dispatchEvent(this.manager.statechange); + } +}; + + +/** + * 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"; +}; + + /** * Handler for clear IO events. * Resets the input, output and info areas. @@ -205,6 +238,7 @@ InputWaiter.prototype.inputDrop = function(e) { * @fires Manager#statechange */ InputWaiter.prototype.clearIoClick = function() { + this.closeFile(); this.manager.highlighter.removeHighlights(); document.getElementById("input-text").value = ""; document.getElementById("output-text").value = ""; diff --git a/src/web/LoaderWorker.js b/src/web/LoaderWorker.js new file mode 100644 index 00000000..b841c096 --- /dev/null +++ b/src/web/LoaderWorker.js @@ -0,0 +1,50 @@ +/** + * Web Worker to load large amounts of data without locking up the UI. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ + + +/** + * Respond to message from parent thread. + */ +self.addEventListener("message", function(e) { + const r = e.data; + if (r.hasOwnProperty("file")) { + self.loadFile(r.file); + } +}); + + +/** + * Loads a file object into an ArrayBuffer, then transfers it back to the parent thread. + * + * @param {File} file + */ +self.loadFile = function(file) { + const reader = new FileReader(); + let data = new Uint8Array(file.size); + let offset = 0; + const CHUNK_SIZE = 10485760; // 10MiB + + const seek = function() { + if (offset >= file.size) { + self.postMessage({"progress": 100}); + self.postMessage({"fileBuffer": data.buffer}, [data.buffer]); + return; + } + self.postMessage({"progress": Math.round(offset / file.size * 100)}); + const slice = file.slice(offset, offset + CHUNK_SIZE); + reader.readAsArrayBuffer(slice); + }; + + reader.onload = function(e) { + data.set(new Uint8Array(reader.result), offset); + offset += CHUNK_SIZE; + seek(); + }; + + seek(); +}; diff --git a/src/web/Manager.js b/src/web/Manager.js index 2b44e6d2..b3ef0158 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -135,13 +135,14 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#input-text", "keyup paste", this.input.inputChange, 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)); - document.getElementById("input-text").addEventListener("dragover", this.input.inputDragover.bind(this.input)); - document.getElementById("input-text").addEventListener("dragleave", this.input.inputDragleave.bind(this.input)); - document.getElementById("input-text").addEventListener("drop", this.input.inputDrop.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.closeFile.bind(this.input)); // Output document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output)); diff --git a/src/web/html/index.html b/src/web/html/index.html index 66dfcc80..3bfefa8b 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -181,6 +181,20 @@
    +
    +
    +
    + +
    + + Name:
    + Size:
    + Type:
    + Uploaded: +
    +
    +
    +
    diff --git a/src/web/stylesheets/components/_pane.css b/src/web/stylesheets/components/_pane.css index 7246a24a..f69984b4 100644 --- a/src/web/stylesheets/components/_pane.css +++ b/src/web/stylesheets/components/_pane.css @@ -28,3 +28,44 @@ margin: 0; padding: 0; } + +.card { + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.3s; + width: 400px; + height: 150px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-family: var(--primary-font-family); + color: var(--primary-font-colour); + line-height: 30px; + background-color: var(--primary-background-colour); +} + +.card:hover { + box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); +} + +.card>img { + float: left; + width: 150px; + height: 150px; +} + +.card-body .close { + position: absolute; + right: 10px; + top: 10px; +} + +.card-body { + float: left; + padding: 16px; + width: 250px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + user-select: text; +} \ No newline at end of file diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 997af92e..855d4262 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -39,7 +39,7 @@ } .textarea-wrapper textarea, -.textarea-wrapper div { +.textarea-wrapper>div { font-family: var(--fixed-width-font-family); font-size: var(--fixed-width-font-size); color: var(--fixed-width-font-colour); @@ -77,6 +77,16 @@ transition: all 0.5s ease; } +#input-file { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: var(--title-background-colour); + display: none; +} + .io-btn-group { float: right; margin-top: -4px; From 12fc8c22dd44960337bb08086d5ea0ecde40b569 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 13:18:25 +0000 Subject: [PATCH 053/124] Made some naming changes to Label-related operations. --- README.md | 2 +- src/core/FlowControl.js | 43 ++++++++++++++---------------- src/core/config/OperationConfig.js | 18 ++++++------- src/web/html/index.html | 2 +- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index aa04fb8c..9dffba47 100755 --- a/README.md +++ b/README.md @@ -100,6 +100,6 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw [6]: https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ [7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA - [8]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA + [8]: https://gchq.github.ioeCyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',false,'base64',10)To_Hex('Space')Return()Label('base64')To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA [9]: https://gchq.github.io/CyberChef/#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ [10]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4 diff --git a/src/core/FlowControl.js b/src/core/FlowControl.js index ea798d7e..bba5eaf1 100755 --- a/src/core/FlowControl.js +++ b/src/core/FlowControl.js @@ -216,29 +216,6 @@ const FlowControl = { return state; }, - /** - * Returns the index of a label. - * - * @param {Object} state - * @param {string} name - * @returns {number} - */ - - _getLabelIndex: function(name, state) { - let index = -1; - for (let o = 0; o < state.opList.length; o++) { - let operation = state.opList[o]; - if (operation.getConfig().op === "Label"){ - let ings = operation.getIngValues(); - if (name === ings[0]) { - index = o; - break; - } - } - } - return index; - }, - /** * Return operation. @@ -268,6 +245,26 @@ const FlowControl = { return state; }, + + /** + * Returns the index of a label. + * + * @param {Object} state + * @param {string} name + * @returns {number} + */ + _getLabelIndex: function(name, state) { + for (let o = 0; o < state.opList.length; o++) { + let operation = state.opList[o]; + if (operation.name === "Label"){ + let ings = operation.getIngValues(); + if (name === ings[0]) { + return o; + } + } + } + return -1; + }, }; export default FlowControl; diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 5ae2992b..56b6cca1 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -137,13 +137,13 @@ const OperationConfig = { }, "Jump": { module: "Default", - description: "Jump forwards or backwards over the specified number of operations.", + description: "Jump forwards or backwards to the specified Label", inputType: "string", outputType: "string", flowControl: true, args: [ { - name: "The Label to Jump to", + name: "Label name", type: "string", value: "" }, @@ -156,7 +156,7 @@ const OperationConfig = { }, "Conditional Jump": { module: "Default", - description: "Conditionally jump forwards or backwards over the specified number of operations based on whether the data matches the specified regular expression.", + 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, @@ -167,13 +167,13 @@ const OperationConfig = { value: "" }, { - name: "Negative match (logical NOT)", + name: "Invert match", type: "boolean", value: false }, { - name: "The Label to Jump to", - type: "string", + name: "Label name", + type: "shortString", value: "" }, { @@ -185,14 +185,14 @@ const OperationConfig = { }, "Label": { module: "Default", - description: "Provides a location for for conditional and fixed jumps to jump.", + description: "Provides a location for conditional and fixed jumps to redirect execution to.", inputType: "string", outputType: "string", flowControl: true, args: [ { - name: "Jump Label", - type: "string", + name: "Name", + type: "shortString", value: "" } ] diff --git a/src/web/html/index.html b/src/web/html/index.html index 66dfcc80..b6289772 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -428,7 +428,7 @@
  • Convert data from a hexdump, then decompress
  • Decrypt and disassemble shellcode
  • Display multiple timestamps as full dates
  • -
  • Carry out different operations on data of different types
  • +
  • Carry out different operations on data of different types
  • Use parts of the input as arguments to operations
  • From 31d90939fe935c455d494b27851a383e485a1a5b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 13:19:46 +0000 Subject: [PATCH 054/124] 6.6.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f0fddf5..87d4f385 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.5.0", + "version": "6.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f62b95e2..f46b85ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.5.0", + "version": "6.6.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From e61ced93d6e29256268690fbd9c05b644aad3ce7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 13:53:33 +0000 Subject: [PATCH 055/124] Removed dependency for Utils.js from NetBIOS.js --- src/core/operations/NetBIOS.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index e3bbf964..f6aa501f 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -1,5 +1,3 @@ -import Utils from "../Utils.js"; - /** * NetBIOS operations. * @@ -29,14 +27,13 @@ const NetBIOS = { offset = args[0]; if (input.length <= 16) { + let 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); } - for (let i = input.length; i < 16; i++) { - output.push(67); - output.push(65); - } } return output; @@ -59,7 +56,7 @@ const NetBIOS = { output.push((((input[i] & 0xff) - offset) << 4) | (((input[i + 1] & 0xff) - offset) & 0xf)); } - output = Utils.strToByteArray(Utils.byteArrayToChars(output).trim()); + output = output.filter(x => x !== 32); } return output; From 5ec210990b41a71703b54f5f5e39d4693db3612d Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:12:18 +0000 Subject: [PATCH 056/124] Fixed NetBIOS space removal --- src/core/operations/NetBIOS.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/operations/NetBIOS.js b/src/core/operations/NetBIOS.js index f6aa501f..60866b65 100644 --- a/src/core/operations/NetBIOS.js +++ b/src/core/operations/NetBIOS.js @@ -56,7 +56,10 @@ const NetBIOS = { output.push((((input[i] & 0xff) - offset) << 4) | (((input[i + 1] & 0xff) - offset) & 0xf)); } - output = output.filter(x => x !== 32); + for (let i = output.length - 1; i > 0; i--) { + if (output[i] === 32) output.splice(i, i); + else break; + } } return output; From 7b433b9bd6a296db077277ca1aaeddecf4b83426 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:12:24 +0000 Subject: [PATCH 057/124] 6.6.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87d4f385..e03a2d91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.0", + "version": "6.6.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f46b85ec..31c9b26c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.0", + "version": "6.6.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 049fc66785418a2b1b771112152ecf56bd9cc2c6 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:24:47 +0000 Subject: [PATCH 058/124] Added note to Default.js to show that crypto is included in that module. --- src/core/config/modules/Default.js | 1 + src/core/operations/UUID.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 19d6c803..8e0c8872 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -39,6 +39,7 @@ import UUID from "../../operations/UUID.js"; * - Utils.js * - CryptoJS * - otp + * - crypto * * @author n1474335 [n1474335@gmail.com] * @copyright Crown Copyright 2017 diff --git a/src/core/operations/UUID.js b/src/core/operations/UUID.js index b6335e24..7b485579 100755 --- a/src/core/operations/UUID.js +++ b/src/core/operations/UUID.js @@ -1,4 +1,6 @@ import crypto from "crypto"; + + /** * UUID operations. * From 22aaeb3ff54bd33a0853ea94ddceb96f1947440e Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:25:12 +0000 Subject: [PATCH 059/124] 6.6.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e03a2d91..a505e3ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.1", + "version": "6.6.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 31c9b26c..176a5901 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.1", + "version": "6.6.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From f7e958e7a1cf0511c9736d7152400708fa92ddf4 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:38:13 +0000 Subject: [PATCH 060/124] Changed HOTP inputType to byteArray --- src/core/config/OperationConfig.js | 2 +- src/core/operations/OTP.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 56b6cca1..38dad80b 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3840,7 +3840,7 @@ const OperationConfig = { "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: "string", + inputType: "byteArray", outputType: "string", args: [ { diff --git a/src/core/operations/OTP.js b/src/core/operations/OTP.js index 20205053..f7862310 100755 --- a/src/core/operations/OTP.js +++ b/src/core/operations/OTP.js @@ -1,6 +1,6 @@ import otp from "otp"; import Base64 from "./Base64.js"; -import Utils from "../Utils.js"; + /** * One-Time Password operations. @@ -25,7 +25,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(Utils.strToByteArray(input), []), + secret: Base64.runTo32(input, []), epoch: args[3], timeSlice: args[4] }); @@ -45,7 +45,7 @@ const OTP = { name: args[0], keySize: args[1], codeLength: args[2], - secret: Base64.runTo32(Utils.strToByteArray(input), []), + secret: Base64.runTo32(input, []), }); const counter = args[3]; return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`; From 80719ae36837192111de42fadc66e845ca19fcd6 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 14:41:34 +0000 Subject: [PATCH 061/124] 6.6.3 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a505e3ef..7fa75786 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.2", + "version": "6.6.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 176a5901..02d5a767 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.2", + "version": "6.6.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 7a951d86d8a085ac14b6c0d5acf07adbf19b9fc2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 15:02:01 +0000 Subject: [PATCH 062/124] Tidied up Chi Square operation --- src/core/config/modules/Default.js | 2 +- src/core/operations/Entropy.js | 47 ++++++++++++++++-------------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index cbed60c9..a0e8bd23 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -143,7 +143,7 @@ OpModules.Default = { "Microsoft Script Decoder": MS.runDecodeScript, "Entropy": Entropy.runEntropy, "Frequency distribution": Entropy.runFreqDistrib, - "Chi Square": Entropy.calcChiSq, + "Chi Square": Entropy.runChiSq, "Detect File Type": FileType.runDetect, "Scan for Embedded Files": FileType.runScanForEmbeddedFiles, "Generate UUID": UUID.runGenerateV4, diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index 6952010f..aa9ed0bc 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -135,6 +135,31 @@ const Entropy = { }, + /** + * Chi Square operation. + * + * @param {byteArray} data + * @param {Object[]} args + * @returns {number} + */ + runChiSq: function(input, args) { + let distArray = new Array(256).fill(0), + total = 0; + + for (let i = 0; i < input.length; i++) { + distArray[input[i]]++; + } + + for (let i = 0; i < distArray.length; i++) { + if (distArray[i] > 0) { + total += Math.pow(distArray[i] - input.length / 256, 2) / (input.length / 256); + } + } + + return total; + }, + + /** * Calculates the Shannon entropy for a given chunk of data. * @@ -163,28 +188,6 @@ const Entropy = { return -entropy; }, - - /** - * Calculates the Chi Square distribution of values. - * - * @private - * @param {byteArray} data - * @param {Object[]} args - * @returns {number} - */ - calcChiSq: function(input, args) { - let distArray = new Array(256).fill(0), - total = 0; - for (let i = 0; i < input.length; i++) { - distArray[input[i]]++; - } - for (let i = 0; i < distArray.length; i++) { - if (distArray[i] > 0) { - total += Math.pow(distArray[i] - input.length / 256, 2) / (input.length / 256); - } - } - return total; - }, }; export default Entropy; From f9eaf67db241f8cc3fb85fcfc18f8071686c9c06 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 15:02:23 +0000 Subject: [PATCH 063/124] 6.7.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7fa75786..48c73b96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.3", + "version": "6.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 02d5a767..8423230b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.6.3", + "version": "6.7.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From ecd0ac25218afe4968f25cc8f3e2adbcf7a27e57 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 19 Dec 2017 16:53:57 +0000 Subject: [PATCH 064/124] Updated dependencies --- README.md | 2 +- package-lock.json | 217 ++++++++++++++++++++++++---------------------- package.json | 16 ++-- 3 files changed, 123 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index 9dffba47..e0fe3c2c 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef) [![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef) -[![npm](http://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef) +[![npm](https://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef) ![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue) [![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE) [![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff --git a/package-lock.json b/package-lock.json index 48c73b96..00bc0c97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -242,7 +242,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.9.0" + "es-abstract": "1.10.0" } }, "array-union": { @@ -286,9 +286,9 @@ "dev": true }, "asn1.js": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", - "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -1054,9 +1054,9 @@ "dev": true }, "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, "bluebird": { @@ -1099,7 +1099,7 @@ "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", - "multicast-dns": "6.2.0", + "multicast-dns": "6.2.1", "multicast-dns-service-types": "1.1.0" } }, @@ -1225,12 +1225,12 @@ } }, "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": { @@ -1798,9 +1798,9 @@ "integrity": "sha1-TCc3K8s85mnSKNV7NZG8YRjFKdU=" }, "crypto-browserify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", - "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { "browserify-cipher": "1.0.0", @@ -1812,7 +1812,8 @@ "inherits": "2.0.3", "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", - "randombytes": "2.0.5" + "randombytes": "2.0.5", + "randomfill": "1.0.3" } }, "crypto-js": { @@ -1976,7 +1977,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "dashdash": { @@ -2376,9 +2377,9 @@ } }, "es-abstract": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", - "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2400,9 +2401,9 @@ } }, "es5-ext": { - "version": "0.10.35", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", - "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", "dev": true, "requires": { "es6-iterator": "2.0.3", @@ -2416,7 +2417,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-symbol": "3.1.1" } }, @@ -2427,7 +2428,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", @@ -2447,7 +2448,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -2460,7 +2461,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "es6-weak-map": { @@ -2470,7 +2471,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } @@ -2832,7 +2833,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "eventemitter2": { @@ -3109,9 +3110,9 @@ } }, "file-loader": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.5.tgz", - "integrity": "sha512-RzGHDatcVNpGISTvCpfUfOGpYuSR7HSsSg87ki+wF6rw1Hm0RALPTiAdsxAq1UwLf0RRhbe22/eHK6nhXspiOQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.6.tgz", + "integrity": "sha512-873ztuL+/hfvXbLDJ262PGO6XjERnybJu2gW1/5j8HUfxSiFJI9Hj/DhZ50ZGRUxBvuNiazb/cM2rh9pqrxP6Q==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -4056,9 +4057,9 @@ } }, "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, "iconv-lite": { @@ -4224,7 +4225,7 @@ "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", "dev": true, "requires": { - "moment": "2.19.2", + "moment": "2.20.1", "sanitize-html": "1.15.0" } }, @@ -4312,9 +4313,9 @@ } }, "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "invariant": { @@ -4362,7 +4363,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -4659,9 +4660,9 @@ "integrity": "sha1-9yxcdhgXa/91zIEqHO2949jraDk=" }, "js-sha3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz", - "integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", + "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==" }, "js-tokens": { "version": "3.0.2", @@ -5484,16 +5485,16 @@ } }, "moment": { - "version": "2.19.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.2.tgz", - "integrity": "sha512-Rf6jiHPEfxp9+dlzxPTmRHbvoFXsh2L/U8hOupUMpnuecHQmI6cF6lUbJl3QqKPko1u6ujO+FxtcajLVfLpAtA==" + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", + "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" }, "moment-timezone": { "version": "0.5.14", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", "requires": { - "moment": "2.19.2" + "moment": "2.20.1" } }, "ms": { @@ -5503,9 +5504,9 @@ "dev": true }, "multicast-dns": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.0.tgz", - "integrity": "sha512-tnQqWkuWYHCOVRveiWQf+5KjHUnEmtxUycTy1esL4prQjXoT4qpndIS4fH63zObmHNxIHke3YHRnQrXYpXHf2A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz", + "integrity": "sha512-uV3/ckdsffHx9IrGQrx613mturMdMqQ06WTq+C09NsStJ9iNG6RcUWgPKs1Rfjy+idZT6tfQoXEusGNnEZhT3w==", "dev": true, "requires": { "dns-packet": "1.2.2", @@ -5561,21 +5562,21 @@ "dev": true }, "node-libs-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", - "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "dev": true, "requires": { "assert": "1.4.1", - "browserify-zlib": "0.1.4", + "browserify-zlib": "0.2.0", "buffer": "4.9.1", "console-browserify": "1.1.0", "constants-browserify": "1.0.0", - "crypto-browserify": "3.11.1", + "crypto-browserify": "3.12.0", "domain-browser": "1.1.7", "events": "1.1.1", - "https-browserify": "0.0.1", - "os-browserify": "0.2.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", "path-browserify": "0.0.0", "process": "0.11.10", "punycode": "1.4.1", @@ -5583,20 +5584,12 @@ "readable-stream": "2.3.3", "stream-browserify": "2.0.1", "stream-http": "2.7.2", - "string_decoder": "0.10.31", + "string_decoder": "1.0.3", "timers-browserify": "2.0.4", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4" - }, - "dependencies": { - "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 - } } }, "node-md6": { @@ -5815,9 +5808,9 @@ } }, "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, "os-homedir": { @@ -5892,9 +5885,9 @@ } }, "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 }, "param-case": { @@ -5912,7 +5905,7 @@ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "dev": true, "requires": { - "asn1.js": "4.9.1", + "asn1.js": "4.9.2", "browserify-aes": "1.1.1", "create-hash": "1.1.3", "evp_bytestokey": "1.0.3", @@ -6508,13 +6501,13 @@ } }, "postcss-loader": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz", - "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.9.tgz", + "integrity": "sha512-sgoXPtmgVT3aBAhU47Kig8oPF+mbXl8Unjvtz1Qj1q2D2EvSVJW2mKJNzxv5y/LvA9xWwuvdysvhc7Zn80UWWw==", "dev": true, "requires": { "loader-utils": "1.1.0", - "postcss": "6.0.13", + "postcss": "6.0.14", "postcss-load-config": "1.2.0", "schema-utils": "0.3.0" }, @@ -6546,9 +6539,9 @@ "dev": true }, "postcss": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz", - "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==", + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { "chalk": "2.3.0", @@ -7225,6 +7218,16 @@ "safe-buffer": "5.1.1" } }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -8220,9 +8223,9 @@ "dev": true }, "style-loader": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz", - "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", + "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -8840,26 +8843,26 @@ "dev": true }, "webpack": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", - "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", "dev": true, "requires": { - "acorn": "5.1.2", + "acorn": "5.2.1", "acorn-dynamic-import": "2.0.2", "ajv": "5.2.3", "ajv-keywords": "2.1.0", "async": "2.5.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", - "interpret": "1.0.4", + "interpret": "1.1.0", "json-loader": "0.5.7", "json5": "0.5.1", "loader-runner": "2.3.0", "loader-utils": "1.1.0", "memory-fs": "0.4.1", "mkdirp": "0.5.1", - "node-libs-browser": "2.0.0", + "node-libs-browser": "2.1.0", "source-map": "0.5.7", "supports-color": "4.5.0", "tapable": "0.2.8", @@ -8870,9 +8873,9 @@ }, "dependencies": { "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true }, "escope": { @@ -8905,22 +8908,30 @@ } }, "webpack-dev-middleware": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", - "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", + "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", "dev": true, "requires": { "memory-fs": "0.4.1", - "mime": "1.4.1", + "mime": "1.6.0", "path-is-absolute": "1.0.1", "range-parser": "1.2.0", "time-stamp": "2.0.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } } }, "webpack-dev-server": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz", - "integrity": "sha512-thrqC0EQEoSjXeYgP6pUXcUCZ+LNrKsDPn+mItLnn5VyyNZOJKd06hUP5vqkYwL8nWWXsii0loSF9NHNccT6ow==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz", + "integrity": "sha512-Pu7uoQFgQj5RE5wmlfkpYSzihMKxulwEuO2xCsaMnAnyRSApwoVi3B8WCm9XbigyWTHaIMzYGkB90Vr6leAeTQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -8948,7 +8959,7 @@ "spdy": "3.4.7", "strip-ansi": "3.0.1", "supports-color": "4.5.0", - "webpack-dev-middleware": "1.12.0", + "webpack-dev-middleware": "1.12.2", "yargs": "6.6.0" }, "dependencies": { @@ -9281,9 +9292,9 @@ "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" }, "xpath": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz", - "integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs=" + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==" }, "xtend": { "version": "4.0.1", diff --git a/package.json b/package.json index 8423230b..3f97db65 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "css-loader": "^0.28.7", "exports-loader": "^0.6.4", "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "^1.1.5", + "file-loader": "^1.1.6", "grunt": ">=1.0.1", "grunt-accessibility": "~5.0.0", "grunt-chmod": "~1.1.1", @@ -56,13 +56,13 @@ "less-loader": "^4.0.5", "postcss-css-variables": "^0.8.0", "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.8", - "style-loader": "^0.19.0", + "postcss-loader": "^2.0.9", + "style-loader": "^0.19.1", "url-loader": "^0.6.2", "val-loader": "^1.1.0", "web-resource-inliner": "^4.2.0", - "webpack": "^3.8.1", - "webpack-dev-server": "^2.9.4", + "webpack": "^3.10.0", + "webpack-dev-server": "^2.9.7", "webpack-node-externals": "^1.6.0", "worker-loader": "^1.1.0" }, @@ -81,12 +81,12 @@ "google-code-prettify": "^1.0.5", "jquery": "^3.2.1", "js-crc": "^0.2.0", - "js-sha3": "^0.6.1", + "js-sha3": "^0.7.0", "jsbn": "^1.1.0", "jsonpath": "^1.0.0", "jsrsasign": "8.0.4", "lodash": "^4.17.4", - "moment": "^2.19.2", + "moment": "^2.20.1", "moment-timezone": "^0.5.14", "node-md6": "^0.1.0", "otp": "^0.1.3", @@ -95,7 +95,7 @@ "split.js": "^1.3.5", "vkbeautify": "^0.99.3", "xmldom": "^0.1.27", - "xpath": "0.0.24", + "xpath": "0.0.27", "zlibjs": "^0.3.1" }, "scripts": { From 317327d0975963249696c7c923ebeaaa19e86708 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 13:30:51 +0000 Subject: [PATCH 065/124] CSS selector operation now works in a web worker. Fixes #218 --- package-lock.json | 2136 +++++++++++++++++++++++---------- package.json | 1 + src/core/operations/Code.js | 31 +- test/tests/operations/Code.js | 22 + 4 files changed, 1567 insertions(+), 623 deletions(-) diff --git a/package-lock.json b/package-lock.json index 00bc0c97..404a87c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,21 +36,21 @@ } }, "access-sniff": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.0.1.tgz", - "integrity": "sha1-IJ4W63DAlaA79/yCnsrLfHeS9e4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.1.0.tgz", + "integrity": "sha512-m8w34KtU7jD89lJ8jMUFoyy9VInfROR/0sKEkfVfcMqVRSGG3I2Y34XNBmz2ROPZK96x1ue5PET5H6gJ79BN7Q==", "dev": true, "requires": { "HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0", "axios": "0.9.1", - "bluebird": "3.5.0", + "bluebird": "3.5.1", "chalk": "1.1.3", - "commander": "2.11.0", + "commander": "2.12.2", "glob": "7.1.2", "jsdom": "9.12.0", "mkdirp": "0.5.1", - "phantomjs-prebuilt": "2.1.15", - "rc": "1.2.1", + "phantomjs-prebuilt": "2.1.16", + "rc": "1.2.2", "underscore": "1.8.3", "unixify": "0.2.1", "validator": "5.7.0" @@ -120,21 +120,21 @@ } }, "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-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", - "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "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": { @@ -312,9 +312,9 @@ "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.4" @@ -339,10 +339,10 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000741", + "caniuse-db": "1.0.30000784", "normalize-range": "0.1.2", "num2fraction": "1.2.2", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" }, "dependencies": { @@ -352,8 +352,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000741", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000784", + "electron-to-chromium": "1.3.29" } } } @@ -406,13 +406,13 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "convert-source-map": "1.5.0", + "convert-source-map": "1.5.1", "debug": "2.6.9", "json5": "0.5.1", "lodash": "4.17.4", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", - "private": "0.1.7", + "private": "0.1.8", "slash": "1.0.0", "source-map": "0.5.7" } @@ -898,7 +898,7 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.1", + "core-js": "2.5.3", "regenerator-runtime": "0.10.5" } }, @@ -935,7 +935,7 @@ "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.5.1", + "browserslist": "2.10.0", "invariant": "2.2.2", "semver": "5.4.1" } @@ -948,7 +948,7 @@ "requires": { "babel-core": "6.26.0", "babel-runtime": "6.26.0", - "core-js": "2.5.1", + "core-js": "2.5.3", "home-or-tmp": "2.0.0", "lodash": "4.17.4", "mkdirp": "0.5.1", @@ -960,14 +960,14 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" }, "dependencies": { "regenerator-runtime": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", - "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" } } }, @@ -1060,9 +1060,9 @@ "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.js": { @@ -1234,13 +1234,13 @@ } }, "browserslist": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz", - "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz", + "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000751", - "electron-to-chromium": "1.3.24" + "caniuse-lite": "1.0.30000784", + "electron-to-chromium": "1.3.29" } }, "buffer": { @@ -1332,7 +1332,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000741", + "caniuse-db": "1.0.30000784", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" }, @@ -1343,22 +1343,22 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000741", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000784", + "electron-to-chromium": "1.3.29" } } } }, "caniuse-db": { - "version": "1.0.30000741", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000741.tgz", - "integrity": "sha1-C+WREdQiHyH2ErUO5dZ4caLEp6U=", + "version": "1.0.30000784", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000784.tgz", + "integrity": "sha1-G+lQEtlInHcZB0+BruV9vf/mNhs=", "dev": true }, "caniuse-lite": { - "version": "1.0.30000751", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000751.tgz", - "integrity": "sha1-KYrTQYLKQ1l1e0qTr8aBt7kX41g=", + "version": "1.0.30000784", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz", + "integrity": "sha1-EpztdOmhKApEGIC2zSvOMO9Z5sA=", "dev": true }, "caseless": { @@ -1399,6 +1399,12 @@ "supports-color": "2.0.0" } }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -1407,6 +1413,7 @@ "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", + "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -1489,9 +1496,9 @@ } }, "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", "dev": true }, "co": { @@ -1506,7 +1513,7 @@ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", "dev": true, "requires": { - "q": "1.5.0" + "q": "1.5.1" } }, "code-point-at": { @@ -1527,15 +1534,15 @@ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "dev": true, "requires": { - "clone": "1.0.2", - "color-convert": "1.9.0", + "clone": "1.0.3", + "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" @@ -1582,9 +1589,9 @@ } }, "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", "dev": true }, "commondir": { @@ -1668,15 +1675,15 @@ "dev": true }, "content-type-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz", - "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", "dev": true }, "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, "cookie": { @@ -1692,9 +1699,9 @@ "dev": true }, "core-js": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", - "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" }, "core-util-is": { "version": "1.0.2", @@ -1840,7 +1847,7 @@ "loader-utils": "1.1.0", "lodash.camelcase": "4.3.0", "object-assign": "4.1.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-modules-extract-imports": "1.1.0", "postcss-modules-local-by-default": "1.2.0", "postcss-modules-scope": "1.1.0", @@ -1908,7 +1915,7 @@ "defined": "1.0.0", "has": "1.0.1", "object-assign": "4.1.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-calc": "5.3.1", "postcss-colormin": "2.2.2", "postcss-convert-values": "2.6.1", @@ -1996,7 +2003,7 @@ "dev": true, "requires": { "image-size": "0.3.5", - "mimer": "0.2.1", + "mimer": "0.2.3", "semver": "5.4.1" }, "dependencies": { @@ -2094,6 +2101,14 @@ "pify": "2.3.0", "pinkie-promise": "2.0.1", "rimraf": "2.2.8" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } } }, "delayed-stream": { @@ -2181,13 +2196,12 @@ } }, "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "2.0.2" } }, "dom-converter": { @@ -2299,9 +2313,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.29", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.29.tgz", + "integrity": "sha1-elgja5VGjD52YAkTSFItZddzazY=", "dev": true }, "elliptic": { @@ -2359,12 +2373,12 @@ "dev": true }, "errno": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", - "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", "dev": true, "requires": { - "prr": "0.0.0" + "prr": "1.0.1" } }, "error-ex": { @@ -2436,9 +2450,9 @@ } }, "es6-promise": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", - "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", + "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==", "dev": true }, "es6-set": { @@ -2523,33 +2537,33 @@ } }, "eslint": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.8.0.tgz", - "integrity": "sha1-Ip7w41Tg5h2DfHqA/fuoJeGZgV4=", + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", + "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", "dev": true, "requires": { - "ajv": "5.2.3", + "ajv": "5.5.2", "babel-code-frame": "6.26.0", - "chalk": "2.1.0", + "chalk": "2.3.0", "concat-stream": "1.6.0", "cross-spawn": "5.1.0", "debug": "3.1.0", - "doctrine": "2.0.0", + "doctrine": "2.0.2", "eslint-scope": "3.7.1", - "espree": "3.5.1", + "espree": "3.5.2", "esquery": "1.0.0", "estraverse": "4.2.0", "esutils": "2.0.2", "file-entry-cache": "2.0.0", "functional-red-black-tree": "1.0.1", "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", + "globals": "11.1.0", + "ignore": "3.3.7", "imurmurhash": "0.1.4", "inquirer": "3.3.0", - "is-resolvable": "1.0.0", + "is-resolvable": "1.0.1", "js-yaml": "3.10.0", - "json-stable-stringify": "1.0.1", + "json-stable-stringify-without-jsonify": "1.0.1", "levn": "0.3.0", "lodash": "4.17.4", "minimatch": "3.0.4", @@ -2579,18 +2593,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "debug": { @@ -2616,6 +2630,12 @@ "path-is-absolute": "1.0.1" } }, + "globals": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true + }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", @@ -2648,9 +2668,9 @@ } }, "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -2752,19 +2772,19 @@ } }, "espree": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", - "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", "dev": true, "requires": { - "acorn": "5.1.2", + "acorn": "5.2.1", "acorn-jsx": "3.0.1" }, "dependencies": { "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true } } @@ -2980,13 +3000,13 @@ "dev": true }, "external-editor": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", - "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { + "chardet": "0.4.2", "iconv-lite": "0.4.19", - "jschardet": "1.5.1", "tmp": "0.0.33" } }, @@ -3005,33 +3025,24 @@ "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "loader-utils": "1.1.0", "schema-utils": "0.3.0", - "webpack-sources": "1.0.1" + "webpack-sources": "1.1.0" } }, "extract-zip": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", - "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", "dev": true, "requires": { "concat-stream": "1.6.0", - "debug": "2.2.0", + "debug": "2.6.9", "mkdirp": "0.5.0", "yauzl": "2.4.1" }, "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" - } - }, "mkdirp": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", @@ -3040,12 +3051,6 @@ "requires": { "minimist": "0.0.8" } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true } } }, @@ -3061,6 +3066,12 @@ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", "dev": true }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -3177,7 +3188,7 @@ "dev": true, "requires": { "commondir": "1.0.1", - "make-dir": "1.0.0", + "make-dir": "1.1.0", "pkg-dir": "2.0.0" } }, @@ -3309,6 +3320,910 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "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, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "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 + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "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" + } + }, + "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" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "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, + "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": { + "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", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "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" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "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" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "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", + "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" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "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, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "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", + "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" + } + }, + "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, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -3405,6 +4320,14 @@ "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 + } } }, "google-code-prettify": { @@ -3478,7 +4401,7 @@ "integrity": "sha1-/uK+5WHjPOl8lfk/7ogEPfFFokk=", "dev": true, "requires": { - "access-sniff": "3.0.1" + "access-sniff": "3.1.0" } }, "grunt-chmod": { @@ -3553,8 +4476,8 @@ "integrity": "sha512-VZlDOLrB2KKefDDcx/wR8rEEz7smDwDKVblmooa+itdt/2jWw3ee2AiZB5Ap4s4AoRY0pbHRjZ3HHwY8uKR9Rw==", "dev": true, "requires": { - "chalk": "2.1.0", - "eslint": "4.8.0" + "chalk": "2.3.0", + "eslint": "4.13.1" }, "dependencies": { "ansi-styles": { @@ -3563,18 +4486,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -3584,9 +4507,9 @@ "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -3736,7 +4659,7 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "5.2.3", + "ajv": "5.5.2", "har-schema": "2.0.0" } }, @@ -3802,7 +4725,7 @@ "boom": "4.3.1", "cryptiles": "3.1.2", "hoek": "4.2.0", - "sntp": "2.0.2" + "sntp": "2.1.0" } }, "he": { @@ -3869,12 +4792,12 @@ "dev": true }, "html-encoding-sniffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz", - "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { - "whatwg-encoding": "1.0.1" + "whatwg-encoding": "1.0.3" } }, "html-entities": { @@ -3884,19 +4807,19 @@ "dev": true }, "html-minifier": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.5.tgz", - "integrity": "sha512-g+1+NBycQI0fGnggd52JM8TRUweG7+9W2wrtjGitMAqc4G7maweAHvVAAjz9veHseIH3tYKE2lk2USGSoewIrQ==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.7.tgz", + "integrity": "sha512-GISXn6oKDo7+gVpKOgZJTbHMCUI2TSGfpg/8jgencWhWJsvEmsvp3M8emX7QocsXsYznWloLib3OeSfeyb/ewg==", "dev": true, "requires": { "camel-case": "3.0.0", "clean-css": "4.1.9", - "commander": "2.11.0", + "commander": "2.12.2", "he": "1.1.1", "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.1.3" + "uglify-js": "3.2.2" } }, "html-webpack-plugin": { @@ -3905,8 +4828,8 @@ "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", "dev": true, "requires": { - "bluebird": "3.5.0", - "html-minifier": "3.5.5", + "bluebird": "3.5.1", + "html-minifier": "3.5.7", "loader-utils": "0.2.17", "lodash": "4.17.4", "pretty-error": "2.1.1", @@ -4080,7 +5003,7 @@ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", "dev": true, "requires": { - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -4089,18 +5012,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -4110,20 +5033,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -4138,9 +5067,9 @@ "dev": true }, "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "image-size": { @@ -4214,9 +5143,9 @@ "dev": true }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "ink-docstrap": { @@ -4226,7 +5155,7 @@ "dev": true, "requires": { "moment": "2.20.1", - "sanitize-html": "1.15.0" + "sanitize-html": "1.16.3" } }, "inquirer": { @@ -4236,10 +5165,10 @@ "dev": true, "requires": { "ansi-escapes": "3.0.0", - "chalk": "2.1.0", + "chalk": "2.3.0", "cli-cursor": "2.1.0", "cli-width": "2.2.0", - "external-editor": "2.0.5", + "external-editor": "2.1.0", "figures": "2.0.0", "lodash": "4.17.4", "mute-stream": "0.0.7", @@ -4263,18 +5192,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -4293,9 +5222,9 @@ } }, "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -4471,13 +5400,13 @@ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "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" @@ -4526,13 +5455,10 @@ } }, "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, - "requires": { - "tryit": "1.0.3" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true }, "is-stream": { "version": "1.1.0", @@ -4649,9 +5575,9 @@ "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=" }, "js-base64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", - "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz", + "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA==", "dev": true }, "js-crc": { @@ -4702,12 +5628,6 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=" }, - "jschardet": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", - "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", - "dev": true - }, "jsdoc": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz", @@ -4715,12 +5635,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.6", + "marked": "0.3.7", "mkdirp": "0.5.1", "requizzle": "0.2.1", "strip-json-comments": "2.0.1", @@ -4770,19 +5690,19 @@ "acorn": "4.0.13", "acorn-globals": "3.1.0", "array-equal": "1.0.0", - "content-type-parser": "1.0.1", + "content-type-parser": "1.0.2", "cssom": "0.3.2", "cssstyle": "0.2.37", "escodegen": "1.9.0", - "html-encoding-sniffer": "1.0.1", - "nwmatcher": "1.4.2", + "html-encoding-sniffer": "1.0.2", + "nwmatcher": "1.4.3", "parse5": "1.5.1", "request": "2.83.0", "sax": "1.2.4", "symbol-tree": "3.2.2", "tough-cookie": "2.3.3", "webidl-conversions": "4.0.2", - "whatwg-encoding": "1.0.1", + "whatwg-encoding": "1.0.3", "whatwg-url": "4.8.0", "xml-name-validator": "2.0.1" } @@ -4816,10 +5736,17 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, + "optional": 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", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -4851,7 +5778,8 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "dev": true, + "optional": true }, "jsonpath": { "version": "1.0.0", @@ -4939,10 +5867,10 @@ "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", "dev": true, "requires": { - "errno": "0.1.4", + "errno": "0.1.6", "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", @@ -5127,6 +6055,12 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } }, @@ -5155,6 +6089,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": { @@ -5195,6 +6137,12 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", @@ -5207,6 +6155,12 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.mergewith": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "dev": true + }, "lodash.unescape": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", @@ -5273,12 +6227,12 @@ "dev": true }, "make-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", - "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", "dev": true, "requires": { - "pify": "2.3.0" + "pify": "3.0.0" } }, "map-obj": { @@ -5288,9 +6242,9 @@ "dev": true }, "marked": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz", - "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.7.tgz", + "integrity": "sha512-zBEP4qO1YQp5aXHt8S5wTiOv9i2X74V/LQL0zhUNvVaklt6Ywa6lChxIvS+ibYlCGgADwKwZFhjC3+XfpsvQvQ==", "dev": true }, "math-expression-evaluator": { @@ -5342,7 +6296,7 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.4", + "errno": "0.1.6", "readable-stream": "2.3.3" } }, @@ -5416,9 +6370,9 @@ } }, "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { @@ -5437,9 +6391,9 @@ } }, "mimer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.1.tgz", - "integrity": "sha1-xjxaF/6GQj9RYahdVcPtUYm6r/w=", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.3.tgz", + "integrity": "sha512-cICHJPMZUdZMqWaOQ+Eh0hHo1R6IUCiBee7WvIGGUJsZyjdMUInxQVmyu8hKj5uCy+Bi+Wlp/EsdUR61yOdWOw==", "dev": true }, "mimic-fn": { @@ -5525,6 +6479,13 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5692,10 +6653,9 @@ "dev": true }, "nwmatcher": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.2.tgz", - "integrity": "sha512-QMkCGQFYp5p+zwU3INntLmz1HMfSx9dMVJMYKmE1yuSf/22Wjo6VPFa405mCLUuQn9lbQvH2DZN9lt10ZNvtAg==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", + "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==" }, "oauth-sign": { "version": "0.8.2", @@ -5990,6 +6950,14 @@ "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": { @@ -6018,175 +6986,26 @@ "dev": true }, "phantomjs-prebuilt": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz", - "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=", + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", "dev": true, "requires": { - "es6-promise": "4.0.5", - "extract-zip": "1.6.5", + "es6-promise": "4.1.1", + "extract-zip": "1.6.6", "fs-extra": "1.0.0", "hasha": "2.2.0", "kew": "0.7.0", "progress": "1.1.8", - "request": "2.81.0", + "request": "2.83.0", "request-progress": "2.0.1", "which": "1.2.14" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": 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 - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": 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, - "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, - "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 - }, - "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, - "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, - "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, - "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 - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": 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, - "requires": { - "hoek": "2.16.3" - } - } } }, "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": { @@ -6239,13 +7058,13 @@ } }, "postcss": { - "version": "5.2.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", - "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", "dev": true, "requires": { "chalk": "1.1.3", - "js-base64": "2.3.2", + "js-base64": "2.4.0", "source-map": "0.5.7", "supports-color": "3.2.3" }, @@ -6267,7 +7086,7 @@ "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-message-helpers": "2.0.0", "reduce-css-calc": "1.3.0" } @@ -6279,7 +7098,7 @@ "dev": true, "requires": { "colormin": "1.1.2", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6289,7 +7108,7 @@ "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6301,7 +7120,7 @@ "requires": { "escape-string-regexp": "1.0.5", "extend": "3.0.1", - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -6310,18 +7129,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6331,20 +7150,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6358,7 +7183,7 @@ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-discard-duplicates": { @@ -6367,7 +7192,7 @@ "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-discard-empty": { @@ -6376,7 +7201,7 @@ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-discard-overridden": { @@ -6385,7 +7210,7 @@ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-discard-unused": { @@ -6394,7 +7219,7 @@ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "uniqs": "2.0.0" } }, @@ -6404,7 +7229,7 @@ "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "uniqid": "4.1.1" } }, @@ -6414,7 +7239,7 @@ "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=", "dev": true, "requires": { - "postcss": "6.0.12", + "postcss": "6.0.14", "postcss-value-parser": "3.3.0", "read-cache": "1.0.0", "resolve": "1.1.7" @@ -6426,18 +7251,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6447,20 +7272,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6518,7 +7349,7 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "dev": true, "requires": { - "color-convert": "1.9.0" + "color-convert": "1.9.1" } }, "chalk": { @@ -6573,7 +7404,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6583,7 +7414,7 @@ "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-merge-rules": { @@ -6594,7 +7425,7 @@ "requires": { "browserslist": "1.7.7", "caniuse-api": "1.6.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-selector-parser": "2.2.3", "vendors": "1.0.1" }, @@ -6605,8 +7436,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000741", - "electron-to-chromium": "1.3.24" + "caniuse-db": "1.0.30000784", + "electron-to-chromium": "1.3.29" } } } @@ -6624,7 +7455,7 @@ "dev": true, "requires": { "object-assign": "4.1.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6634,7 +7465,7 @@ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6645,7 +7476,7 @@ "dev": true, "requires": { "alphanum-sort": "1.0.2", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0", "uniqs": "2.0.0" } @@ -6658,7 +7489,7 @@ "requires": { "alphanum-sort": "1.0.2", "has": "1.0.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-selector-parser": "2.2.3" } }, @@ -6668,7 +7499,7 @@ "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", "dev": true, "requires": { - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -6677,18 +7508,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6698,20 +7529,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6726,7 +7563,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -6735,18 +7572,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6756,20 +7593,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6784,7 +7627,7 @@ "dev": true, "requires": { "css-selector-tokenizer": "0.7.0", - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -6793,18 +7636,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6814,20 +7657,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6842,7 +7691,7 @@ "dev": true, "requires": { "icss-replace-symbols": "1.1.0", - "postcss": "6.0.12" + "postcss": "6.0.14" }, "dependencies": { "ansi-styles": { @@ -6851,18 +7700,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -6872,20 +7721,26 @@ "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.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", "dev": true, "requires": { - "chalk": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.4.0" + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -6899,7 +7754,7 @@ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-normalize-url": { @@ -6910,7 +7765,7 @@ "requires": { "is-absolute-url": "2.1.0", "normalize-url": "1.9.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6920,7 +7775,7 @@ "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6930,7 +7785,7 @@ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6940,7 +7795,7 @@ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { - "postcss": "5.2.17" + "postcss": "5.2.18" } }, "postcss-reduce-transforms": { @@ -6950,7 +7805,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0" } }, @@ -6972,7 +7827,7 @@ "dev": true, "requires": { "is-svg": "2.1.0", - "postcss": "5.2.17", + "postcss": "5.2.18", "postcss-value-parser": "3.3.0", "svgo": "0.7.2" } @@ -6984,7 +7839,7 @@ "dev": true, "requires": { "alphanum-sort": "1.0.2", - "postcss": "5.2.17", + "postcss": "5.2.18", "uniqs": "2.0.0" } }, @@ -7001,7 +7856,7 @@ "dev": true, "requires": { "has": "1.0.1", - "postcss": "5.2.17", + "postcss": "5.2.18", "uniqs": "2.0.0" } }, @@ -7033,9 +7888,9 @@ } }, "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, "process": { @@ -7077,9 +7932,9 @@ } }, "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, "pseudomap": { @@ -7102,9 +7957,9 @@ } }, "pump": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", - "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "dev": true, "requires": { "end-of-stream": "1.4.0", @@ -7119,7 +7974,7 @@ "requires": { "duplexify": "3.5.1", "inherits": "2.0.3", - "pump": "1.0.2" + "pump": "1.0.3" } }, "punycode": { @@ -7129,9 +7984,9 @@ "dev": true }, "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "qs": { @@ -7247,13 +8102,13 @@ } }, "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", "dev": true, "requires": { "deep-extend": "0.4.2", - "ini": "1.3.4", + "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" }, @@ -7273,6 +8128,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": { @@ -7409,7 +8272,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "private": "0.1.7" + "private": "0.1.8" } }, "regex-cache": { @@ -7694,17 +8557,40 @@ "dev": true }, "sanitize-html": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.15.0.tgz", - "integrity": "sha512-1jWLToWx8ZV53Z1Jg+2fHl8dNFsxvQt2Cmrk4o/z1+MUdB5EXSU0QVuzlGGhfp7cQrYbEEfMO/TUWHfkBUqujQ==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.16.3.tgz", + "integrity": "sha512-XpAJGnkMfNM7AzXLRw225blBB/pE4dM4jzRn98g4r88cfxwN6g+5IsRmCAh/gbhYGm6u6i97zsatMOM7Lr8wyw==", "dev": true, "requires": { "htmlparser2": "3.9.2", + "lodash.clonedeep": "4.5.0", "lodash.escaperegexp": "4.1.2", + "lodash.mergewith": "4.6.0", + "postcss": "6.0.14", "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==", + "dev": true, + "requires": { + "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==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, "domhandler": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", @@ -7714,6 +8600,12 @@ "domelementtype": "1.3.0" } }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, "htmlparser2": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", @@ -7727,6 +8619,32 @@ "inherits": "2.0.3", "readable-stream": "2.3.3" } + }, + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.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=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -7742,7 +8660,7 @@ "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", "dev": true, "requires": { - "ajv": "5.2.3" + "ajv": "5.5.2" } }, "select-hose": { @@ -7785,6 +8703,14 @@ "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + } } }, "serve-index": { @@ -7896,9 +8822,9 @@ } }, "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" @@ -8273,9 +9199,9 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.2.3", - "ajv-keywords": "2.1.0", - "chalk": "2.1.0", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", "lodash": "4.17.4", "slice-ansi": "1.0.0", "string-width": "2.1.1" @@ -8287,18 +9213,18 @@ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", "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.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" } }, "has-flag": { @@ -8308,9 +9234,9 @@ "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": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -8438,12 +9364,6 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -8491,13 +9411,21 @@ "dev": true }, "uglify-js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.3.tgz", - "integrity": "sha512-5ZUOgufCHjN2mBBLfz63UtWTP6va2sSzBpNCM+/iqI6RnPzEhANmB0EKiKBYdQbc3v7KeomXJ2DJx0Xq9gvUvA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.2.tgz", + "integrity": "sha512-++1NO/zZIEdWf6cDIGceSJQPX31SqIpbVAHwFG5+240MtZqPG/NIPoinj8zlXQtAfMBqEt1Jyv2FiLP3n9gVhQ==", "dev": true, "requires": { - "commander": "2.11.0", - "source-map": "0.5.7" + "commander": "2.12.2", + "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 + } } }, "uglify-to-browserify": { @@ -8515,7 +9443,7 @@ "requires": { "source-map": "0.5.7", "uglify-js": "2.8.29", - "webpack-sources": "1.0.1" + "webpack-sources": "1.1.0" }, "dependencies": { "camelcase": { @@ -8644,7 +9572,7 @@ "dev": true, "requires": { "loader-utils": "1.1.0", - "mime": "1.4.1", + "mime": "1.6.0", "schema-utils": "0.3.0" } }, @@ -8781,7 +9709,7 @@ "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "chokidar": "1.7.0", "graceful-fs": "4.1.11" } @@ -8801,7 +9729,7 @@ "integrity": "sha512-NvLvZzKvnNAB3LXG5c12WwUx5ZA7ZfNMYq82GnbhFyBLuu3jtamW4tQ40M02XiQzkFsyDuWG6Y2TOq9yywaxlg==", "dev": true, "requires": { - "async": "2.5.0", + "async": "2.6.0", "chalk": "1.1.3", "datauri": "1.0.5", "htmlparser2": "3.9.2", @@ -8850,9 +9778,9 @@ "requires": { "acorn": "5.2.1", "acorn-dynamic-import": "2.0.2", - "ajv": "5.2.3", - "ajv-keywords": "2.1.0", - "async": "2.5.0", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "async": "2.6.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", "interpret": "1.1.0", @@ -8868,7 +9796,7 @@ "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", "watchpack": "1.4.0", - "webpack-sources": "1.0.1", + "webpack-sources": "1.1.0", "yargs": "8.0.2" }, "dependencies": { @@ -8918,14 +9846,6 @@ "path-is-absolute": "1.0.1", "range-parser": "1.2.0", "time-stamp": "2.0.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - } } }, "webpack-dev-server": { @@ -9048,12 +9968,6 @@ "lcid": "1.0.0" } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -9119,13 +10033,21 @@ "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" + "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 + } } }, "websocket-driver": { @@ -9145,20 +10067,12 @@ "dev": true }, "whatwg-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz", - "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", "dev": true, "requires": { - "iconv-lite": "0.4.13" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - } + "iconv-lite": "0.4.19" } }, "whatwg-url": { @@ -9395,6 +10309,12 @@ "pify": "2.3.0" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", diff --git a/package.json b/package.json index 3f97db65..a5c8a74f 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "moment": "^2.20.1", "moment-timezone": "^0.5.14", "node-md6": "^0.1.0", + "nwmatcher": "^1.4.3", "otp": "^0.1.3", "sladex-blowfish": "^0.8.1", "sortablejs": "^1.7.0", diff --git a/src/core/operations/Code.js b/src/core/operations/Code.js index fb4a7e9d..d6904e09 100755 --- a/src/core/operations/Code.js +++ b/src/core/operations/Code.js @@ -2,9 +2,10 @@ import {camelCase, kebabCase, snakeCase} from "lodash"; import Utils from "../Utils.js"; import vkbeautify from "vkbeautify"; -import {DOMParser as dom} from "xmldom"; +import {DOMParser} from "xmldom"; import xpath from "xpath"; import jpath from "jsonpath"; +import nwmatcher from "nwmatcher"; import prettyPrintOne from "imports-loader?window=>global!exports-loader?prettyPrintOne!google-code-prettify/bin/prettify.min.js"; @@ -336,7 +337,7 @@ const Code = { let doc; try { - doc = new dom().parseFromString(input); + doc = new DOMParser().parseFromString(input, "application/xml"); } catch (err) { return "Invalid input XML."; } @@ -423,7 +424,7 @@ const Code = { let query = args[0], delimiter = args[1], parser = new DOMParser(), - html, + dom, result; if (!query.length || !input.length) { @@ -431,32 +432,32 @@ const Code = { } try { - html = parser.parseFromString(input, "text/html"); + dom = parser.parseFromString(input); } catch (err) { return "Invalid input HTML."; } try { - result = html.querySelectorAll(query); + const matcher = nwmatcher({document: dom}); + result = matcher.select(query, dom); } catch (err) { return "Invalid CSS Selector. Details:\n" + err.message; } const nodeToString = function(node) { + return node.toString(); + /* xmldom does not return the outerHTML value. switch (node.nodeType) { - case Node.ELEMENT_NODE: return node.outerHTML; - case Node.ATTRIBUTE_NODE: return node.value; - case Node.COMMENT_NODE: return node.data; - case Node.TEXT_NODE: return node.wholeText; - case Node.DOCUMENT_NODE: return node.outerHTML; + case node.ELEMENT_NODE: return node.outerHTML; + case node.ATTRIBUTE_NODE: return node.value; + case node.TEXT_NODE: return node.wholeText; + case node.COMMENT_NODE: return node.data; + case node.DOCUMENT_NODE: return node.outerHTML; default: throw new Error("Unknown Node Type: " + node.nodeType); - } + }*/ }; - return Array.apply(null, Array(result.length)) - .map(function(_, i) { - return result[i]; - }) + return result .map(nodeToString) .join(delimiter); }, diff --git a/test/tests/operations/Code.js b/test/tests/operations/Code.js index fee0b5f4..b13dcfd9 100644 --- a/test/tests/operations/Code.js +++ b/test/tests/operations/Code.js @@ -310,4 +310,26 @@ TestRegister.addTests([ } ], }, + { + name: "CSS selector", + input: '
    \n

    hello

    \n

    world

    \n

    again

    \n
    ', + expectedOutput: '

    hello

    \n

    again

    ', + recipeConfig: [ + { + "op": "CSS selector", + "args": ["#test p.a", "\\n"] + } + ] + }, + { + name: "XPath expression", + input: '
    \n

    hello

    \n

    world

    \n

    again

    \n
    ', + expectedOutput: '

    hello

    \n

    again

    ', + recipeConfig: [ + { + "op": "XPath expression", + "args": ["/div/p[@class=\"a\"]", "\\n"] + } + ] + } ]); From 5e9380b550f1289196ec75fd63bda814b4d6bd03 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 13:43:31 +0000 Subject: [PATCH 066/124] 6.7.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 404a87c0..2a141d0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.0", + "version": "6.7.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a5c8a74f..26df4a9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.0", + "version": "6.7.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 57b1667b69c43df46338b27a96cbc82d7eb304ce Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 15:45:58 +0000 Subject: [PATCH 067/124] Fixed the Numberwang algorithm to correctly recognise recently discovered Numberwang values. Fixes #204 --- src/core/operations/Numberwang.js | 68 ++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/src/core/operations/Numberwang.js b/src/core/operations/Numberwang.js index 9d0fce68..4267923d 100755 --- a/src/core/operations/Numberwang.js +++ b/src/core/operations/Numberwang.js @@ -14,16 +14,72 @@ const Numberwang = { * @returns {string} */ run: function(input, args) { - if (!input) return "Let's play Wangernumb!"; - const match = input.match(/\d+/); - if (match) { - return match[0] + "! That's Numberwang!"; + let output; + if (!input) { + output = "Let's play Wangernumb!"; } else { - // That's a bad miss! - return "Sorry, that's not Numberwang. Let's rotate the board!"; + 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() * Numberwang._didYouKnow.length); + return output + "\n\nDid you know: " + Numberwang._didYouKnow[rand]; }, + + /** + * Taken from http://numberwang.wikia.com/wiki/Numberwang_Wikia + * + * @private + * @constant + */ + _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; From 09b6661e3521af6e71f46f5a286d5d6252bbe360 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 15:51:57 +0000 Subject: [PATCH 068/124] Fixed trailing spaces --- src/core/Utils.js | 2 +- src/core/operations/MS.js | 2 +- src/web/App.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index f2a992e5..e7243201 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -859,7 +859,7 @@ const Utils = { * * fragment = *( pchar / "/" / "?" ) * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" * pct-encoded = "%" HEXDIG HEXDIG * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" diff --git a/src/core/operations/MS.js b/src/core/operations/MS.js index d0f6149a..a74dbe17 100644 --- a/src/core/operations/MS.js +++ b/src/core/operations/MS.js @@ -1,5 +1,5 @@ /** - * Microsoft operations. + * Microsoft operations. * * @author bmwhitn [brian.m.whitney@outlook.com] * @copyright Crown Copyright 2017 diff --git a/src/web/App.js b/src/web/App.js index 036a4fb9..d877791d 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -529,7 +529,7 @@ App.prototype.setCompileMessage = function() { /** * Determines whether the browser supports Local Storage and if it is accessible. - * + * * @returns {boolean} */ App.prototype.isLocalStorageAvailable = function() { From fe4c5f5899636c68709edec610edaa09ee4c3816 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 15:56:56 +0000 Subject: [PATCH 069/124] 6.7.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a141d0d..bdb94e32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.1", + "version": "6.7.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 26df4a9a..f9e7b4b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.1", + "version": "6.7.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 5e7f8e397656063047db1e4519779265833d972a Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 20 Dec 2017 16:34:21 +0000 Subject: [PATCH 070/124] Removed unnecessary whitespace --- src/core/Dish.js | 4 ++-- src/core/operations/ByteRepr.js | 2 +- src/core/operations/Numberwang.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/Dish.js b/src/core/Dish.js index 914188c1..26cf5ea1 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -13,7 +13,7 @@ import Utils from "./Utils.js"; */ const Dish = function(value, type) { this.value = value || typeof value == "string" ? value : null; - this.type = type || Dish.BYTE_ARRAY; + this.type = type || Dish.BYTE_ARRAY; }; @@ -101,7 +101,7 @@ Dish.enumLookup = function(typeEnum) { */ Dish.prototype.set = function(value, type) { this.value = value; - this.type = type; + this.type = type; if (!this.valid()) { const sample = Utils.truncate(JSON.stringify(this.value), 13); diff --git a/src/core/operations/ByteRepr.js b/src/core/operations/ByteRepr.js index 5ba7f082..87a543ff 100755 --- a/src/core/operations/ByteRepr.js +++ b/src/core/operations/ByteRepr.js @@ -186,7 +186,7 @@ const ByteRepr = { // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly if (delim === "0x" || delim === "\\x") { pos[0].start += 2; - pos[0].end += 2; + pos[0].end += 2; } return pos; }, diff --git a/src/core/operations/Numberwang.js b/src/core/operations/Numberwang.js index 4267923d..e323f74c 100755 --- a/src/core/operations/Numberwang.js +++ b/src/core/operations/Numberwang.js @@ -16,7 +16,7 @@ const Numberwang = { run: function(input, args) { let output; if (!input) { - output = "Let's play Wangernumb!"; + 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) { From 0fea84ed7a63492f6cea6de19b8a5452ac17db18 Mon Sep 17 00:00:00 2001 From: bwhitn Date: Thu, 21 Dec 2017 00:19:47 -0500 Subject: [PATCH 071/124] WIP --- src/core/config/Categories.js | 9 ++- src/core/operations/Arithmetic.js | 100 +++++++++++++++--------------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 2109ff15..0ab32eb1 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -113,7 +113,7 @@ const Categories = [ ] }, { - name: "Logical operations", + name: "Arithmetic / Logic", ops: [ "XOR", "XOR Brute Force", @@ -127,6 +127,13 @@ const Categories = [ "Rotate left", "Rotate right", "ROT13", + "Sum", + "Sub", + "Multiply", + "Divide", + "Mean", + "Median", + "Standard Deviation", ] }, { diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 1151c28f..6472a7fc 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -31,15 +31,58 @@ const Arithmetic = { "Standard Deviation" ], + /** * * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ - runOp: function(input, args) { - const delim = Utils.charRep[args[0] || "Space"]; + computeSum: function(input, args) { + const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeSub: function(input, args) { + let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeMulti: function(input, args) { + let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeDiv: function(input, args) { + let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeMean: function(input, args) { + let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeMedian: function(input, args) { + let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + computeStdDev: function(input, args) { + let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); + return typeof(val) === 'number' ? val.toString() : ""; + }, + + + _createNumArray: function(input, delim) { + const delim = Utils.charRep[delim || "Space"]; let splitNumbers = input.split(delim), numbers = [], num; @@ -53,11 +96,7 @@ const Arithmetic = { numbers.push(num); } } - num = Arithmetic.opMap[args[1] || "Sum"](numbers); - if (num === null) { - return ""; - } - return num.toString(); + return numbers; }, @@ -71,8 +110,6 @@ const Arithmetic = { _sum: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc + curr); - } else { - return null; } }, @@ -86,8 +123,6 @@ const Arithmetic = { _sub: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc - curr); - } else { - return null; } }, @@ -98,11 +133,9 @@ const Arithmetic = { * @param {number[]} data * @returns {number} */ - _multiply: function(data) { + _multi: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc * curr); - } else { - return null; } }, @@ -113,11 +146,9 @@ const Arithmetic = { * @param {number[]} data * @returns {number} */ - _divide: function(data) { + _div: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc / curr); - } else { - return null; } }, @@ -131,8 +162,6 @@ const Arithmetic = { _mean: function(data) { if (data.length > 0) { return Arithmetic._sum(data) / data.length; - } else { - return null; } }, @@ -172,39 +201,8 @@ const Arithmetic = { devSum += (data[i] - avg) ** 2; } return Math.sqrt(devSum / data.length); - } else { - return null; } }, - - /** - * A mapping of operation names to their function. - * - * @constant - */ - opMap: { - "Sum": function(numArray) { - return Arithmetic._sum(numArray); - }, - "Sub": function(numArray) { - return Arithmetic._sub(numArray); - }, - "Multiply": function(numArray) { - return Arithmetic._multiply(numArray); - }, - "Divide": function(numArray) { - return Arithmetic._divide(numArray); - }, - "Mean": function(numArray) { - return Arithmetic._mean(numArray); - }, - "Median": function(numArray) { - return Arithmetic._median(numArray); - }, - "Standard Deviation": function (numArray) { - return Arithmetic._stdDev(numArray); - }, - }, }; export default Arithmetic; From fc7d2c2f5229c5c5b7c1eee7fbf7dc29a0a160fd Mon Sep 17 00:00:00 2001 From: bwhitn Date: Thu, 21 Dec 2017 05:58:31 -0800 Subject: [PATCH 072/124] separated all functions and updated comments/descriptions --- src/core/config/Categories.js | 3 +- src/core/config/OperationConfig.js | 83 +++++++++++++++++++++-- src/core/config/modules/Default.js | 8 ++- src/core/operations/Arithmetic.js | 103 +++++++++++++++++++---------- 4 files changed, 155 insertions(+), 42 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 0ab32eb1..8fc8ac02 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -128,7 +128,7 @@ const Categories = [ "Rotate right", "ROT13", "Sum", - "Sub", + "Subtract", "Multiply", "Divide", "Mean", @@ -166,7 +166,6 @@ const Categories = [ { name: "Utils", ops: [ - "Arithmetic", "Diff", "Remove whitespace", "Remove null bytes", diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 9f41f2f8..93c82adf 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -658,9 +658,9 @@ const OperationConfig = { } ] }, - "Arithmetic": { + "Sum": { module: "Default", - description: "Conducts mathamatical operations on a list of numbers", + description: "Sums 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: "string", args: [ @@ -668,11 +668,84 @@ const OperationConfig = { 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: "string", + args: [ { - name: "Operation", + name: "Delimiter", type: "option", - value: Arithmetic.OPERATIONS + 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: "string", + 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: "string", + 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: "string", + 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: "string", + 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: "string", + args: [ + { + name: "Delimiter", + type: "option", + value: Arithmetic.DELIM_OPTIONS } ] }, diff --git a/src/core/config/modules/Default.js b/src/core/config/modules/Default.js index 6f672ce2..9a373e12 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -157,7 +157,13 @@ OpModules.Default = { "Return": FlowControl.runReturn, "Comment": FlowControl.runComment, "PHP Deserialize": PHP.runDeserialize, - "Arithmetic": Arithmetic.runOp, + "Sum": Arithmetic.runSum, + "Subtract": Arithmetic.runSub, + "Multiply": Arithmetic.runMulti, + "Divide": Arithmetic.runDiv, + "Mean": Arithmetic.runMean, + "Median": Arithmetic.runMedian, + "Standard Deviation": Arithmetic.runStdDev, /* diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 6472a7fc..9b07f8ad 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -17,72 +17,107 @@ const Arithmetic = { */ DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], - /** - * @constant - * @default - */ - OPERATIONS: [ - "Sum", - "Sub", - "Multiply", - "Divide", - "Mean", - "Median", - "Standard Deviation" - ], - /** - * + * Splits a string based on a delimiter and calculates the sum of numbers. * * @param {string} input * @param {Object[]} args - * @returns {number} + * @returns {string} */ - computeSum: function(input, args) { + runSum: function(input, args) { const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeSub: function(input, args) { + /** + * Splits a string based on a delimiter and subtracts all the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runSub: function(input, args) { let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeMulti: function(input, args) { + /** + * Splits a string based on a delimiter and multiplies the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runMulti: function(input, args) { let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeDiv: function(input, args) { + /** + * Splits a string based on a delimiter and divides the numbers. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runDiv: function(input, args) { let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeMean: function(input, args) { + /** + * Splits a string based on a delimiter and computes the mean (average). + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runMean: function(input, args) { let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeMedian: function(input, args) { + /** + * Splits a string based on a delimiter and finds the median. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runMedian: function(input, args) { let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, - computeStdDev: function(input, args) { + /** + * splits a string based on a delimiter and computes the standard deviation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + runStdDev: function(input, args) { let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === 'number' ? val.toString() : ""; + return typeof(val) === "number" ? val.toString() : ""; }, + /** + * Converts a string array to a number array. + * + * @param {string[]} input + * @param {string} delim + * @returns {number[]} + */ _createNumArray: function(input, delim) { - const delim = Utils.charRep[delim || "Space"]; + delim = Utils.charRep[delim || "Space"]; let splitNumbers = input.split(delim), numbers = [], num; @@ -153,7 +188,7 @@ const Arithmetic = { }, /** - * Finds the mean of a number array and returns the value. + * Computes mean of a number array and returns the value. * * @private * @param {number[]} data @@ -166,7 +201,7 @@ const Arithmetic = { }, /** - * Finds the median of a number array and returns the value. + * Computes median of a number array and returns the value. * * @private * @param {number[]} data @@ -187,7 +222,7 @@ const Arithmetic = { }, /** - * Finds the standard deviation of a number array and returns the value. + * Computes standard deviation of a number array and returns the value. * * @private * @param {number[]} data From 98f59ace3a3d03a48b3a630c7b27deafc1316844 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 21 Dec 2017 15:12:06 +0000 Subject: [PATCH 073/124] Small tweaks to the arithmetic ops --- src/core/config/Categories.js | 10 +- src/core/config/OperationConfig.js | 182 ++++++++++++++--------------- src/core/operations/Arithmetic.js | 39 ++++--- 3 files changed, 120 insertions(+), 111 deletions(-) diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index 177c71fc..e2ee57cf 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -122,11 +122,6 @@ const Categories = [ "AND", "ADD", "SUB", - "Bit shift left", - "Bit shift right", - "Rotate left", - "Rotate right", - "ROT13", "Sum", "Subtract", "Multiply", @@ -134,6 +129,11 @@ const Categories = [ "Mean", "Median", "Standard Deviation", + "Bit shift left", + "Bit shift right", + "Rotate left", + "Rotate right", + "ROT13", ] }, { diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 55c5ff41..2f1d6781 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -520,6 +520,97 @@ const OperationConfig = { } ] }, + "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: "number", + 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: "number", + 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: "number", + 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: "number", + 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: "number", + 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: "number", + 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: "number", + 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 Γειά σου", @@ -677,97 +768,6 @@ const OperationConfig = { } ] }, - "Sum": { - module: "Default", - description: "Sums 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: "string", - 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: "string", - 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: "string", - 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: "string", - 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: "string", - 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: "string", - 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: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: Arithmetic.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.", diff --git a/src/core/operations/Arithmetic.js b/src/core/operations/Arithmetic.js index 9b07f8ad..1fe73ac1 100644 --- a/src/core/operations/Arithmetic.js +++ b/src/core/operations/Arithmetic.js @@ -1,5 +1,6 @@ import Utils from "../Utils.js"; + /** * Math operations on numbers. * @@ -15,7 +16,7 @@ const Arithmetic = { * @constant * @default */ - DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], + DELIM_OPTIONS: ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"], /** @@ -23,11 +24,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runSum: function(input, args) { const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -36,11 +37,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runSub: function(input, args) { let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -49,11 +50,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runMulti: function(input, args) { let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -62,11 +63,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runDiv: function(input, args) { let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -75,11 +76,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runMean: function(input, args) { let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -88,11 +89,11 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runMedian: function(input, args) { let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, @@ -101,17 +102,18 @@ const Arithmetic = { * * @param {string} input * @param {Object[]} args - * @returns {string} + * @returns {number} */ runStdDev: function(input, args) { let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); - return typeof(val) === "number" ? val.toString() : ""; + return typeof(val) === "number" ? val : NaN; }, /** * Converts a string array to a number array. * + * @private * @param {string[]} input * @param {string} delim * @returns {number[]} @@ -121,6 +123,7 @@ const Arithmetic = { let splitNumbers = input.split(delim), numbers = [], num; + for (let i = 0; i < splitNumbers.length; i++) { if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); @@ -148,6 +151,7 @@ const Arithmetic = { } }, + /** * Subtracts an array of numbers and returns the value. * @@ -161,6 +165,7 @@ const Arithmetic = { } }, + /** * Multiplies an array of numbers and returns the value. * @@ -174,6 +179,7 @@ const Arithmetic = { } }, + /** * Divides an array of numbers and returns the value. * @@ -187,6 +193,7 @@ const Arithmetic = { } }, + /** * Computes mean of a number array and returns the value. * @@ -200,6 +207,7 @@ const Arithmetic = { } }, + /** * Computes median of a number array and returns the value. * @@ -221,6 +229,7 @@ const Arithmetic = { } }, + /** * Computes standard deviation of a number array and returns the value. * From 8ee37422163c0b050eaaeb0dbf72cd90a7a1d2b3 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 21 Dec 2017 15:13:54 +0000 Subject: [PATCH 074/124] 6.8.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index bdb94e32..5821d84a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.2", + "version": "6.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f9e7b4b2..c8616b62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.7.2", + "version": "6.8.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 0e7989111f871ed0387fab7453f153125e0145e6 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 25 Dec 2017 23:11:52 +0000 Subject: [PATCH 075/124] Removed CryptoJS from Utils.js. UTF8 conversion is now achieved with the much smaller and actively maintained utf8 library. --- package-lock.json | 5 ++ package.json | 1 + src/core/Dish.js | 24 ++++++ src/core/Utils.js | 118 +++++++++-------------------- src/core/config/modules/Default.js | 1 - src/core/operations/BitwiseOp.js | 18 ++--- src/core/operations/Cipher.js | 95 ++++++++++++++++------- src/web/HighlighterWaiter.js | 2 +- src/web/OutputWaiter.js | 10 +++ 9 files changed, 151 insertions(+), 123 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f0fddf5..5bfed4eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8663,6 +8663,11 @@ } } }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", diff --git a/package.json b/package.json index f62b95e2..ac864d02 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "sladex-blowfish": "^0.8.1", "sortablejs": "^1.7.0", "split.js": "^1.3.5", + "utf8": "^3.0.0", "vkbeautify": "^0.99.3", "xmldom": "^0.1.27", "xpath": "0.0.24", diff --git a/src/core/Dish.js b/src/core/Dish.js index 3cd1c6f3..f1093966 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -217,4 +217,28 @@ Dish.prototype.valid = function() { } }; + +/** + * Determines how much space the Dish takes up. + * Numbers in JavaScript are 64-bit floating point, however for the purposes of the Dish, + * we measure how many bytes are taken up when the number is written as a string. + * + * @returns {number} +*/ +Dish.prototype.size = function() { + switch (this.type) { + case Dish.BYTE_ARRAY: + case Dish.STRING: + case Dish.HTML: + return this.value.length; + case Dish.NUMBER: + return this.value.toString().length; + case Dish.ARRAY_BUFFER: + return this.value.byteLength; + default: + return -1; + } +}; + + export default Dish; diff --git a/src/core/Utils.js b/src/core/Utils.js index f2a992e5..a4a455a2 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -1,4 +1,4 @@ -import CryptoJS from "crypto-js"; +import utf8 from "utf8"; /** @@ -340,6 +340,32 @@ const Utils = { }, + /** + * Coverts data of varying types to a byteArray. + * Accepts hex, Base64, UTF8 and Latin1 strings. + * + * @param {string} str + * @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1" + * @returns {byteArray} + * + * @example + * // returns [] + */ + convertToByteArray: function(str, type) { + switch (type.toLowerCase()) { + case "hex": + return Utils.fromHex(str); + case "base64": + return Utils.fromBase64(str, null, "byteArray"); + case "utf8": + return Utils.strToUtf8ByteArray(str); + case "latin1": + default: + return Utils.strToByteArray(str); + } + }, + + /** * Converts a string to a byte array. * Treats the string as UTF-8 if any values are over 255. @@ -381,17 +407,17 @@ const Utils = { * Utils.strToUtf8ByteArray("你好"); */ strToUtf8ByteArray: function(str) { - let wordArray = CryptoJS.enc.Utf8.parse(str), - byteArray = Utils.wordArrayToByteArray(wordArray); + const utf8Str = utf8.encode(str); - if (str.length !== wordArray.sigBytes) { + if (str.length !== utf8Str.length) { if (ENVIRONMENT_IS_WORKER()) { self.setOption("attemptHighlight", false); } else if (ENVIRONMENT_IS_WEB()) { window.app.options.attemptHighlight = false; } } - return byteArray; + + return Utils.strToByteArray(utf8Str); }, @@ -443,26 +469,21 @@ const Utils = { * Utils.byteArrayToUtf8([228,189,160,229,165,189]); */ byteArrayToUtf8: function(byteArray) { + const str = Utils.byteArrayToChars(byteArray); try { - // Try to output data as UTF-8 string - const words = []; - for (let i = 0; i < byteArray.length; i++) { - words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8); - } - let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length), - str = CryptoJS.enc.Utf8.stringify(wordArray); + const utf8Str = utf8.decode(str); - if (str.length !== wordArray.sigBytes) { + if (str.length !== utf8Str.length) { if (ENVIRONMENT_IS_WORKER()) { self.setOption("attemptHighlight", false); } else if (ENVIRONMENT_IS_WEB()) { window.app.options.attemptHighlight = false; } } - return str; + return utf8Str; } catch (err) { // If it fails, treat it as ANSI - return Utils.byteArrayToChars(byteArray); + return str; } }, @@ -490,30 +511,6 @@ const Utils = { }, - /** - * Converts a CryptoJS.lib.WordArray to a byteArray. - * - * @param {CryptoJS.lib.WordArray} wordArray - * @returns {byteArray} - * - * @example - * // returns [84, 101, 115, 116] - * Utils.wordArrayToByteArray(CryptoJS.enc.Hex.parse("54657374")); - */ - wordArrayToByteArray: function(wordArray) { - if (wordArray.sigBytes <= 0) return []; - - let words = wordArray.words, - byteArray = []; - - for (let i = 0; i < wordArray.sigBytes; i++) { - byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff); - } - - return byteArray; - }, - - /** * Base64's the input byte array using the given alphabet, returning a string. * @@ -1248,21 +1245,6 @@ const Utils = { "None": /\s+/g // Included here to remove whitespace when there shouldn't be any }, - - /** - * A mapping of string formats to their classes in the CryptoJS library. - * @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 Utils; @@ -1374,31 +1356,3 @@ Array.prototype.equals = function(other) { String.prototype.count = function(chr) { return this.split(chr).length - 1; }; - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Library overrides /////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * 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/config/modules/Default.js b/src/core/config/modules/Default.js index dec015a5..eea41164 100644 --- a/src/core/config/modules/Default.js +++ b/src/core/config/modules/Default.js @@ -37,7 +37,6 @@ import UUID from "../../operations/UUID.js"; * * Libraries: * - Utils.js - * - CryptoJS * - otp * * @author n1474335 [n1474335@gmail.com] diff --git a/src/core/operations/BitwiseOp.js b/src/core/operations/BitwiseOp.js index 7512aa32..f2551cba 100755 --- a/src/core/operations/BitwiseOp.js +++ b/src/core/operations/BitwiseOp.js @@ -67,7 +67,7 @@ const BitwiseOp = { * @constant * @default */ - KEY_FORMAT: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"], + KEY_FORMAT: ["Hex", "Base64", "UTF8", "Latin1"], /** * XOR operation. @@ -77,12 +77,10 @@ const BitwiseOp = { * @returns {byteArray} */ runXor: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), + const key = Utils.convertToByteArray(args[0].string || "", args[0].option), scheme = args[1], nullPreserving = args[2]; - key = Utils.wordArrayToByteArray(key); - return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme); }, @@ -200,8 +198,7 @@ const BitwiseOp = { * @returns {byteArray} */ runAnd: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._and); }, @@ -215,8 +212,7 @@ const BitwiseOp = { * @returns {byteArray} */ runOr: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._or); }, @@ -230,8 +226,7 @@ const BitwiseOp = { * @returns {byteArray} */ runAdd: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._add); }, @@ -245,8 +240,7 @@ const BitwiseOp = { * @returns {byteArray} */ runSub: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""); - key = Utils.wordArrayToByteArray(key); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option); return BitwiseOp._bitOp(input, key, BitwiseOp._sub); }, diff --git a/src/core/operations/Cipher.js b/src/core/operations/Cipher.js index 465c3e9e..227c2735 100755 --- a/src/core/operations/Cipher.js +++ b/src/core/operations/Cipher.js @@ -61,9 +61,9 @@ const Cipher = { * @returns {string} */ _enc: function (algo, input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), - iv = Utils.format[args[1].option].parse(args[1].string || ""), - salt = Utils.format[args[2].option].parse(args[2].string || ""), + let key = Cipher._format[args[0].option].parse(args[0].string || ""), + iv = Cipher._format[args[1].option].parse(args[1].string || ""), + salt = Cipher._format[args[2].option].parse(args[2].string || ""), mode = CryptoJS.mode[args[3]], padding = CryptoJS.pad[args[4]], resultOption = args[5].toLowerCase(), @@ -83,12 +83,12 @@ const Cipher = { let result = ""; if (resultOption === "show all") { - result += "Key: " + encrypted.key.toString(Utils.format[outputFormat]); - result += "\nIV: " + encrypted.iv.toString(Utils.format[outputFormat]); - if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Utils.format[outputFormat]); - result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Utils.format[outputFormat]); + result += "Key: " + encrypted.key.toString(Cipher._format[outputFormat]); + result += "\nIV: " + encrypted.iv.toString(Cipher._format[outputFormat]); + if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Cipher._format[outputFormat]); + result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Cipher._format[outputFormat]); } else { - result = encrypted[resultOption].toString(Utils.format[outputFormat]); + result = encrypted[resultOption].toString(Cipher._format[outputFormat]); } return result; @@ -105,9 +105,9 @@ const Cipher = { * @returns {string} */ _dec: function (algo, input, args) { - let key = Utils.format[args[0].option].parse(args[0].string || ""), - iv = Utils.format[args[1].option].parse(args[1].string || ""), - salt = Utils.format[args[2].option].parse(args[2].string || ""), + let key = Cipher._format[args[0].option].parse(args[0].string || ""), + iv = Cipher._format[args[1].option].parse(args[1].string || ""), + salt = Cipher._format[args[2].option].parse(args[2].string || ""), mode = CryptoJS.mode[args[3]], padding = CryptoJS.pad[args[4]], inputFormat = args[5], @@ -118,7 +118,7 @@ const Cipher = { return "No input"; } - const ciphertext = Utils.format[inputFormat].parse(input); + const ciphertext = Cipher._format[inputFormat].parse(input); if (iv.sigBytes === 0) { // Use passphrase rather than key. Need to convert it to a string. @@ -136,7 +136,7 @@ const Cipher = { let result; try { - result = decrypted.toString(Utils.format[outputFormat]); + result = decrypted.toString(Cipher._format[outputFormat]); } catch (err) { result = "Decrypt error: " + err.message; } @@ -260,7 +260,7 @@ const Cipher = { * @returns {string} */ runBlowfishEnc: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1), + let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1), mode = args[1], outputFormat = args[2]; @@ -272,7 +272,7 @@ const Cipher = { }), enc = CryptoJS.enc.Hex.parse(encHex); - return enc.toString(Utils.format[outputFormat]); + return enc.toString(Cipher._format[outputFormat]); }, @@ -284,13 +284,13 @@ const Cipher = { * @returns {string} */ runBlowfishDec: function (input, args) { - let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1), + let key = Cipher._format[args[0].option].parse(args[0].string).toString(Cipher._format.Latin1), mode = args[1], inputFormat = args[2]; if (key.length === 0) return "Enter a key"; - input = Utils.format[inputFormat].parse(input); + input = Cipher._format[inputFormat].parse(input); return Blowfish.decrypt(input.toString(CryptoJS.enc.Base64), key, { outputType: 0, // This actually means inputType. The library is weird. @@ -329,14 +329,14 @@ const Cipher = { salt = CryptoJS.enc.Hex.parse(args[3] || ""), inputFormat = args[4], outputFormat = args[5], - passphrase = Utils.format[inputFormat].parse(input), + passphrase = Cipher._format[inputFormat].parse(input), key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize, hasher: CryptoJS.algo[hasher], iterations: iterations, }); - return key.toString(Utils.format[outputFormat]); + return key.toString(Cipher._format[outputFormat]); }, @@ -354,14 +354,14 @@ const Cipher = { salt = CryptoJS.enc.Hex.parse(args[3] || ""), inputFormat = args[4], outputFormat = args[5], - passphrase = Utils.format[inputFormat].parse(input), + passphrase = Cipher._format[inputFormat].parse(input), key = CryptoJS.EvpKDF(passphrase, salt, { keySize: keySize, hasher: CryptoJS.algo[hasher], iterations: iterations, }); - return key.toString(Utils.format[outputFormat]); + return key.toString(Cipher._format[outputFormat]); }, @@ -373,11 +373,11 @@ const Cipher = { * @returns {string} */ runRc4: function (input, args) { - let message = Utils.format[args[1]].parse(input), - passphrase = Utils.format[args[0].option].parse(args[0].string), + 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(Utils.format[args[2]]); + return encrypted.ciphertext.toString(Cipher._format[args[2]]); }, @@ -395,12 +395,12 @@ const Cipher = { * @returns {string} */ runRc4drop: function (input, args) { - let message = Utils.format[args[1]].parse(input), - passphrase = Utils.format[args[0].option].parse(args[0].string), + 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(Utils.format[args[2]]); + return encrypted.ciphertext.toString(Cipher._format[args[2]]); }, @@ -783,6 +783,23 @@ const Cipher = { 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; @@ -827,3 +844,27 @@ CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) { // 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/web/HighlighterWaiter.js b/src/web/HighlighterWaiter.js index c650e6ba..d9980fec 100755 --- a/src/web/HighlighterWaiter.js +++ b/src/web/HighlighterWaiter.js @@ -402,7 +402,7 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) { // 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 (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false; + if (this.manager.output.containsCR()) return false; const startPlaceholder = "[startHighlight]"; const startPlaceholderRegex = /\[startHighlight\]/g; diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index a5576f31..076d62b2 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -282,4 +282,14 @@ OutputWaiter.prototype.setStatusMsg = function(msg) { el.textContent = msg; }; + +/** + * Returns true if the output contains carriage returns + * + * @returns {boolean} + */ +OutputWaiter.prototype.containsCR = function() { + return this.app.dishStr.indexOf("\r") >= 0; +}; + export default OutputWaiter; From af71ca6a25bfb8f1d4e449d84bdfaa677e3603d8 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 26 Dec 2017 00:44:40 +0000 Subject: [PATCH 076/124] Output over 1MiB is passed back as an ArrayBuffer and an output file card is displayed. --- src/core/Chef.js | 7 ++- src/core/Utils.js | 25 +++++++- src/web/InputWaiter.js | 9 +-- src/web/OutputWaiter.js | 92 +++++++++++++++++++++--------- src/web/WorkerWaiter.js | 14 ++++- src/web/html/index.html | 15 ++++- src/web/stylesheets/layout/_io.css | 3 +- 7 files changed, 130 insertions(+), 35 deletions(-) diff --git a/src/core/Chef.js b/src/core/Chef.js index d176a36d..06d08aa0 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -76,10 +76,15 @@ Chef.prototype.bake = async function(input, recipeConfig, options, progress, ste progress = err.progress; } + // Depending on the size of the output, we may send it back as a string or an ArrayBuffer. + // This can prevent unnecessary casting as an ArrayBuffer can be easily downloaded as a file. + // 1048576 bytes = 1 MiB + const returnType = this.dish.size() > 1048576 ? Dish.ARRAY_BUFFER : Dish.STRING; + return { result: this.dish.type === Dish.HTML ? this.dish.get(Dish.HTML) : - this.dish.get(Dish.STRING), + this.dish.get(returnType), type: Dish.enumLookup(this.dish.type), progress: progress, duration: new Date().getTime() - startTime, diff --git a/src/core/Utils.js b/src/core/Utils.js index a4a455a2..4ab365c8 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -349,7 +349,14 @@ const Utils = { * @returns {byteArray} * * @example - * // returns [] + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("Привет", "utf8"); + * + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("d097d0b4d180d0b0d0b2d181d182d0b2d183d0b9d182d0b5", "hex"); + * + * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] + * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); */ convertToByteArray: function(str, type) { switch (type.toLowerCase()) { @@ -511,6 +518,22 @@ const Utils = { }, + /** + * Converts an ArrayBuffer to a string. + * + * @param {ArrayBuffer} arrayBuffer + * @returns {string} + * + * @example + * // returns "hello" + * Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer); + */ + arrayBufferToStr: function(arrayBuffer) { + const byteArray = Array.prototype.slice.call(new Uint8Array(arrayBuffer)); + return Utils.byteArrayToUtf8(byteArray); + }, + + /** * Base64's the input byte array using the given alphabet, returning a string. * diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index b5748e3f..e5a58fe1 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -79,13 +79,13 @@ InputWaiter.prototype.setFile = function(file) { fileName = document.getElementById("input-file-name"), fileSize = document.getElementById("input-file-size"), fileType = document.getElementById("input-file-type"), - fileUploaded = document.getElementById("input-file-uploaded"); + fileLoaded = document.getElementById("input-file-loaded"); fileOverlay.style.display = "block"; fileName.textContent = file.name; fileSize.textContent = file.size.toLocaleString() + " bytes"; fileType.textContent = file.type; - fileUploaded.textContent = "0%"; + fileLoaded.textContent = "0%"; }; @@ -210,8 +210,8 @@ InputWaiter.prototype.inputDrop = function(e) { InputWaiter.prototype.handleLoaderMessage = function(e) { const r = e.data; if (r.hasOwnProperty("progress")) { - const fileUploaded = document.getElementById("input-file-uploaded"); - fileUploaded.textContent = r.progress + "%"; + const fileLoaded = document.getElementById("input-file-loaded"); + fileLoaded.textContent = r.progress + "%"; } if (r.hasOwnProperty("fileBuffer")) { @@ -246,6 +246,7 @@ InputWaiter.prototype.clearIoClick = function() { document.getElementById("output-info").innerHTML = ""; document.getElementById("input-selection-info").innerHTML = ""; document.getElementById("output-selection-info").innerHTML = ""; + document.getElementById("output-file").style.display = "none"; window.dispatchEvent(this.manager.statechange); }; diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 076d62b2..1c857074 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -31,47 +31,85 @@ OutputWaiter.prototype.get = function() { /** * Sets the output in the output textarea. * - * @param {string} dataStr - The output string/HTML + * @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 */ -OutputWaiter.prototype.set = function(dataStr, type, duration) { +OutputWaiter.prototype.set = function(data, type, duration) { 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 (type === "html") { - outputText.style.display = "none"; - outputHtml.style.display = "block"; - outputHighlighter.display = "none"; - inputHighlighter.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 = dataStr; + outputText.value = ""; + outputHtml.innerHTML = data; + length = data.length; - // Execute script sections - const scriptElements = outputHtml.querySelectorAll("script"); - for (let i = 0; i < scriptElements.length; i++) { - try { - eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval - } catch (err) { - console.error(err); + // 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) { + console.error(err); + } } - } - } else { - outputText.style.display = "block"; - outputHtml.style.display = "none"; - outputHighlighter.display = "block"; - inputHighlighter.display = "block"; + break; + case "ArrayBuffer": + outputText.style.display = "block"; + outputHtml.style.display = "none"; + outputHighlighter.display = "none"; + inputHighlighter.display = "none"; - outputText.value = Utils.printable(dataStr, true); - outputHtml.innerHTML = ""; + outputText.value = ""; + outputHtml.innerHTML = ""; + length = data.byteLength; + + this.setFile(new File([data], "output.dat")); + 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; + break; } this.manager.highlighter.removeHighlights(); - const lines = dataStr.count("\n") + 1; - this.setOutputInfo(dataStr.length, lines, duration); + this.setOutputInfo(length, lines, duration); +}; + + +/** + * Shows file details. + * + * @param {File} file + */ +OutputWaiter.prototype.setFile = function(file) { + // 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"; }; @@ -86,6 +124,8 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { let width = length.toString().length; width = width < 4 ? 4 : width; + lines = typeof lines === "number" ? lines : ""; + const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " "); diff --git a/src/web/WorkerWaiter.js b/src/web/WorkerWaiter.js index 6fc69e40..3ed9e7ea 100644 --- a/src/web/WorkerWaiter.js +++ b/src/web/WorkerWaiter.js @@ -111,7 +111,19 @@ WorkerWaiter.prototype.bakingComplete = function(response) { this.app.handleError(response.error); } - this.app.dishStr = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result; + switch (response.type) { + case "html": + this.app.dishStr = Utils.stripHtmlTags(response.result, true); + break; + case "ArrayBuffer": + this.app.dishStr = ""; + break; + case "string": + default: + this.app.dishStr = response.result; + break; + } + this.app.progress = response.progress; this.manager.recipe.updateBreakpointIndicator(response.progress); this.manager.output.set(response.result, response.type, response.duration); diff --git a/src/web/html/index.html b/src/web/html/index.html index 3bfefa8b..dd6260ea 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -190,7 +190,7 @@ Name:
    Size:
    Type:
    - Uploaded: + Loaded: @@ -216,6 +216,19 @@
    +
    +
    +
    + +
    + Size:
    + Download
    + Display in output
    + Options for how much to display +
    +
    +
    +
    diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 855d4262..519b81fc 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -77,7 +77,8 @@ transition: all 0.5s ease; } -#input-file { +#input-file, +#output-file { position: absolute; left: 0; top: 0; From ff94172b3cf3b079c1a8eedf1a2af468d188ba85 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 26 Dec 2017 01:32:51 +0000 Subject: [PATCH 077/124] Output files can now be downloaded using FileSaver (supports large files ~500MB) --- package-lock.json | 917 ++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/web/InputWaiter.js | 2 +- src/web/Manager.js | 1 + src/web/OutputWaiter.js | 47 +- src/web/html/index.html | 2 +- 6 files changed, 952 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5bfed4eb..e4ba3947 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1407,6 +1407,7 @@ "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", + "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -3118,6 +3119,11 @@ "schema-utils": "0.3.0" } }, + "file-saver": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", + "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI=" + }, "file-sync-cmp": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", @@ -3308,6 +3314,910 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "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, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "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 + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "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" + } + }, + "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" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "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, + "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": { + "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", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "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" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "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" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "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", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "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", + "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" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "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, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "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", + "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" + } + }, + "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, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5524,6 +6434,13 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", diff --git a/package.json b/package.json index ac864d02..8c6fc2d8 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "esmangle": "^1.0.1", "esprima": "^4.0.0", "exif-parser": "^0.1.12", + "file-saver": "^1.3.3", "google-code-prettify": "^1.0.5", "jquery": "^3.2.1", "js-crc": "^0.2.0", diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index e5a58fe1..62a579bb 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -239,6 +239,7 @@ InputWaiter.prototype.closeFile = function() { */ InputWaiter.prototype.clearIoClick = function() { this.closeFile(); + this.manager.output.closeFile(); this.manager.highlighter.removeHighlights(); document.getElementById("input-text").value = ""; document.getElementById("output-text").value = ""; @@ -246,7 +247,6 @@ InputWaiter.prototype.clearIoClick = function() { document.getElementById("output-info").innerHTML = ""; document.getElementById("input-selection-info").innerHTML = ""; document.getElementById("output-selection-info").innerHTML = ""; - document.getElementById("output-file").style.display = "none"; window.dispatchEvent(this.manager.statechange); }; diff --git a/src/web/Manager.js b/src/web/Manager.js index b3ef0158..270e68f8 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -158,6 +158,7 @@ Manager.prototype.initialiseEventListeners = function() { 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(".file-switch", "click", this.output.fileSwitch, this.output); + this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); // Options document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 1c857074..d8d028d0 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -1,4 +1,5 @@ import Utils from "../core/Utils.js"; +import FileSaver from "file-saver"; /** @@ -15,6 +16,8 @@ import Utils from "../core/Utils.js"; const OutputWaiter = function(app, manager) { this.app = app; this.manager = manager; + + this.file = null; }; @@ -43,6 +46,8 @@ OutputWaiter.prototype.set = function(data, type, duration) { const inputHighlighter = document.getElementById("input-highlighter"); let scriptElements, lines, length; + this.closeFile(); + switch (type) { case "html": outputText.style.display = "none"; @@ -104,6 +109,8 @@ OutputWaiter.prototype.set = function(data, type, duration) { * @param {File} file */ OutputWaiter.prototype.setFile = function(file) { + this.file = file; + // Display file overlay in output area with details const fileOverlay = document.getElementById("output-file"), fileSize = document.getElementById("output-file-size"); @@ -113,6 +120,25 @@ OutputWaiter.prototype.setFile = function(file) { }; +/** + * Removes the output file and nulls its memory. + */ +OutputWaiter.prototype.closeFile = function() { + this.file = null; + document.getElementById("output-file").style.display = "none"; +}; + + +/** + * Handler for file download events. + */ +OutputWaiter.prototype.downloadFile = function() { + const filename = window.prompt("Please enter a filename:", "download.dat"); + + if (filename) FileSaver.saveAs(this.file, filename, false); +}; + + /** * Displays information about the output. * @@ -169,24 +195,13 @@ OutputWaiter.prototype.adjustWidth = function() { /** * Handler for save click events. - * Saves the current output to a file, downloaded as a URL octet stream. + * Saves the current output to a file. */ OutputWaiter.prototype.saveClick = function() { - const data = Utils.toBase64(this.app.dishStr); - const filename = window.prompt("Please enter a filename:", "download.dat"); - - if (filename) { - const el = document.createElement("a"); - el.setAttribute("href", "data:application/octet-stream;base64;charset=utf-8," + data); - el.setAttribute("download", filename); - - // Firefox requires that the element be added to the DOM before it can be clicked - el.style.display = "none"; - document.body.appendChild(el); - - el.click(); - el.remove(); + if (!this.file) { + this.file = new File([new Uint8Array(Utils.strToCharcode(this.app.dishStr))], ""); } + this.downloadFile(); }; @@ -250,7 +265,7 @@ OutputWaiter.prototype.undoSwitchClick = function() { /** * Handler for file switch click events. - * Moves a files data for items created via Utils.displayFilesAsHTML to the input. + * Moves a file's data for items created via Utils.displayFilesAsHTML to the input. */ OutputWaiter.prototype.fileSwitch = function(e) { e.preventDefault(); diff --git a/src/web/html/index.html b/src/web/html/index.html index dd6260ea..cd690869 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -222,7 +222,7 @@
    Size:
    - Download
    +
    Display in output
    Options for how much to display
    From 53a3f3d4528e3429f0a3de614ba1a18b892204e7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 26 Dec 2017 22:05:10 +0000 Subject: [PATCH 078/124] Changed inputType for file magic byte operations to ArrayBuffer --- src/core/config/OperationConfig.js | 4 ++-- src/core/operations/FileType.js | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 43072558..d353328b 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3261,14 +3261,14 @@ const OperationConfig = { "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: "byteArray", + 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: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { diff --git a/src/core/operations/FileType.js b/src/core/operations/FileType.js index ad3e5ba7..715f8205 100755 --- a/src/core/operations/FileType.js +++ b/src/core/operations/FileType.js @@ -15,12 +15,13 @@ const FileType = { /** * Detect File Type operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runDetect: function(input, args) { - const type = FileType.magicType(input); + const data = new Uint8Array(input), + type = FileType.magicType(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?"; @@ -46,20 +47,21 @@ const FileType = { /** * Scan for Embedded Files operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runScanForEmbeddedFiles: function(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, - ignoreCommon = args[0], - commonExts = ["ico", "ttf", ""], numFound = 0, numCommonFound = 0; + const ignoreCommon = args[0], + commonExts = ["ico", "ttf", ""], + data = new Uint8Array(input); - for (let i = 0; i < input.length; i++) { - type = FileType.magicType(input.slice(i)); + for (let i = 0; i < data.length; i++) { + type = FileType.magicType(data.slice(i)); if (type) { if (ignoreCommon && commonExts.indexOf(type.ext) > -1) { numCommonFound++; @@ -96,7 +98,7 @@ const FileType = { * Given a buffer, detects magic byte sequences at specific positions and returns the * extension and mime type. * - * @param {byteArray} buf + * @param {Uint8Array} buf * @returns {Object} type * @returns {string} type.ext - File extension * @returns {string} type.mime - Mime type From bad0816115ea73ef9459980d26bdca30bbb1473c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 01:52:41 +0000 Subject: [PATCH 079/124] Output files can be viewed in slices --- src/web/Manager.js | 4 +- src/web/OutputWaiter.js | 58 ++++++++++++++++++----- src/web/html/index.html | 17 +++++-- src/web/static/images/file-128x128.png | Bin 0 -> 19378 bytes src/web/static/images/file-32x32.png | Bin 0 -> 1946 bytes src/web/stylesheets/components/_pane.css | 18 +++++-- src/web/stylesheets/layout/_io.css | 8 ++++ src/web/stylesheets/utils/_overrides.css | 12 ++++- 8 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 src/web/static/images/file-128x128.png create mode 100644 src/web/static/images/file-32x32.png diff --git a/src/web/Manager.js b/src/web/Manager.js index 270e68f8..4b89942a 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -142,7 +142,7 @@ Manager.prototype.initialiseEventListeners = function() { 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.closeFile.bind(this.input)); + 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)); @@ -159,6 +159,8 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output); this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); + this.addDynamicListener("#output-file-slice", "click", this.output.displayFile, 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)); diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index d8d028d0..93cc351b 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -17,7 +17,7 @@ const OutputWaiter = function(app, manager) { this.app = app; this.manager = manager; - this.file = null; + this.dishBuffer = null; }; @@ -37,8 +37,9 @@ OutputWaiter.prototype.get = function() { * @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 = function(data, type, duration) { +OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { const outputText = document.getElementById("output-text"); const outputHtml = document.getElementById("output-html"); const outputFile = document.getElementById("output-file"); @@ -46,7 +47,7 @@ OutputWaiter.prototype.set = function(data, type, duration) { const inputHighlighter = document.getElementById("input-highlighter"); let scriptElements, lines, length; - this.closeFile(); + if (!preserveBuffer) this.closeFile(); switch (type) { case "html": @@ -80,7 +81,7 @@ OutputWaiter.prototype.set = function(data, type, duration) { outputHtml.innerHTML = ""; length = data.byteLength; - this.setFile(new File([data], "output.dat")); + this.setFile(data); break; case "string": default: @@ -106,10 +107,11 @@ OutputWaiter.prototype.set = function(data, type, duration) { /** * Shows file details. * - * @param {File} file + * @param {ArrayBuffer} buf */ -OutputWaiter.prototype.setFile = function(file) { - this.file = file; +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"), @@ -124,7 +126,7 @@ OutputWaiter.prototype.setFile = function(file) { * Removes the output file and nulls its memory. */ OutputWaiter.prototype.closeFile = function() { - this.file = null; + this.dishBuffer = null; document.getElementById("output-file").style.display = "none"; }; @@ -134,8 +136,40 @@ OutputWaiter.prototype.closeFile = function() { */ OutputWaiter.prototype.downloadFile = function() { const filename = window.prompt("Please enter a filename:", "download.dat"); + const file = new File([this.dishBuffer], filename); - if (filename) FileSaver.saveAs(this.file, filename, false); + if (filename) FileSaver.saveAs(file, filename, false); +}; + + +/** + * Handler for file display events. + */ +OutputWaiter.prototype.displayFile = 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)); + + 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; + + outputFile.style.display = "block"; + showFileOverlay.style.display = "none"; }; @@ -198,8 +232,8 @@ OutputWaiter.prototype.adjustWidth = function() { * Saves the current output to a file. */ OutputWaiter.prototype.saveClick = function() { - if (!this.file) { - this.file = new File([new Uint8Array(Utils.strToCharcode(this.app.dishStr))], ""); + if (!this.dishBuffer) { + this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.app.dishStr)).buffer; } this.downloadFile(); }; @@ -227,7 +261,7 @@ OutputWaiter.prototype.copyClick = function() { let success = false; try { textarea.select(); - success = document.execCommand("copy"); + success = textarea.value && document.execCommand("copy"); } catch (err) { success = false; } diff --git a/src/web/html/index.html b/src/web/html/index.html index cd690869..a132aebd 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -184,7 +184,7 @@
    - +
    Name:
    @@ -216,15 +216,22 @@
    +
    - +
    Size:
    -
    - Display in output
    - Options for how much to display + +
    + + + + +
    to
    + +
    diff --git a/src/web/static/images/file-128x128.png b/src/web/static/images/file-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..005c504dd363985045a80a4f76c3de22ea506998 GIT binary patch literal 19378 zcmV)SK(fDyP)uo)N$$6Q^JTAj*IgmOKyC@M?>g&!?^Dm&<-hmYr@W0= zI`z#mGRuq6L@TenvJxE~9WiUxta#_0cj8^B-mz|$wk%V!%-M3wEf*w3Yin!FpFcld zc;SVZF=Ix&7wX%$ulGiKdwVRI{+IA+Nz@Wcr`9avqZ7@WH!t3L>#cb6%{K{uctniN zGGtL1nq_dGK7D+S$g+8sJ+f>>nMRBlF)r`lF9mo~mLF&NX_jw9#93L+%yLqe|C8m! zEML#^g)9eVIXufh=Cwy;`E*3=wdk4KXW2Q+`dK#4GA2vEEW;MPe^8d90ZnBU=X|Hr z@gb!5f&i;#`MWH?%<}dkh3G>ECQX{OkTp)9K0SO+o;*1oeDJ~B)3R3|G-%MvW5 zt+UQL@#?Fu#odh4w> zd)l;VtG2bZ4gAPQKJr%5x0aMtRpuRb`hkLRC%KBi2W;v9j;!i5VViqFVv zVuKAfh;`Rp*KzKJfT4}^6e3=H@x@3XM+!GajT#lhhY#mU;+%jP3(4kKqaKHgK z-f_nrv(7v3ysIh8A{TX8mizG!k3S3waOg=Vo%9di{`R-$Tz>iGhhi=PC!7;}B(xJ8 zYb7k!kJ+URgur@Pp%QDXu||v=H_rV~z&RG}IszeN75C{FWq<(O0&9KS-l)r5uF}vDR8^d8X&Y;K76AuYdh(9DMM>lp~&c>M6&) zFD6c$=)R*bag-D8+qHRCQBl&!QaKqmGgBg6Bb-NYsmrReXA^7-w!O;mW`M^{?aPlTV(I z?&!7^UI9|@vHR}3AOE8t{pfo?``OP}1a)fz~lATUw0ox zaSi4Ywok_>8@MKH_xt1`SRo;~pTMg7Spugt?xj$K7TL|L`gmU;^`e-R)-zo19qy-0 zgia}LzWHW#p$J?LC4&Uo8HE42&wcK$Z1?!jeC9L5d%FU(#gYj__e+0&8mqnGh8w~s zs{)+_SFkGR!gvhD+zmI}5VHx*bp(N_<)a;s3?f;#bDqgc37UW~+jq~5^ud%OvRC1M zXix%G#14c>kgh9BCsg&Lc%JDRiXzC2wbx$TwTil96oqt6WROc?)sd@;Y`-=@veyG<|B?c z;^Ji5(W&u~T|X8P_uO+2BybG@iq7NVhaZkrS6vkv5CH2XSXM+S2#W9t*7M7^6D-B? zU16~pNH7$HP$-jU5WagWvL`@wcHFhmOcYA6NHCtM?)4l>;d=M#zM|@hAkV-4`s)dt zvcxvqY!g5E$xmD#yY04{cq8`PZ@&pyw<{y!fQpF(ww~|Vy*>{xVZwy?-S2)EpZLTl zcFd^#j*Bn8II>TVNua-&&#L3kfBrMbjqSJJzOr=HSI2w;#$bYCY3`v27$vx4tt`$b zfm0j|^$yRC#SsOhMBY)?_^y7QGe=#z|SPbO*9SdGI# zR?adBl7%_0zs=VZKEV?-rn6>3#8`p?r=H;$)L@04;~oJU7vVc0u_S^dtmsnaZx93`boKEb-@&_h zpxILE9qOR#sV$xZWez>`Q1BlYTyTN&@%`_AKla~$f65&9-FKgQa1o3{pgj1y-~H}v zij#cn)h?hTA+9|$Z0iw}KuHgvQoJk^aRC@X2xWDZ^Bj3<$@@d z;@!H0uBp09E%WV=Ov)H)v3xM^7{xC*kX7%S;j&l@8tUx(-*kK3Eq6mC+b@N!3dpwU|!9HQc z;)vCHKTBs-W$An@1y};9OC_BsnR=INq7($qqAN2AjVi^gXQG}2N^#;#U;2{c6i#3m zpZe6Nw8?9R=*2j%8X>%B?;Gu@`V_sKTL?2&l>dM z`92I}Rq_L1U;i1ySa0>+E9EMQR6?O>e~a)P<31?O(uk1V&x(E5Q}LVqd-Ky?ol2;rSvVZ|7w0F+9QOkoZ?>@bNSu*9-<$?{LpgQ*4FEunz&krhC(D6T*N zSSi;%_uP|!6eDu{B;jKiXmt%n`p(+81Pmn<2qGA)0i4dT-&y#TPIiC17owC^ch8{! zisw-x^>Pdnskb^-Z^8BMb*{!72;KRLdzuJBQXuz0h(n}N@VBQcKpTx;3XFDO0zqj! z_+;rUgpWjy-FoY-EQGJ*4nRLk$87!{!zn{>DK+r}dQ_r_HA0!1{J}Mp@QcdLu-NxX zu2+hxt12d-P`axSib5jKR&Uo)SV}?o6ogVEZSjoGwAEHyF&HQr#~*+EgtN~++YJL2 z&19O`BNc#9mS91wq#=3YJEr&~97@2?6Qr&lYpSFQ0kd@1h@KsDEn!w}-v0!kpz1qQ zNY9rS=-mAS+n%|s1iC$k@I6cV+It%VF^j@Hk>nKmXlTtSiK6NJ7dj@{#I%Xhv zK%&8Urn4=YWO8$la{-vXlrj*rd}rbOy6+&5;K4qt7v&>NtuB~zu4U;M4MD^JV7DfK zpi1&!s`D%k>J&j6Ykfh>kF2D1ofQ$ z^br_~CFmMTb>49nR>F6G`FsLt7CvEk=ld3ZwWk6}-)q3Cgsz@~I7Gp{mlX@@_Q`LBIbsUEhVG^|6F!=$Sup3He?Eaclmgq0 zbykE-NHzS*CD3+OLP-$lbgr06xZvG!!f&z`g1`u{Nx3@vYrwU+>nkQJvmYVrX<5_yM@ZBd!#Bhvl_ScnCcHIX> zl(FU_5UP5W@M{QKU21Fq>{AL+y|DvAr>GPbDzNgUkxZdBeDj;%ga~o?;fF(mUuL#Y zrtto54+06gsbGG6$0S0WhZ+2L&CO@UAdv9*MFF8KntL!65k98sO7V%6VDVYP$4G7h zGBgvk@%-hHPp_Ut%?pGu6%-PF#W@l_>Y!Z|#xyY&?SAc7-YaFcRktwy@|V8|lDUK- zIhb^nTmg^Ltq4F6i}PVs^m;0|V+Ar^{uixd9KT&DVFDGzDHud)n%#lt`Ho}(F;fqr znZRz%<690?2`29-)KUMMhe-JdNqZ@@_F3%0`UQq2hfrGg$KOKcN__q6UysvHJI%eu z4o0VfZJSxc+ZL^EdbC>}?H7B6l z1`;$@YPMMcDT()D{_>*AS9DG}3x)|_AHK4h+EQZ}kN{t_9WpF~YcholU&7>Cqm29R zyYD|F8l01B4_+60W_i5J6+nRUE(oBJgt7+auvjrc4FnOsJOJjHFu_;4$F+|0x2~(e zkk*%CU|=l(DRPd&xo>$=XT+o2H6KyixGQZCvru{pp$(Lx#tZm=sIe?`^wCE{7^o7z z_{A?a&3TsRX7=!yq_wi!xMf$z1#RGPDf#qiDXd|j8}lFlYmho+(O?lXJclAc1jL_W zYWdv?7;8QNKIfT9}4otUZKEs{B{EP}@kfmc))a5|7kOqSkh+@)h5~4JO==-*h=j&;~^TE9yfC2#u0tuM#O_X#@sg<~_ zhxKa=;p<+3`GS71Um3@qK<>q~;{oBh~+n8Ttg0aTMMSi8|PRxB{&B3vUz-~uF0%F-zT1t`C-xUYv$ z)vtK9FQZ26nhlCr>Nep3%iu0W{>5_#gwW$MU3G!H11$|Hg z{P!Rtc<`=X5Ujejlw1#{ge69h;;r=r&;W!lvm$ub=Rf~>E3xo)sEsQ!U_LVIv7kHG z1q{d}#oTQ8zvdFBQ?I-3Iu*1sR`kk3j0W=W1S$ZmrPQ^~-)E(lDMT&T5?fG+=t)#L z3P=axq`Cj_hd)q=iV3804G3|KRs$`UZtGcRoh9h>PBFrc5ph>{tqT~GLY|v*-Ctwv ztY5^>5+H&;KjyG_zR`CRLkJ!-Ysl4izOH8bRDZvRQOy;ouCMm^6xUF6&}@8PexMMc z2EOoyJA;mtyB3JzMGZAqV$E@-1mhi0#&gZ4#>>cVxA=gBgz1sF?=Wk}p)u>WNe-=;q!Hg=UQuUcD*3Ypjfd zcvoI|rQQ!$M*;AGOXLc*+r2fET+8FjKxz(T4I8`9aS8xMtvFga_hD+!RYtY0q01HE zt(@!LKNmZUlKtZ2HGoA_4giB3uM{qbRMA@0iE+-eAXGDKdm^bbWv-dO1^wD4LF5=; zU3&^SZ#{r+qBsCL;uAv=8=)E|cda5$D5|06R0N;qABZt(rxMSWqJ3=9q?~S101fL% zs2ibC`oA?XwAS6#QY(zo6$E7(%6bSJ8t|z_?(eBodl^yW8Y-?O>)>9GhLT7Vr_)4&)i=aNei%FqG&G)XeOPS8DdKDPn|JJt0CRFap+AN>6c&CvcHI z9Vc9$y2bb-eO?K*90Bw^3gmjmV_pR}!q}`Z8j|%Gll71f(Eon6tGj`A+#C-DSTh*n z*Cjky<=K3-#Vvo}2w=AAVgiSP^$x<+C<1n@QkN=Rqk>>g0OPy}R)Z^@Drl_r{JoVR94h~h zw4e2|{Q4g;6bK0cD!t5gI$x`wz<;KA8CY#zZSe?x8C$_G=O*RC()}sI^4yfV4dg6g zqsR{FN*b;48bMoY)(-|~44+0B2wSXB%fYIf$U0U8BFrL4SUZt++MZ7Sqw@Z>`E^Y; zku4Pf$|~ZSUXwh5^Nh?hYp=o)zB4Y5_j;ko2i_(XZldP>_*is<;0yjKMO~w@d_AiN zg|#@eP{DWoS{m&gD-tn;+Rw0gP^YNeL@gsLzUej#jLj(!C>mkq9(5BL6a?Tl1%YXJ z&u0p~gulS&a#3m;xR{kJ1^a#KcYz4CR{54v&{Sgs)g|Qfd@p6;J}AP9Mm3kA7MgY< zMxhiU)NW;9-Krqyh(`iHJCap~wUSBI&7NZ0dbyY^;(+$9>ING2WXVd4%GUO+l@;UT z2){OWV(DT4L;-52@7gkD1tWqb#M)bUX>%&^#C3w?LPPry%a=d`h{2U`4NyhV8xS-> zhK87`%f|w0AxBl7hN>u{41`Pp^n2yBX*s2Ez3w32?-?s9X)hvRf^Od7L`fn@DCiTv z>O7w5S=4qpT!r%%)ZlgT(&&==->LN%?(Yf(uo!zGv`c&mWx=|_u)So3#|MO|ccT~&ApaY^56bNIK6^$yvqtp=c5~zNa zMC8xP#Z7oBIK-z)oN)o>%x#dz9`oF;oDX1u;trXkmZqGpa)KBC8wJ~Gr=4oUWGT`5 zX%~H5-96`O3pr?^;=XeUzQ+noe+xwG-rgphk<$UuA+u9&0Aybkb$5jJHQ!a0BL#!foe99ZqA30s{7U~z1lHd;9Qwf z$iOu~PyDLIwGVdJgplX5j7TA_%CcECjU-&jo>Nafm9T5dSM9s6AvGbgx;+JFwHi1+ zWYk&sm1Ha9!7uKUdo0APjN+4N^|L!+OtfvgQ!JP~DLSUTx?INs=E!%XU+Mr!^$Q`i zlXVk*EvE+eH6Oq+=kx?h_~5NJhWrpx15cU>KV?rR=g8@Ue|aSS{k-$z*%xx!SSrH} zx7=F8=d9n-Be6xJvCpwzi7(xBPaJghEpgI)kH&@5=EQH?+v27*H;!LE|4Q`P zb?>;~$>+Cd8Nbn)?VE11N$a=`1{4Bxl?#w_7RFCzx!|3pgDgsbjAR+<0$ug1AX377 zTag(xM$l?T&4+=s(~jYOONiU+KXh1J{pgeN_G)WJ3>zLD<2FgIXQF4u%xDZr7+R$ntFt-Epmz9UvYz0um|gm`Q2UG4vM)kE_izWB1xx`9Twnh5OaGS-TsLWUJW0r>GkG{|T+(2Y4U*L`y0H3y+S4(MZd0q#{uWVhEW+S;PhNqho%1MBjeVVTids z%k*ikiG|NS9gTs5V!=ayx^(`1cOJ$&E8?}~F(YWcZVV*Q7uBs3&`AOjer=$@ML1Se zqh7T+bZsoXB9K8Fe2}u`-;H$s$3+w4l7}9R0c+=!?>!ER1^xO*yfr6UB!&9*jh5l* zNfXjT3^Xr2E8+J^;WokpA%O$}&5DLX$==DVVk%HeKC6+66QkFNj=Z-qBqy9c{&2KT z*yE6vaT~PEn|S`QvbM`B2y~9*>`ubYT_s15z?vn8f01YxX6L z2nv$K7VkQk(o={#^Q#~dVsB@?*2(dX^E0r!e3h}$dcff^Z~I-NF?dKcX3vTi8((~6 zWV8_8n=>O)pbY{|C~ry24wgM9VLq+9@m3D9y*f2w?rfGH9jOp4tF4ju4otnE7-@rv zAdSdu;QAXy+m5?M$E=yrw!^Lm_5Jcc`$hA8mX`v+I6h`%3UEXDd=Y=``DZGV9WH8v zrTRq>6GO!Y`nR{Ml!ZuzHCvd3$YLZN2rQW9+)|f6qEQe)Uem z_S)n4^k}3@Xk_2KCHX@USZ}1jL3WGZHcIPl$b&Q@&*k7y`uNr%!=q);kZ7eWi3*KW zjuxY@84t7!9u$rKD+w5*1A3$@S@_!2Xc@3_^xN;?=$MgF#<&f)>38ID7e~MTr$oe> zu?)1N+^o?kiT>xZpTBtqf$Q>pX0e(G3DzquT;txgJ-lELD%9`pDa}OSx{WpIvh%)u zrcFENcy|*tQ(t2qlV6?^=Rf^Y{PSt2$JEWXi?-eNCG=>_m}bk>i2e!fc0oJv2e-@?<)rAOPjn_jN_Ud)f)i;_&nBN{QsbX4k`Z~g#rYp(1|s|#Bq`yGDU2w3CJSq#`py3yv81eip+wJT;%~2rfBN}<#v6Wqc8`6d zH5DM9pA6omX9!ZjmXfi3@3+}Tmd5m5IysBlsHoi~5>{RV;hc6P3O zRXmq4|E*l8xEZUgWRMv{e0NR$ma0@OG%AokP^l^!L?H?hr6kahl_ey>#92t-W-?FwOZIJe&0Izomd z6c?vh`I3}T{IBc{AfGk_Y9fGBL_pxPgL<6jkYmI-(R6m9d*FPGLx=&}Azs@M*C!Lw z&f;{gC1w!a$2~7YSbrobvQ;YKW(f1ux`8w>ez+(>dY`5z-3qredj&Cn{q@(Q+X0n1 zZV&|%AOIZ$k>g$<3W>pY&zU0x>UD(Na+dOG2T(YMN+3@DTTLCi{((&AXTEYv_`BP_ zC&NnxF4x}}($#B2W9JJY!+`4)fv4hXiaEP`LfRu+U{Z#hbUkVy)TeV!PtEP@OAO~m zDN%xGA_1_W7Ba;X>VpFsyB31fOej@C5WzH_dQ9h3jkV?UtomLVe;Jna;r$5tD-J8q7TuRO6>S4e)x4UKl1JVmYx~Sr}x!G;~^p|c9 ze}C6Kp)oWV+HU$(D6i8ZSHIpCGI4k!LWMgU64#ZJPL-(FvyU7JK`J1{*vsm;egFx8 zfX83B*a*+hhiPipPbC{B2r{cq$UUqwb__VxAATTAKmSZpzUrE<)px#l zQ8qd}{%Qzdy6K6Y#mJ+S*-OKD-JK=^z+kh;hl>G}urOTj6+{3VfahBHkw~Fe75%N( z5ZX2U*KdC(eBtf~B$|$ewj2L4q~h@UlaB$Mz;5SHwBXZq>oLl3_mB>p&wZh7>aPcYYqQDH_us^ZzF&4&2N1x+_QI3ppJ&hyWbnZ&vrZ?8d&KSo-d72zC=VV zE{lMs;!J(O;s-cTMFj}-Hr%^tE2Na#(@rz0YwC}h& zOy7H_CYGdMX&e~%Sf(+_Cvf9Z0zn;34GCHW>ae(??kZQ8e8ai)%!8W&3GPR)J0{=` z;Z5M%@&|mY55V_Kn3+iyj+1CwN+=mZS}Z-wc!0lPPk^`x<_?u%{qB_^Rpbp0%E~Pv z6LG-BC5ik*FP(61^_hBF!wi0 z3S3WS(ePUfZR8|SHS=u_QIo!&Z}U>NpZ%vVhOvv^iawXve^wxLhQ?Gi55;cS7=88> zV5f7S17MdDto^8q6WqdOEA_V&-MCa3RmII!fqYh1NBF^or-a{KwJcn=dU^QP`CGzy zD?7s)*#;dNqo(V;MfHJODNiGCyk4K12*@9#N%T4t5JGLldsDfGF$%e9%ReXFtH@y( z8J@Y%NdQ9-fti9`b^b$eAvzuK(dPh$$cNLd^O@FUv5%C%Aem`89>bZ)Lj`V(2~1?h;E{K0l*rzs3V8JVO3Z7&+|?Sy#o8e!;+xl{+>!Hyj_H_ zp}jSXilEBPlHL)(atj6@&%*cF##~b9f9w#crch}k4iTf0Y4BhMh$He#UI(IHvGczmYoN}xyw7k zod-w4h*ZHU5l3Stz^H&Ug_{L*nJ6KWGzZ=U0Ebhj0D&tHQJ*-Lhn0JJ!}R?>45f2l z|F5gE{H<}Qw z=;8#^U4fp4h&>^<(S`+HhpG|PQB^d9Z*Xb?_TUlB7>O7>0Nl9Tf)>cA z0DO4}0I|!p7PzZDqL6y>=XtoD=-! zg`wx#yb>tt1G{7b&RBZ_CrAL7f9w&pN{Um@7752?h9!HSdb!5GB8hdq}ZM*4-Nox-4>28RM&{ z)vHFgFCWihg>TXO7@%%cHJ9s%#Sei%C|;mq&N4H%Zo^>x>0{f%&tBdi z0-_w9&T~Qlm7Ew-NrvbZNdHG)-$9u|JuJ2n{>9~M(_a95erPys9Xt|tj8(%0{puhB z!;DWV7JzigqW3s8->{5PX$5=}g+Oj&T&UlK5$%Fh%$6+grj`&pMrq_hq}w~CvMzwY z^_P8K0&wFXP~v4H1ppsQA28uyfOq>C0}2=0eWQjB{c3Kv7>7_CL_%r+6rgc@E?teU zPuLj(!NBx*-b_f`&-D=AT-=X(ffVBz{S z)DSiaglH)s?k*~f9GId2g?Nju%>;bul+!6L{@G5b1tn`4s=kIZDUlCM7xn@Q9n=Na@r9EBYBPXs7@9pmiXLhwmFJQ4>0ALJK2b%15CY>GHJL4V@{aFUF z6i6oaQbJZ~X?3`neX*GuD-g*TWr%%5C-d3iL}%~dNF)IIo%0sq6p$c}?Si>!1Yp8> z5Cf8eW89DHH)F%Iz}n{=VcMD3S)%YfaJ&g@R_?&jNw4hTCeIM-PaoZyGc_(H|Ed$z z@aH;S<78yzIwEnnOyanv>6K`vB^59z8)Bo}zz=Wi4S&3$H}puwux%R|58qWBU|fKv zfV+5=DxA%3@Bua+w?qI{zT?KG^e)7y89oAmi_j@q3hRoR&qWEKEKaUy2Pgpb^02nF z;o@eCpF&YYcI4J8uDGI^`?=1#+G@g6%jeSP0ER(_SO>(JrD6~zMkpN5bGW7ZtS~Rc z=S84>-h{FLm;l#vrHYybSNEh!`Vi)YV~FzE)iXS1?Imz4Is9pX@h2zthA+KlLwHlq zvha!sVgS1!O|kyvDk?+SC8HWZm!w(}O3r5|iFkfQy8>BAvMed=gjk9`g+WN|Ag#wP zUd#yeHYO2&OfNa{T0e+;fB|fC7QQqH zljxjuoB=nmi;96H-~rUb`i{2n(UbbZT8&NAZ^tpUomFsXiz0u+QYp&>KB3`Oac848 z4MD)D3vZ|;3^`{ao5T{5E1MXnKqMy;QrMcDQtDrq7p=VJoO9DP{pVt?ErkGvBr+$o zl>r+Lh6oVH*7tVz+|=OKTW@s_9P~GUqZ$AKz|h~0AR<*)Tiz1&w@8YRb(cHxs9k! zc@0An{kOg}5R*NZ^=eTFsev(p{M=X-!%r@v>>;^|4;|I2BRaQUwgTD1MYl##HlC!- zUO`U8+QURqwpO1CjnR=@Ye9E_Gvl>-IAM8vc-@N5 zm>4=xaQO-)k~%~nuT-Z(UBB@=%R0g;1&F5V89%us0>CY$E`iV9;)5>0D?;$6ylic0g3qGApizq+fsoz0HERTJ3atF zoCCb58tkHxbb_#OIX$b`8@~mS!1*pNb!M@N^BJ3KuvPetS%xFWkwnwuqdE91x-s^6 zQG`)#Oko(hEPHk#MoR?`VP5=^ki${|@7S;^e0b9u8G^O2M+u;#h2=e^^EH7zuDwNI z^|dNFHl|fdL=f$zCHj~=7sjA*%vxDwDgjuZfV)P-~Q5Ej4!GMqaP z`0lX>$Tl>Q7>vVbr=Mqm4>%BXC&eBE`{4?LCV3_AR1xP#U7-JA$K?1Y*5T1FE2m-S zXf=FK37>rvHL2r_+=uE&SjsOw1o9D)c z!S{z)Ma&RoW9%q4PrKp<8;nqYh(_nMR0oFSmkJ;97IP!N+spUgr-0828T>J)Dn0>Ny735wog(AV6Xk zNS6Z#52&hFhT)+D5#$8XNs%XNpzK;a_8Gd~m7EJ8RZjDy*>l6k!q10B74ZvEHQ%A|ALG|elt1#K*Nl$4RL&xTmUK{FGel5a4aWmJcu*SUYl;*Oc6!j zVg%5pm)ULo4>0-;*8x7q;9h14!^yVt;ZT=oaV?x`slX195EKMJwT?TB04e~vM9i+G z)rUEsF(4>Q6-y(B>D0m`Ldpi;^V-9q#`)a$)za|F)b!8|Ge zFjMJzBzg-wez=alG+vE1zzOXw`do`u!Y7Il7|X-Gs)$oLP9lZFa~G7)6s_Vdj2uPX zd9q5sJRS7nSh|GSu{~~M&R;h^25bN%;KOGYPJnwct^gbm(EX?i<`odfccR9 zrk=<#8)Ux5BFlvhz^aIOi^O}cfR6Z3AfjXIB$5da6AP&6M86V2y*d{1b(UXce~%;w zUA9Jo;g{8O8zoIh2E~2@L5Zyl&!ILIXEZN`0BV2==m6wJB5bvr^WZA00yq$W2ncZv z1VQz%MYh3o)X?3=0p00dW*76jT!UnR_}pp^(akdeI0VE!2A|(Yk~9~9xOB}i1sje? zh$ zCM0&pyoLaric9D90N^a0r`p!*2LceBOxH^Q0SqLCD}ne-ln*I_eE?zD7BHAxi_~y6 zPxGuJI2TWYN**KL$(TE?P4~wgBM;+`1W;1K zn2n$7s5C@B#8FkPplTX3**uNspRO$_5~$$M5p4hk0RS+dxP3ev3fJ2GV){77AT|IX z^Rj)dtAG*ZWaBsw@SaYN*oRx0zyWBe7RL4(M5qS}jBWaIabMH>Ozr%G&KF#@0t zU^yZa3E+A?fI+n54IsiPtb`*Gw^v_%wWo}8Z3Kr6v5sp7(16e8G&0A%1S{%;F`LWE zP!AZFs1JjU{`Nu^NFUUYH%lG|kX)09xc5ZDP_1augN+K%Jw2ACCL zVQ~s-0E3U`qHG=Yz%wAx@=`JEjNwBxqQdU^CF$?Q2;dCq?S?0E0_{ZQ$F4B=5YL>6 zBc7e-1i>d*=KoUS0 zfYS9@tP|WmN+>uBr**aQmmTBcIJ|%a^c|)KWQs$a8H^Q7S*d~#O>F~_!Tc0a!KumZ zI`$yaBVA|i!;#!jsqM|t0YPz%x695tBXq2nVYGW^ z$kc{SCjlNqiHI5rA$>kpL40O@&f33p56pFm4 zb7UToK&3QUnkGmSfQIXBvlL!TLM$Waeqn-rgET<3HPmA`hP+2d_fzq`m<>?D1`wCD zxmXjBFvJky7Tt(staVodyGD%Gq`X!dKvI78B9=cDEgjb5FskS=NTU^ z#%Sa@h$ncB-sa8A+;Y7aa^kzU9({jzcY7Wtz5UkEKoVdm>6!*y)f!{%ytF*imL()y z9C(Af7FE+V>G_LQ7<#4vXM@|@%W2^WG@^8PP^ID!Sb97z04gbsKM+H`_98MdOol{s z{UF)FN(D~`Re_DO1`WIz0YKJW;{FOi@$y}d2dH!dK?MLZ910j1Zw~JQy0d)%hD6{x zR|LVe=zD-QVKA;2UVvZ_=Pn$v;R&(u7b$^(hiJzh!6raDa6RX|x!XBoUE zjiN?HgqQSm#o*7Fa`oq}=m&; zrpF#Ho{%w;0CA1aj~hqXIEEkK0TB0jT>^jwEJq1ZK^T2_3H;@m7#DEu^P@T-RK}qw z)$VHJf5p8y?K#Rw&`V8hU~eg5tGrPt`F>|&MtSYrgAQV+cYp) zHPD#1qlY83%cMHC9vutc9~cf#$@u%g<2%FU4?iDnA2_0Nu*2aWpW7F5-vga^Cig}-BcgFk2GOiuHp9`G(zHVJBE|mU z_um;Rha}#m4(g9Tf)NGamMWSsy{-};+bUmqX3R7e$q2LVyXF1$1u0iLzH5{TAPJ}}_&UqJR!exkifWjSv za|r@L3{)0dMYz>GoSf<2h73Nh#}6R@5T$5|j8F&+fFVG@hhV&lH<3Xbj_d%6=RpH& z#D7U+CE9t0MEAAINKJSq7oWEfO>skQI^2LYj&SFelX5a|Kpaev=5 z@IsLe=vbr%(g0&IR}an`5l~Up@1Tsm$0X`ktn3J<>-!Um4Uh{cEfxUew{Yq7hnz(Q zA>xu!A};Vr`cxnIpU~*&Ap{)odAEX>UPhxb;;Lz z#L>5X?sK1mW8gZsenW=?vct8G=R+LqfD3V;8UPC}M@$0>q8j1=doJ zZwq+DK57EB0g<@<9II_YXz}<}S6$^?0b@EV=mwP#Mtl~C7zu{DVobp1Ik6qEGZ>pO z`Q7(@?Bikk+ux(sYrhIXV!kBX0M09I*c3!Tw0VufGt&!a&Hx!W=HH1e3yZuJZe`+V zBnX%IxULw|pce3mO2PcSj98z;(06i*BoCZSOdppHiIWrwtLdH3hbg+OoO?lNJoa$N zAV54BT-aazB4oQ>JV?%?@#NN~ves5JG=N|e2;stnlbo=>;cKmxd zl;8}+fl&r`1DqR306Nzp#vud;a3B!Z6nfe?W7>{jP66ZLRss}ig{oxF>~RqY_X0Wu z%KiKv&*(|1fX@!m;*}t|03V{Uhv5}aX>*UX`t&oq!tM#(`{3Pb%>1UjluGSc)6J*m zp<5YjNkyK3-b;Poo|sWg``5!cc@z<%fFnDW!F%o|5F=dgp2jXt!8pWNj0Wgk zciqMK(bb(&Kfo6!YRtZ+mQH)0yn`o^2)SASAm$DdYwr{AbnmQ=Gid{E#V^M`$Rl(` zlSjm`!L4XF_#AUbFkDbn2znmBo%=b*akxDjkR|`hJ{nU+_ijoZLW5e@g#CNP=_>ak z&8uf1gZ*ADPLsDR)icI#%Ub*Pfke+!? z$Y>hH>}WMzsHc(ydckFN45u*@aRZ`xr~rropc7Og6}m*|_>M?VnSEUBNtzRf_Bb6K zZl_HgF$Xt+pdqA=H{fcDJgD=-`54$6jlPD6BD}CYWRg%>zxE&hAOspjyycyt@%?Xq zT5x?)dyn>`Gp&teF0E7SQv&K^GLXIu_tS{Ui$uZU0P3{>(8GvW+&jQVT~Gr6r+JNG zL^|Bc?samJ9Dt6<1x)M+&-%4WKvKZnPDpVcsex4C9(Nsq&}^JScn}3(I%DZNhM9|D zBi$T@g9*D>uV7dcE3i>q{62BWS3mTj53Ru825@K9 z02eMo6vL6|bgwQBut)&74xkJyA{Xv+ix>a{H~?Z?h>3ID=WF16>vF(yqQ{1&C#iT^ zx~r8L*WF4W9@GQk9q^oqw08qhGKT9Mn>(6D!W7qzuiF^8uyp<<5!{l90YfXclbM{L zQDjsV39gsgwXsqNkww4-(4?MM=m0Qv$|rmftfDVa1J8hp-))buh5-SpuQ%@d;Rki=S=#a0tBchXp&wQjf5*uL7DRBd z8bp6d%fymwfs^4-L@r$8mT&;>$r*rv9(F@WbhHyRaHa3#JRqW*9ZPUI7$Tl=;Z!69 z!~syA{mXX~fR7twjL`i8xTKBa4yY5Yj=0zO46xn+Lw z9!kK+V~cxBNx9sUzVY(TL=6{+x~0snUB4;MwF@|OZy8A;eO({i5B7Q2Fx<*C0-lTe zB7p>;Q8GZlQ$;+VNaSRm+U0Lu4XIp|Lf@ad!q9XsrKGD7UBVi!D4oj*155Ppsj7$2 zpD9T7?;^Z@QPF;bKOX_~6t+NL5gt5T{HOnv7gM~HPF46^Az-=%KAhz#Vt{V33-}!4 zGu#8`+Xmn}puQq8d{kW6D*{+8;Kn351_U%2$3dx;qdGq&X)#dK^ln7E{(06e z;{Z6GL_^oB5w!ju!`{G`&kf5W$IoIDSkvH2cOkF?-%G25#dbj zFIns_L;$Ob6~ou_A1o;UBJHOZ15^u6I4E6zxpe#aa+mg??*-0~45ya_VpZWA*`kgKMJgVP#THsF?AirFI%=gh^+;znmUJof{yy93={DxFNdvYR2sME~WBhFQORQFsOOXB(l%N{8Bm4EX5BzU?XVW7$ z4aV_tlF7Vfx-Zb#ZI@k@r64%aURtC|2yx+~aNvt@=A$5S;sbD`96*4811+#GQ($Ix zc4sCp6JxJ`BmP3P+Etemwe%>CoyU%!_au(Zn6`M`yS(TsGaC?S#GrQ|P|f~<_Z)nR zW$3cQ_(+)7W4qbA)DK~DEbl&2n18k+wwzm@Pitv!PI<;aPN}!lolw_>*<+6<_niQ# zX#SFZErd$QC)A~s&%`RUWd-$haE-Y>_|P3*Gu`ZVbm#uf#;tw7xMUE7oxKp?O-AP{ zdYG37{)f}>zg}MWU@a^?v%V1?@BHKw-)+_pFN>T{H{SRARXv6W;g2OloKO^w@=j0v z7r$QS_b2++G5=%x^_QQ+#~OM>(6W4{0O&Mi;}T3Mh#X&su(!~jhYk)so?NpFQCbl4 z0Akho(d+bQ(zvlV!qXVXRrC~c7|1{un&Zc3Ge_lLlS4_ojys?<{o1en&4@t214bWN8nTtGee_G(O^qk4US#f z*u}&>!p~oWnU-sf2w*H4UyJ6)B9w-F3>fJ%6+yA!6x6-x;Eq2B?`<=<@m6&AUdQac znwit-qMlBgrknL_yAz)O&!=oLC#WpLN2N~J`+m>Z@NIt<9vvIKelYL3WBj2b`E+#Z z%4#=j>37F)|2^MB0Sq1d22GYgf^tn|+(!3=yy!|dsc6j&q&|WOC2bhhTIs9?Qp!q^ zKoXhnJ?|pVbz$9t42{Q zMR{hJ_@P+FhgilZ4!+>NjRljzCSwTM4S4bMxpI zsg``Y%$002ovPDHLkV1ge`(YgQt literal 0 HcmV?d00001 diff --git a/src/web/static/images/file-32x32.png b/src/web/static/images/file-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..884bf4851c1adef7191525b124c246db6ff48d80 GIT binary patch literal 1946 zcmV;L2W9w)P)OIt)aMW!1`|0{S6A!n)~$1_UAq=?$JEpm zgJIRGRd6^QAj-F88O~csO7^2ZAiE*u02zcfDgwS4`eQ)=qS$ItCyYE~ zv)Sbdi0sb#`g#%oQBqO@Vt#&}S(6my<};j5CkO^6f&4WG4jjPo!GY|vjz%_OmsLX>054au#6WG6h|9UCITX+;0gx9`(`^E+b2bDNnjgOD3NF<^r zCnwdTAnK@*kr8$9;6Zit=uwrAuC6Y%bLY-I^7v>4_*)ef6_}o$<})*<%y<;24h>5` zc)ecasZ13|wqna0LOni=76m}Xv* z0Oc;Hspx*1?FnF;aoe_S%$Nb$v{*tW!}82XpK!@mPcG#FvUQ2%_70H6cw8`0Yilc7 zT3WDq^JZ+{z8$r-wNw*#?%d&T8A>S&4}m=kPM$oe+S=L>3Pn4{A`)4-H+%cS7i)1iHJsReO6o39uK~`}t|{LHAoYfAP|PS~hLkaQ6KV z@%g{5E;$RPr0*9~Hg-Rf_m+{&E#&8`bW|W3xMz1{em%r`D@W6>BOR#tE z-V4&hU#9HbJ}XwNusfbeYG2FYKPzd1$c|-Qn*YV)<4hnrr-JN z>r$J$ixr@2H`1{*6tm~WdeYG(#WTTj`2CwFapd#sKwUjNTV8_0=|slL!c>5Ug>I{U z{;RDVU?ms`94UfjOLa)6GI8Z7$ZaHe%gh+r!;za@^v)F7@hxpT(vp90D4`^5q z|C%*$NfL3>frMrvDl=Uawy~iZM$-#60Z9K3v#qlJi9~|?ns;s` z-bu)wjs(l3={mk1x`xgRp8+p!MWALiG_McS84E85OVQWSg!+IFF=fbFxg;5#BfWmZ z&$P0NSM`;ve=v@xDHA6mvu4|5=2V4u5@AphW2v}9G)n*OM}XT8uN-FJ_d_diBC9mi zI!#oW8ph)ZZe?h04^%n@q>^wv-wHTgU77RmlYouNTeoh31Bpa<+~RyE!ulR0ILZT>dEm6cTf3{4!L6H#V-u-cTtL z$uyJ(k>3SP%FNzo1Vhlu%6IB{6HU>849+{{W)n5CXxCW*z~^$(Ah`p-_kpCkbY22c;4$2iFiz znjjJ9+68%`V33GX7)c~SI3ze>|K&q=9@cyY@C7RKOJFc)&U~!5eI}s%R3`rrLbPq# zgu0q4SR?=CUS9~HEbx(>?7%q^{77=Vtl1fM%?UkkUprWHnr~=mhyiIv5(B@}_4Eb5 zQH}fe?x_N=PyM=S128&*bk>5FNkhq6&ErB?d~iej@kMkNgl39|bPW&_W_jSfbrUK) z+Hbew&dyFHrxwNzxL3fL!&h{HS_`HX8`sD8WMT!n&n`L zs1Rb}k?PVC+!!6jyW=t7wO_y;s)oT{AZ1GGCfu^#OwA!PHHmCIiuAn*vj6CrP`#I$ z0gRD=AHY^QK>St)kRchzW$PJoDvn7xQi3@tPeS~WmF$b9{ysTg4by(PSyI5e0cck9 z=G~50b~l?fbqkIcg?J9hO7Qsy_hH@s7Wnto9`*I`ZvaH{2U39E!qekLk>{$mu2Jc2 z+m-(6Yf5Y1q0rc(P`OgUFunxPf&~~9pB}(dfF7|Qb7}+uya1pMKq!}36aa(w1DFF4 g1CX@O13xCd2d**bOul<@m;e9(07*qoM6N<$g6&+S2><{9 literal 0 HcmV?d00001 diff --git a/src/web/stylesheets/components/_pane.css b/src/web/stylesheets/components/_pane.css index f69984b4..fb8f309b 100644 --- a/src/web/stylesheets/components/_pane.css +++ b/src/web/stylesheets/components/_pane.css @@ -50,8 +50,10 @@ .card>img { float: left; - width: 150px; - height: 150px; + width: 128px; + height: 128px; + margin-left: 10px; + margin-top: 11px; } .card-body .close { @@ -68,4 +70,14 @@ overflow: hidden; text-overflow: ellipsis; user-select: text; -} \ No newline at end of file +} + +.card-body>.btn { + margin-bottom: 15px; + margin-top: 5px; +} + +.card input[type=number] { + padding-right: 6px; + padding-left: 6px; +} diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 519b81fc..370c2235 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -88,6 +88,14 @@ display: none; } +#show-file-overlay { + position: absolute; + right: 15px; + top: 15px; + cursor: pointer; + display: none; +} + .io-btn-group { float: right; margin-top: -4px; diff --git a/src/web/stylesheets/utils/_overrides.css b/src/web/stylesheets/utils/_overrides.css index 36069cd5..23f83bd8 100755 --- a/src/web/stylesheets/utils/_overrides.css +++ b/src/web/stylesheets/utils/_overrides.css @@ -64,7 +64,8 @@ a:focus { .alert, .modal-content, .tooltip-inner, -.dropdown-menu { +.dropdown-menu, +.input-group-addon { border-radius: 0 !important; } @@ -187,6 +188,15 @@ optgroup { color: var(--primary-font-colour); } +.input-group-addon:not(:first-child):not(:last-child) { + border-left: 0; + border-right: 0; +} + +.input-group-btn:first-child>.btn { + border-right: 0; +} + /* Bootstrap-switch */ From a0aa363203a31bdb3a755156cef2b4447f086d2b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 02:01:17 +0000 Subject: [PATCH 080/124] Download filenames now persist --- src/web/OutputWaiter.js | 6 +++--- src/web/html/index.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 93cc351b..ca1f3605 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -135,10 +135,10 @@ OutputWaiter.prototype.closeFile = function() { * Handler for file download events. */ OutputWaiter.prototype.downloadFile = function() { - const filename = window.prompt("Please enter a filename:", "download.dat"); - const file = new File([this.dishBuffer], filename); + this.filename = window.prompt("Please enter a filename:", this.filename || "download.dat"); + const file = new File([this.dishBuffer], this.filename); - if (filename) FileSaver.saveAs(file, filename, false); + if (this.filename) FileSaver.saveAs(file, this.filename, false); }; diff --git a/src/web/html/index.html b/src/web/html/index.html index a132aebd..c8857ff9 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -226,7 +226,7 @@
    - +
    to
    From e81122739bf4a134a00734208fccdef2e2058771 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 02:26:24 +0000 Subject: [PATCH 081/124] Files can now be moved from the output to the input --- src/web/InputWaiter.js | 2 +- src/web/Manager.js | 2 +- src/web/OutputWaiter.js | 33 +++++++++++++++++++++++++-------- src/web/WorkerWaiter.js | 14 -------------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index 62a579bb..f6818b11 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -84,7 +84,7 @@ InputWaiter.prototype.setFile = function(file) { fileOverlay.style.display = "block"; fileName.textContent = file.name; fileSize.textContent = file.size.toLocaleString() + " bytes"; - fileType.textContent = file.type; + fileType.textContent = file.type || "unknown"; fileLoaded.textContent = "0%"; }; diff --git a/src/web/Manager.js b/src/web/Manager.js index 4b89942a..39aaf409 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -159,7 +159,7 @@ Manager.prototype.initialiseEventListeners = function() { this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter); this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output); this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output); - this.addDynamicListener("#output-file-slice", "click", this.output.displayFile, 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 diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index ca1f3605..51def0b4 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -18,6 +18,7 @@ const OutputWaiter = function(app, manager) { this.manager = manager; this.dishBuffer = null; + this.dishStr = null; }; @@ -47,7 +48,10 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { const inputHighlighter = document.getElementById("input-highlighter"); let scriptElements, lines, length; - if (!preserveBuffer) this.closeFile(); + if (!preserveBuffer) { + this.closeFile(); + document.getElementById("show-file-overlay").style.display = "none"; + } switch (type) { case "html": @@ -60,6 +64,7 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { outputText.value = ""; outputHtml.innerHTML = data; length = data.length; + this.dishStr = Utils.stripHtmlTags(data, true); // Execute script sections scriptElements = outputHtml.querySelectorAll("script"); @@ -80,6 +85,7 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { outputText.value = ""; outputHtml.innerHTML = ""; length = data.byteLength; + this.dishStr = ""; this.setFile(data); break; @@ -96,6 +102,7 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { lines = data.count("\n") + 1; length = data.length; + this.dishStr = data; break; } @@ -143,9 +150,9 @@ OutputWaiter.prototype.downloadFile = function() { /** - * Handler for file display events. + * Handler for file slice display events. */ -OutputWaiter.prototype.displayFile = function() { +OutputWaiter.prototype.displayFileSlice = function() { const startTime = new Date().getTime(), showFileOverlay = document.getElementById("show-file-overlay"), sliceFromEl = document.getElementById("output-file-slice-from"), @@ -233,7 +240,7 @@ OutputWaiter.prototype.adjustWidth = function() { */ OutputWaiter.prototype.saveClick = function() { if (!this.dishBuffer) { - this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.app.dishStr)).buffer; + this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.dishStr)).buffer; } this.downloadFile(); }; @@ -254,14 +261,14 @@ OutputWaiter.prototype.copyClick = function() { textarea.style.height = 0; textarea.style.border = "none"; - textarea.value = this.app.dishStr; + textarea.value = this.dishStr; document.body.appendChild(textarea); // Select and copy the contents of this textarea let success = false; try { textarea.select(); - success = textarea.value && document.execCommand("copy"); + success = this.dishStr && document.execCommand("copy"); } catch (err) { success = false; } @@ -284,7 +291,17 @@ OutputWaiter.prototype.copyClick = function() { OutputWaiter.prototype.switchClick = function() { this.switchOrigData = this.manager.input.get(); document.getElementById("undo-switch").disabled = false; - this.app.setInput(this.app.dishStr); + if (this.dishBuffer) { + this.manager.input.setFile(new File([this.dishBuffer], "output.dat")); + this.manager.input.handleLoaderMessage({ + data: { + progress: 100, + fileBuffer: this.dishBuffer + } + }); + } else { + this.app.setInput(this.dishStr); + } }; @@ -378,7 +395,7 @@ OutputWaiter.prototype.setStatusMsg = function(msg) { * @returns {boolean} */ OutputWaiter.prototype.containsCR = function() { - return this.app.dishStr.indexOf("\r") >= 0; + return this.dishStr.indexOf("\r") >= 0; }; export default OutputWaiter; diff --git a/src/web/WorkerWaiter.js b/src/web/WorkerWaiter.js index 3ed9e7ea..402b56b0 100644 --- a/src/web/WorkerWaiter.js +++ b/src/web/WorkerWaiter.js @@ -1,4 +1,3 @@ -import Utils from "../core/Utils.js"; import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js"; /** @@ -111,19 +110,6 @@ WorkerWaiter.prototype.bakingComplete = function(response) { this.app.handleError(response.error); } - switch (response.type) { - case "html": - this.app.dishStr = Utils.stripHtmlTags(response.result, true); - break; - case "ArrayBuffer": - this.app.dishStr = ""; - break; - case "string": - default: - this.app.dishStr = response.result; - break; - } - this.app.progress = response.progress; this.manager.recipe.updateBreakpointIndicator(response.progress); this.manager.output.set(response.result, response.type, response.duration); From caf794b01d24aea3b16bafa9b478a3eaccb96f66 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 12:29:10 +0000 Subject: [PATCH 082/124] Threshold for treating output as a file is now configurable --- src/core/Chef.js | 5 +++-- src/web/html/index.html | 18 +++++++++++------- src/web/index.js | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/core/Chef.js b/src/core/Chef.js index 06d08aa0..8df6d523 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -78,8 +78,9 @@ Chef.prototype.bake = async function(input, recipeConfig, options, progress, ste // Depending on the size of the output, we may send it back as a string or an ArrayBuffer. // This can prevent unnecessary casting as an ArrayBuffer can be easily downloaded as a file. - // 1048576 bytes = 1 MiB - const returnType = this.dish.size() > 1048576 ? Dish.ARRAY_BUFFER : Dish.STRING; + // The threshold is specified in KiB. + const threshold = (options.outputFileThreshold || 1024) * 1024; + const returnType = this.dish.size() > threshold ? Dish.ARRAY_BUFFER : Dish.STRING; return { result: this.dish.type === Dish.HTML ? diff --git a/src/web/html/index.html b/src/web/html/index.html index c8857ff9..7f2c98d0 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -342,31 +342,35 @@
    - +
    - +
    - +
    - +
    - +
    - +
    - + +
    +
    + +
    From f7f07f2cb55dad6dfa35bb889c24d46023eee484 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 15:52:38 +0000 Subject: [PATCH 084/124] Loading a new file only causes a statechange event once the whole file has loaded --- src/web/InputWaiter.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index f6818b11..af5ed81f 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -58,13 +58,14 @@ InputWaiter.prototype.get = function() { * @fires Manager#statechange */ InputWaiter.prototype.set = function(input) { + const inputText = document.getElementById("input-text"); if (input instanceof File) { this.setFile(input); - input = ""; + inputText.value = ""; + } else { + inputText.value = input; + window.dispatchEvent(this.manager.statechange); } - - document.getElementById("input-text").value = input; - window.dispatchEvent(this.manager.statechange); }; From 50e4daeaf228988bfb34c51ba17800975e4caef0 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 27 Dec 2017 23:05:32 +0000 Subject: [PATCH 085/124] Output info tidied up for file outputs --- src/web/OutputWaiter.js | 22 +++++++++++++--------- src/web/stylesheets/layout/_io.css | 2 ++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 51def0b4..06379b94 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -63,8 +63,9 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { outputText.value = ""; outputHtml.innerHTML = data; - length = data.length; this.dishStr = Utils.stripHtmlTags(data, true); + length = data.length; + lines = this.dishStr.count("\n") + 1; // Execute script sections scriptElements = outputHtml.querySelectorAll("script"); @@ -84,8 +85,8 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { outputText.value = ""; outputHtml.innerHTML = ""; - length = data.byteLength; this.dishStr = ""; + length = data.byteLength; this.setFile(data); break; @@ -177,6 +178,7 @@ OutputWaiter.prototype.showFileOverlayClick = function(e) { outputFile.style.display = "block"; showFileOverlay.style.display = "none"; + this.setOutputInfo(this.dishBuffer.byteLength, null, 0); }; @@ -191,15 +193,17 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { let width = length.toString().length; width = width < 4 ? 4 : width; - lines = typeof lines === "number" ? lines : ""; - const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); - const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); - const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " "); + const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " "); - document.getElementById("output-info").innerHTML = "time: " + timeStr + - "
    length: " + lengthStr + - "
    lines: " + linesStr; + let msg = "time: " + timeStr + "
    length: " + lengthStr; + + if (typeof lines === "number") { + const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); + msg += "
    lines: " + linesStr; + } + + document.getElementById("output-info").innerHTML = msg; document.getElementById("input-selection-info").innerHTML = ""; document.getElementById("output-selection-info").innerHTML = ""; }; diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index 370c2235..c93c800b 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -111,6 +111,8 @@ font-family: var(--fixed-width-font-family); font-weight: normal; font-size: 8pt; + display: flex; + align-items: center; } #input-info { From e18ec5f2b2831053c64abca2930dccbd42c8e6a7 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 28 Dec 2017 00:24:16 +0000 Subject: [PATCH 086/124] Changed inputType to ArrayBuffer for 'Frequency distribution', 'Chi Square' and 'Extract EXIF' operations. --- src/core/config/OperationConfig.js | 6 +++--- src/core/operations/Entropy.js | 18 ++++++++++-------- src/core/operations/Image.js | 7 +++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 354ec12e..0a4a6161 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -3287,7 +3287,7 @@ const OperationConfig = { "Frequency distribution": { module: "Default", description: "Displays the distribution of bytes in the data as a graph.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "html", args: [ { @@ -3300,7 +3300,7 @@ const OperationConfig = { "Chi Square": { module: "Default", description: "Calculates the Chi Square distribution of values.", - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "number", args: [] }, @@ -3740,7 +3740,7 @@ const OperationConfig = { "

    ", "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.", ].join("\n"), - inputType: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [], }, diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index aa9ed0bc..db860720 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -81,22 +81,23 @@ const Entropy = { /** * Frequency distribution operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {html} */ runFreqDistrib: function (input, args) { - if (!input.length) return "No data"; + const data = new Uint8Array(input); + if (!data.length) return "No data"; let distrib = new Array(256).fill(0), percentages = new Array(256), - len = input.length, + len = data.length, showZeroes = args[0], i; // Count bytes for (i = 0; i < len; i++) { - distrib[input[i]]++; + distrib[data[i]]++; } // Calculate percentages @@ -138,21 +139,22 @@ const Entropy = { /** * Chi Square operation. * - * @param {byteArray} data + * @param {ArrayBuffer} data * @param {Object[]} args * @returns {number} */ runChiSq: function(input, args) { + const data = new Uint8Array(input); let distArray = new Array(256).fill(0), total = 0; - for (let i = 0; i < input.length; i++) { - distArray[input[i]]++; + 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] - input.length / 256, 2) / (input.length / 256); + total += Math.pow(distArray[i] - data.length / 256, 2) / (data.length / 256); } } diff --git a/src/core/operations/Image.js b/src/core/operations/Image.js index 2dd72df5..afab21c1 100644 --- a/src/core/operations/Image.js +++ b/src/core/operations/Image.js @@ -20,14 +20,13 @@ const Image = { * * Extracts EXIF data from a byteArray, representing a JPG or a TIFF image. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runExtractEXIF(input, args) { try { - const bytes = Uint8Array.from(input); - const parser = ExifParser.create(bytes.buffer); + const parser = ExifParser.create(input); const result = parser.parse(); let lines = []; @@ -53,7 +52,7 @@ const Image = { * @author David Moodie [davidmoodie12@gmail.com] * @param {byteArray} input * @param {Object[]} args - * @returns {string} + * @returns {byteArray} */ runRemoveEXIF(input, args) { // Do nothing if input is empty From 849d41ee5600f1a389d1239d940256905b0e5c74 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 28 Dec 2017 14:38:57 +0000 Subject: [PATCH 087/124] Removed padLeft and padRight in favour of String.prototype.padStart and padEnd. 'To Hex' now supports ArrayBuffers. --- src/core/Utils.js | 110 ++++++++++++----------------- src/core/config/OperationConfig.js | 2 +- src/core/operations/BCD.js | 4 +- src/core/operations/ByteRepr.js | 6 +- src/core/operations/Compress.js | 6 +- src/core/operations/Entropy.js | 2 +- src/core/operations/HTML.js | 6 +- src/core/operations/Hexdump.js | 4 +- src/core/operations/PublicKey.js | 9 ++- src/core/operations/SeqUtils.js | 2 +- src/core/operations/Tidy.js | 7 +- src/core/operations/URL.js | 3 +- src/web/HighlighterWaiter.js | 9 +-- src/web/InputWaiter.js | 5 +- src/web/OutputWaiter.js | 6 +- 15 files changed, 77 insertions(+), 104 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index 766bc118..a6ab48db 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -64,58 +64,6 @@ const Utils = { }, - /** - * Adds leading zeros to strings - * - * @param {string} str - String to add leading characters to. - * @param {number} max - Maximum width of the string. - * @param {char} [chr='0'] - The character to pad with. - * @returns {string} - * - * @example - * // returns "0a" - * Utils.padLeft("a", 2); - * - * // returns "000a" - * Utils.padLeft("a", 4); - * - * // returns "xxxa" - * Utils.padLeft("a", 4, "x"); - * - * // returns "bcabchello" - * Utils.padLeft("hello", 10, "abc"); - */ - padLeft: function(str, max, chr) { - chr = chr || "0"; - let startIndex = chr.length - (max - str.length); - startIndex = startIndex < 0 ? 0 : startIndex; - return str.length < max ? - Utils.padLeft(chr.slice(startIndex, chr.length) + str, max, chr) : str; - }, - - - /** - * Adds trailing spaces to strings. - * - * @param {string} str - String to add trailing characters to. - * @param {number} max - Maximum width of the string. - * @param {char} [chr='0'] - The character to pad with. - * @returns {string} - * - * @example - * // returns "a " - * Utils.padRight("a", 4); - * - * // returns "axxx" - * Utils.padRight("a", 4, "x"); - */ - padRight: function(str, max, chr) { - chr = chr || " "; - return str.length < max ? - Utils.padRight(str + chr.slice(0, max-str.length), max, chr) : str; - }, - - /** * Adds trailing bytes to a byteArray. * @@ -152,14 +100,6 @@ const Utils = { }, - /** - * @alias Utils.padLeft - */ - pad: function(str, max, chr) { - return Utils.padLeft(str, max, chr); - }, - - /** * Truncates a long string to max length and adds suffix. * @@ -201,7 +141,7 @@ const Utils = { hex: function(c, length) { c = typeof c == "string" ? Utils.ord(c) : c; length = length || 2; - return Utils.pad(c.toString(16), length); + return c.toString(16).padStart(length, "0"); }, @@ -222,7 +162,7 @@ const Utils = { bin: function(c, length) { c = typeof c == "string" ? Utils.ord(c) : c; length = length || 8; - return Utils.pad(c.toString(2), length); + return c.toString(2).padStart(length, "0"); }, @@ -656,7 +596,7 @@ const Utils = { /** * Convert a byte array into a hex string. * - * @param {byteArray} data + * @param {Uint8Array|byteArray} data * @param {string} [delim=" "] * @param {number} [padding=2] * @returns {string} @@ -676,7 +616,7 @@ const Utils = { let output = ""; for (let i = 0; i < data.length; i++) { - output += Utils.pad(data[i].toString(16), padding) + delim; + output += data[i].toString(16).padStart(padding, "0") + delim; } // Add \x or 0x to beginning @@ -1379,3 +1319,45 @@ Array.prototype.equals = function(other) { String.prototype.count = function(chr) { return this.split(chr).length - 1; }; + + +/* + * Polyfills + */ + +// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart +if (!String.prototype.padStart) { + String.prototype.padStart = function padStart(targetLength, padString) { + targetLength = targetLength>>0; //floor if number or convert non-number to 0; + padString = String((typeof padString !== "undefined" ? padString : " ")); + if (this.length > targetLength) { + return String(this); + } else { + targetLength = targetLength-this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed + } + return padString.slice(0, targetLength) + String(this); + } + }; +} + + +// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd +if (!String.prototype.padEnd) { + String.prototype.padEnd = function padEnd(targetLength, padString) { + targetLength = targetLength>>0; //floor if number or convert non-number to 0; + padString = String((typeof padString !== "undefined" ? padString : " ")); + if (this.length > targetLength) { + return String(this); + } else { + targetLength = targetLength-this.length; + if (targetLength > padString.length) { + padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed + } + return String(this) + padString.slice(0, targetLength); + } + }; +} diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 0a4a6161..15f00df8 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -631,7 +631,7 @@ const OperationConfig = { 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: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { diff --git a/src/core/operations/BCD.js b/src/core/operations/BCD.js index 63c0cda3..d3efbc71 100755 --- a/src/core/operations/BCD.js +++ b/src/core/operations/BCD.js @@ -134,11 +134,11 @@ const BCD = { switch (outputFormat) { case "Nibbles": return nibbles.map(n => { - return Utils.padLeft(n.toString(2), 4); + return n.toString(2).padStart(4, "0"); }).join(" "); case "Bytes": return bytes.map(b => { - return Utils.padLeft(b.toString(2), 8); + return b.toString(2).padStart(8, "0"); }).join(" "); case "Raw": default: diff --git a/src/core/operations/ByteRepr.js b/src/core/operations/ByteRepr.js index 87a543ff..986926ca 100755 --- a/src/core/operations/ByteRepr.js +++ b/src/core/operations/ByteRepr.js @@ -31,13 +31,13 @@ const ByteRepr = { /** * To Hex operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runToHex: function(input, args) { const delim = Utils.charRep[args[0] || "Space"]; - return Utils.toHex(input, delim, 2); + return Utils.toHex(new Uint8Array(input), delim, 2); }, @@ -266,7 +266,7 @@ const ByteRepr = { padding = 8; for (let i = 0; i < input.length; i++) { - output += Utils.pad(input[i].toString(2), padding) + delim; + output += input[i].toString(2).padStart(padding, "0") + delim; } if (delim.length) { diff --git a/src/core/operations/Compress.js b/src/core/operations/Compress.js index 639b89c6..57b01027 100755 --- a/src/core/operations/Compress.js +++ b/src/core/operations/Compress.js @@ -418,9 +418,9 @@ const Compress = { } }; - const fileSize = Utils.padLeft(input.length.toString(8), 11, "0"); + const fileSize = input.length.toString(8).padStart(11, "0"); const currentUnixTimestamp = Math.floor(Date.now() / 1000); - const lastModTime = Utils.padLeft(currentUnixTimestamp.toString(8), 11, "0"); + const lastModTime = currentUnixTimestamp.toString(8).padStart(11, "0"); const file = { fileName: Utils.padBytesRight(args[0], 100), @@ -452,7 +452,7 @@ const Compress = { } }); } - checksum = Utils.padBytesRight(Utils.padLeft(checksum.toString(8), 7, "0"), 8); + checksum = Utils.padBytesRight(checksum.toString(8).padStart(7, "0"), 8); file.checksum = checksum; const tarball = new Tarball(); diff --git a/src/core/operations/Entropy.js b/src/core/operations/Entropy.js index db860720..baf9edb3 100755 --- a/src/core/operations/Entropy.js +++ b/src/core/operations/Entropy.js @@ -127,7 +127,7 @@ const Entropy = { for (i = 0; i < 256; i++) { if (distrib[i] || showZeroes) { output += " " + Utils.hex(i, 2) + " (" + - Utils.padRight(percentages[i].toFixed(2).replace(".00", "") + "%)", 8) + + (percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") + Array(Math.ceil(percentages[i])+1).join("|") + "\n"; } } diff --git a/src/core/operations/HTML.js b/src/core/operations/HTML.js index 30eda63e..b1f7e065 100755 --- a/src/core/operations/HTML.js +++ b/src/core/operations/HTML.js @@ -215,9 +215,9 @@ const HTML = { k = k.toFixed(2); let hex = "#" + - Utils.padLeft(Math.round(r).toString(16), 2) + - Utils.padLeft(Math.round(g).toString(16), 2) + - Utils.padLeft(Math.round(b).toString(16), 2), + 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 + "%)", diff --git a/src/core/operations/Hexdump.js b/src/core/operations/Hexdump.js index a9ed7a10..6b322b1f 100755 --- a/src/core/operations/Hexdump.js +++ b/src/core/operations/Hexdump.js @@ -56,8 +56,8 @@ const Hexdump = { } output += lineNo + " " + - Utils.padRight(hexa, (length*(padding+1))) + - " |" + Utils.padRight(Utils.printable(Utils.byteArrayToChars(buff)), buff.length) + "|\n"; + hexa.padEnd(length*(padding+1), " ") + + " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n"; if (includeFinalLength && i+buff.length === input.length) { output += Utils.hex(i+buff.length, 8) + "\n"; diff --git a/src/core/operations/PublicKey.js b/src/core/operations/PublicKey.js index 295a5bf4..66b177a5 100755 --- a/src/core/operations/PublicKey.js +++ b/src/core/operations/PublicKey.js @@ -121,8 +121,7 @@ const PublicKey = { // Format Public Key fields for (let i = 0; i < pkFields.length; i++) { pkStr += " " + pkFields[i].key + ":" + - Utils.padLeft( - pkFields[i].value + "\n", + (pkFields[i].value + "\n").padStart( 18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1, " " ); @@ -286,9 +285,9 @@ ${extensions}`; key = fields[i].split("=")[0]; value = fields[i].split("=")[1]; - str = Utils.padRight(key, maxKeyLen) + " = " + value + "\n"; + str = key.padEnd(maxKeyLen, " ") + " = " + value + "\n"; - output += Utils.padLeft(str, indent + str.length, " "); + output += str.padStart(indent + str.length, " "); } return output.slice(0, -1); @@ -314,7 +313,7 @@ ${extensions}`; if (i === 0) { output += str; } else { - output += Utils.padLeft(str, indent + str.length, " "); + output += str.padStart(indent + str.length, " "); } } diff --git a/src/core/operations/SeqUtils.js b/src/core/operations/SeqUtils.js index 3272e706..fa900cf9 100755 --- a/src/core/operations/SeqUtils.js +++ b/src/core/operations/SeqUtils.js @@ -158,7 +158,7 @@ const SeqUtils = { width = lines.length.toString().length; for (let n = 0; n < lines.length; n++) { - output += Utils.pad((n+1).toString(), width, " ") + " " + lines[n] + "\n"; + output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n"; } return output.slice(0, output.length-1); }, diff --git a/src/core/operations/Tidy.js b/src/core/operations/Tidy.js index 881508cf..41f0561d 100755 --- a/src/core/operations/Tidy.js +++ b/src/core/operations/Tidy.js @@ -1,6 +1,3 @@ -import Utils from "../Utils.js"; - - /** * Tidy operations. * @@ -229,11 +226,11 @@ const Tidy = { if (position === "Start") { for (i = 0; i < lines.length; i++) { - output += Utils.padLeft(lines[i], lines[i].length+len, chr) + "\n"; + output += lines[i].padStart(lines[i].length+len, chr) + "\n"; } } else if (position === "End") { for (i = 0; i < lines.length; i++) { - output += Utils.padRight(lines[i], lines[i].length+len, chr) + "\n"; + output += lines[i].padEnd(lines[i].length+len, chr) + "\n"; } } diff --git a/src/core/operations/URL.js b/src/core/operations/URL.js index 25526f0e..2f30c952 100755 --- a/src/core/operations/URL.js +++ b/src/core/operations/URL.js @@ -1,5 +1,4 @@ /* globals unescape */ -import Utils from "../Utils.js"; import url from "url"; @@ -78,7 +77,7 @@ const URL_ = { output += "Arguments:\n"; for (let key in uri.query) { - output += "\t" + Utils.padRight(key, padding); + output += "\t" + key.padEnd(padding, " "); if (uri.query[key].length) { output += " = " + uri.query[key] + "\n"; } else { diff --git a/src/web/HighlighterWaiter.js b/src/web/HighlighterWaiter.js index d9980fec..6e4ca599 100755 --- a/src/web/HighlighterWaiter.js +++ b/src/web/HighlighterWaiter.js @@ -1,6 +1,3 @@ -import Utils from "../core/Utils.js"; - - /** * Waiter to handle events related to highlighting in CyberChef. * @@ -312,9 +309,9 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) { HighlighterWaiter.prototype.selectionInfo = function(start, end) { const len = end.toString().length; const width = len < 2 ? 2 : len; - const startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, " "); - const endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, " "); - const lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, " "); + 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; }; diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index af5ed81f..af3f72ee 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -1,4 +1,3 @@ -import Utils from "../core/Utils.js"; import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker.js"; @@ -100,8 +99,8 @@ InputWaiter.prototype.setInputInfo = function(length, lines) { let width = length.toString().length; width = width < 2 ? 2 : width; - const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); - const linesStr = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); + const lengthStr = length.toString().padStart(width, " ").replace(/ /g, " "); + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); document.getElementById("input-info").innerHTML = "length: " + lengthStr + "
    lines: " + linesStr; }; diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 06379b94..42742734 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -193,13 +193,13 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) { let width = length.toString().length; width = width < 4 ? 4 : width; - const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, " "); - const timeStr = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, " "); + 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 = Utils.pad(lines.toString(), width, " ").replace(/ /g, " "); + const linesStr = lines.toString().padStart(width, " ").replace(/ /g, " "); msg += "
    lines: " + linesStr; } From 75a554e215ac16c3e9c8b13d064f6a3943f355fb Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 28 Dec 2017 15:59:58 +0000 Subject: [PATCH 088/124] 'To Base64' and 'To Hexdump' operations now support ArrayBuffers --- src/core/Utils.js | 4 ++-- src/core/config/OperationConfig.js | 4 ++-- src/core/operations/Base64.js | 4 ++-- src/core/operations/Hexdump.js | 9 +++++---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/core/Utils.js b/src/core/Utils.js index a6ab48db..f9e5a3b8 100755 --- a/src/core/Utils.js +++ b/src/core/Utils.js @@ -438,7 +438,7 @@ const Utils = { /** * Converts a charcode array to a string. * - * @param {byteArray} byteArray + * @param {byteArray|Uint8Array} byteArray * @returns {string} * * @example @@ -477,7 +477,7 @@ const Utils = { /** * Base64's the input byte array using the given alphabet, returning a string. * - * @param {byteArray|string} data + * @param {byteArray|Uint8Array|string} data * @param {string} [alphabet] * @returns {string} * diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 15f00df8..dbac0bfe 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -245,7 +245,7 @@ const OperationConfig = { 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: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { @@ -782,7 +782,7 @@ const OperationConfig = { 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: "byteArray", + inputType: "ArrayBuffer", outputType: "string", args: [ { diff --git a/src/core/operations/Base64.js b/src/core/operations/Base64.js index c6d9ce6c..31c7e2a1 100755 --- a/src/core/operations/Base64.js +++ b/src/core/operations/Base64.js @@ -40,13 +40,13 @@ const Base64 = { /** * To Base64 operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runTo: function(input, args) { const alphabet = args[0] || Base64.ALPHABET; - return Utils.toBase64(input, alphabet); + return Utils.toBase64(new Uint8Array(input), alphabet); }, diff --git a/src/core/operations/Hexdump.js b/src/core/operations/Hexdump.js index 6b322b1f..fc907d9e 100755 --- a/src/core/operations/Hexdump.js +++ b/src/core/operations/Hexdump.js @@ -31,18 +31,19 @@ const Hexdump = { /** * To Hexdump operation. * - * @param {byteArray} input + * @param {ArrayBuffer} input * @param {Object[]} args * @returns {string} */ runTo: function(input, args) { + const data = new Uint8Array(input); const length = args[0] || Hexdump.WIDTH; const upperCase = args[1]; const includeFinalLength = args[2]; let output = "", padding = 2; - for (let i = 0; i < input.length; i += length) { - const buff = input.slice(i, i+length); + 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) + " "; @@ -59,7 +60,7 @@ const Hexdump = { hexa.padEnd(length*(padding+1), " ") + " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n"; - if (includeFinalLength && i+buff.length === input.length) { + if (includeFinalLength && i+buff.length === data.length) { output += Utils.hex(i+buff.length, 8) + "\n"; } } From 124ff83206bf41c9863d955c732f276a3852395c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 28 Dec 2017 16:10:39 +0000 Subject: [PATCH 089/124] 7.0.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8370224b..53402923 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.8.0", + "version": "7.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3319e9fa..18f57fb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "6.8.0", + "version": "7.0.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From d079420d46f0787664de6f5c856f6ecd5a018092 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 28 Dec 2017 18:17:38 +0000 Subject: [PATCH 090/124] Added logging with configurable levels to make debugging easier. --- .eslintrc.json | 2 +- package-lock.json | 3 +-- package.json | 1 + src/core/Chef.js | 5 ++++- src/core/ChefWorker.js | 7 ++++++- src/core/Dish.js | 3 +++ src/core/Recipe.js | 3 +++ src/web/App.js | 5 +++-- src/web/InputWaiter.js | 1 + src/web/Manager.js | 3 ++- src/web/OptionsWaiter.js | 24 ++++++++++++++++++++++-- src/web/OutputWaiter.js | 3 ++- src/web/WorkerWaiter.js | 24 ++++++++++++++++++++++-- src/web/html/index.html | 11 +++++++++++ src/web/index.js | 6 ++---- test/index.js | 2 ++ webpack.config.js | 3 ++- 17 files changed, 88 insertions(+), 18 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index b892ae60..629f7b10 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -35,7 +35,6 @@ }], // disable rules from base configurations - "no-console": "off", "no-control-regex": "off", // stylistic conventions @@ -90,6 +89,7 @@ "$": false, "jQuery": false, "moment": false, + "log": false, "COMPILE_TIME": false, "COMPILE_MSG": false, diff --git a/package-lock.json b/package-lock.json index 53402923..a90959be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6132,8 +6132,7 @@ "loglevel": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.0.tgz", - "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ=", - "dev": true + "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ=" }, "longest": { "version": "1.0.1", diff --git a/package.json b/package.json index 18f57fb0..99fcccd4 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "jsonpath": "^1.0.0", "jsrsasign": "8.0.4", "lodash": "^4.17.4", + "loglevel": "^1.6.0", "moment": "^2.20.1", "moment-timezone": "^0.5.14", "node-md6": "^0.1.0", diff --git a/src/core/Chef.js b/src/core/Chef.js index 8df6d523..0d71ce2e 100755 --- a/src/core/Chef.js +++ b/src/core/Chef.js @@ -34,6 +34,7 @@ const Chef = function() { * @returns {number} response.error - The error object thrown by a failed operation (false if no error) */ Chef.prototype.bake = async function(input, recipeConfig, options, progress, step) { + log.debug("Chef baking"); let startTime = new Date().getTime(), recipe = new Recipe(recipeConfig), containsFc = recipe.containsFlowControl(), @@ -69,7 +70,7 @@ Chef.prototype.bake = async function(input, recipeConfig, options, progress, ste try { progress = await recipe.execute(this.dish, progress); } catch (err) { - console.log(err); + log.error(err); error = { displayStr: err.displayStr, }; @@ -112,6 +113,8 @@ Chef.prototype.bake = async function(input, recipeConfig, options, progress, ste * @returns {number} The time it took to run the silent bake in milliseconds. */ Chef.prototype.silentBake = function(recipeConfig) { + log.debug("Running silent bake"); + let startTime = new Date().getTime(), recipe = new Recipe(recipeConfig), dish = new Dish("", Dish.STRING); diff --git a/src/core/ChefWorker.js b/src/core/ChefWorker.js index 4bb7f9e5..899f6664 100644 --- a/src/core/ChefWorker.js +++ b/src/core/ChefWorker.js @@ -42,6 +42,8 @@ self.postMessage({ self.addEventListener("message", function(e) { // Handle message const r = e.data; + log.debug("ChefWorker receiving command '" + r.action + "'"); + switch (r.action) { case "bake": bake(r.data); @@ -61,6 +63,9 @@ self.addEventListener("message", function(e) { r.data.pos ); break; + case "setLogLevel": + log.setLevel(r.data, false); + break; default: break; } @@ -121,7 +126,7 @@ function loadRequiredModules(recipeConfig) { let module = self.OperationConfig[op.op].module; if (!OpModules.hasOwnProperty(module)) { - console.log("Loading module " + module); + log.info("Loading module " + module); self.sendStatusMessage("Loading module " + module); self.importScripts(self.docURL + "/" + module + ".js"); } diff --git a/src/core/Dish.js b/src/core/Dish.js index 4a16919a..001f78e1 100755 --- a/src/core/Dish.js +++ b/src/core/Dish.js @@ -111,6 +111,7 @@ Dish.enumLookup = function(typeEnum) { * @param {number} type - The data type of value, see Dish enums. */ Dish.prototype.set = function(value, type) { + log.debug("Dish type: " + Dish.enumLookup(type)); this.value = value; this.type = type; @@ -141,6 +142,8 @@ Dish.prototype.get = function(type) { * @param {number} toType - The data type of value, see Dish enums. */ Dish.prototype.translate = function(toType) { + log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`); + // Convert data to intermediate byteArray type switch (this.type) { case Dish.STRING: diff --git a/src/core/Recipe.js b/src/core/Recipe.js index fdd06943..6f2fb166 100755 --- a/src/core/Recipe.js +++ b/src/core/Recipe.js @@ -150,14 +150,17 @@ Recipe.prototype.execute = async function(dish, startFrom) { for (let i = startFrom; i < this.opList.length; i++) { op = this.opList[i]; if (op.isDisabled()) { + log.debug(`[${i}] '${op.name}' is disabled`); continue; } if (op.isBreakpoint()) { + log.debug(`[${i}] Pausing at breakpoint on '${op.name}'`); return i; } try { input = dish.get(op.inputType); + log.debug(`[${i}] Executing '${op.name}'`); if (op.isFlowControl()) { // Package up the current state diff --git a/src/web/App.js b/src/web/App.js index d877791d..eb174e72 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -91,7 +91,7 @@ App.prototype.loaded = function() { * @param {boolean} [logToConsole=false] */ App.prototype.handleError = function(err, logToConsole) { - if (logToConsole) console.error(err); + if (logToConsole) log.error(err); const msg = err.displayStr || err.toString(); this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); }; @@ -129,6 +129,7 @@ App.prototype.autoBake = function() { if (this.autoBakePause) return false; if (this.autoBake_ && !this.baking) { + log.debug("Auto-baking"); this.bake(); } else { this.manager.controls.showStaleIndicator(); @@ -569,7 +570,7 @@ App.prototype.isLocalStorageAvailable = function() { App.prototype.alert = function(str, style, timeout, silent) { const time = new Date(); - console.log("[" + time.toLocaleString() + "] " + str); + log.info("[" + time.toLocaleString() + "] " + str); if (silent) return; style = style || "danger"; diff --git a/src/web/InputWaiter.js b/src/web/InputWaiter.js index af3f72ee..33784edc 100755 --- a/src/web/InputWaiter.js +++ b/src/web/InputWaiter.js @@ -215,6 +215,7 @@ InputWaiter.prototype.handleLoaderMessage = function(e) { } if (r.hasOwnProperty("fileBuffer")) { + log.debug("Input file loaded"); this.fileBuffer = r.fileBuffer; window.dispatchEvent(this.manager.statechange); } diff --git a/src/web/Manager.js b/src/web/Manager.js index 39aaf409..c19ddaf5 100755 --- a/src/web/Manager.js +++ b/src/web/Manager.js @@ -58,7 +58,7 @@ const Manager = function(app) { 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.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); @@ -172,6 +172,7 @@ Manager.prototype.initialiseEventListeners = function() { 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)); diff --git a/src/web/OptionsWaiter.js b/src/web/OptionsWaiter.js index b3eb364c..f121c469 100755 --- a/src/web/OptionsWaiter.js +++ b/src/web/OptionsWaiter.js @@ -8,8 +8,9 @@ * @constructor * @param {App} app - The main view object for CyberChef. */ -const OptionsWaiter = function(app) { +const OptionsWaiter = function(app, manager) { this.app = app; + this.manager = manager; }; @@ -86,6 +87,7 @@ OptionsWaiter.prototype.switchChange = function(e, state) { const el = e.target; const option = el.getAttribute("option"); + log.debug(`Setting ${option} to ${state}`); this.app.options[option] = state; if (this.app.isLocalStorageAvailable()) @@ -102,8 +104,10 @@ OptionsWaiter.prototype.switchChange = function(e, state) { OptionsWaiter.prototype.numberChange = function(e) { const el = e.target; const option = el.getAttribute("option"); + const val = parseInt(el.value, 10); - this.app.options[option] = parseInt(el.value, 10); + log.debug(`Setting ${option} to ${val}`); + this.app.options[option] = val; if (this.app.isLocalStorageAvailable()) localStorage.setItem("options", JSON.stringify(this.app.options)); @@ -120,6 +124,7 @@ OptionsWaiter.prototype.selectChange = function(e) { const el = e.target; const option = el.getAttribute("option"); + log.debug(`Setting ${option} to ${el.value}`); this.app.options[option] = el.value; if (this.app.isLocalStorageAvailable()) @@ -149,6 +154,8 @@ OptionsWaiter.prototype.setWordWrap = function() { /** * Changes the theme by setting the class of the element. + * + * @param {Event} e */ OptionsWaiter.prototype.themeChange = function (e) { const themeClass = e.target.value; @@ -156,4 +163,17 @@ OptionsWaiter.prototype.themeChange = function (e) { document.querySelector(":root").className = themeClass; }; + +/** + * Changes the console logging level. + * + * @param {Event} e + */ +OptionsWaiter.prototype.logLevelChange = function (e) { + const level = e.target.value; + log.info("Setting log level to " + level); + log.setLevel(level, false); + this.manager.worker.setLogLevel(); +}; + export default OptionsWaiter; diff --git a/src/web/OutputWaiter.js b/src/web/OutputWaiter.js index 42742734..6012975e 100755 --- a/src/web/OutputWaiter.js +++ b/src/web/OutputWaiter.js @@ -41,6 +41,7 @@ OutputWaiter.prototype.get = function() { * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer */ OutputWaiter.prototype.set = 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"); @@ -73,7 +74,7 @@ OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) { try { eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval } catch (err) { - console.error(err); + log.error(err); } } break; diff --git a/src/web/WorkerWaiter.js b/src/web/WorkerWaiter.js index 402b56b0..7d4dbf2f 100644 --- a/src/web/WorkerWaiter.js +++ b/src/web/WorkerWaiter.js @@ -21,8 +21,10 @@ const WorkerWaiter = function(app, manager) { * 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("/"); @@ -40,6 +42,8 @@ WorkerWaiter.prototype.registerChefWorker = function() { */ WorkerWaiter.prototype.handleChefMessage = function(e) { const r = e.data; + log.debug("Receiving '" + r.action + "' from ChefWorker"); + switch (r.action) { case "bakeSuccess": this.bakingComplete(r.data); @@ -58,6 +62,7 @@ WorkerWaiter.prototype.handleChefMessage = function(e) { 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": @@ -67,7 +72,7 @@ WorkerWaiter.prototype.handleChefMessage = function(e) { this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction); break; default: - console.error("Unrecognised message from ChefWorker", e); + log.error("Unrecognised message from ChefWorker", e); break; } }; @@ -145,7 +150,7 @@ WorkerWaiter.prototype.bake = function(input, recipeConfig, options, progress, s * 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 {Objectp[]} [recipeConfig] + * @param {Object[]} [recipeConfig] */ WorkerWaiter.prototype.silentBake = function(recipeConfig) { this.chefWorker.postMessage({ @@ -178,4 +183,19 @@ WorkerWaiter.prototype.highlight = function(recipeConfig, direction, pos) { }; +/** + * 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/html/index.html b/src/web/html/index.html index ea5fec36..6dd6ff53 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -372,6 +372,17 @@
    +
    + + +
    - - + +
    - +