2
0
mirror of https://github.com/gchq/CyberChef synced 2025-12-05 23:53:27 +00:00

Compare commits

..

90 Commits

Author SHA1 Message Date
n1474335
9947c574d2 5.7.2 2017-05-20 13:49:29 +01:00
n1474335
693abdacf6 Merge branch 'tlwr-master' 2017-05-20 13:49:17 +01:00
toby
dd3b42fb53 Fix bug with UTF16LE in Encode/Decode ops 2017-05-19 16:11:08 -04:00
n1474335
8e72d7d0d6 5.7.1 2017-05-19 16:28:43 +00:00
n1474335
a6317212d9 Merge branch 'feature-loading-messages' 2017-05-19 16:25:30 +00:00
n1474335
347adf688a Added loading messages to preloader 2017-05-19 16:23:52 +00:00
n1474335
3ee67927a5 Moved bootstrap from devDependencies to dependencies and removed bootstrap-sass. 2017-05-19 14:17:34 +00:00
n1474335
7ecd36efcf Cleaned up extraneous character encoding functions in Utils.js 2017-05-19 14:05:57 +00:00
n1474335
714ce8a8a3 5.7.0 2017-05-19 13:45:30 +00:00
n1474335
7b18a2f46f Merge branch 'tlwr-feature-ebcdic' 2017-05-19 13:44:18 +00:00
n1474335
19103a64e5 Tidied up character encoding names 2017-05-19 13:43:55 +00:00
n1474335
a13f1d27e2 Merge branch 'feature-ebcdic' of https://github.com/tlwr/CyberChef into tlwr-feature-ebcdic 2017-05-19 13:16:54 +00:00
n1474335
9a6e4b1e85 5.6.0 2017-05-19 13:12:04 +00:00
n1474335
67b78fc230 Merge branch 'feature-render-images' 2017-05-19 13:11:12 +00:00
n1474335
5e79187176 Added ico and removed tiff from supported image types 2017-05-19 12:58:42 +00:00
n1474335
491a82cd67 Added 'Render Image' operation 2017-05-19 11:15:48 +00:00
n1474335
87c2ec678f 5.5.0 2017-05-19 00:22:50 +01:00
n1474335
70135ab3ea Really fix compile message formatting 2017-05-19 00:22:41 +01:00
n1474335
ad18d84f14 Fix option defaults and compile message formatting 2017-05-19 00:10:36 +01:00
n1474335
77e47e3fa4 Merge branch 'feature-sass' 2017-05-18 23:51:29 +01:00
n1474335
04432385b3 Merge branch 'master' into feature-sass 2017-05-18 23:50:43 +01:00
n1474335
cbdc24d869 Travis CI now adds a compile message 2017-05-18 23:46:03 +01:00
n1474335
2b3e471f96 Added version number to About/Support pane 2017-05-18 23:40:53 +01:00
n1474335
488d54493a Added modern browser warning for theme support 2017-05-18 23:29:04 +01:00
n1474335
a418f63a44 Added postcss-loader to provide fallbacks for older browsers 2017-05-18 23:24:24 +01:00
toby
0e285151f3 Add codepage numbers to CharEnc IO_FORMAT 2017-05-17 18:22:04 -04:00
n1474335
e4ad7768d5 Finalised the dark theme 2017-05-17 23:02:52 +01:00
toby
f800fab1a3 Add author tags to Encode text & Decode text ops 2017-05-17 17:31:28 -04:00
toby
dc61aeeeb8 Improve format of en/decoding text descriptions 2017-05-17 17:18:08 -04:00
toby
4b1d0fd011 Merge branch 'feature-ebcdic' of github.com:tlwr/CyberChef into feature-ebcdic 2017-05-17 11:30:20 -04:00
toby
2b7ba594fc Split "Text encoding" op into two ops
This commit splits "Text encoding" into two operations:
+ Encode text `string -> byteArray`
+ Decode text `byteArray -> string`

Base64 and Hex support are removed "Encode text" and "Decode text" as
they have their own operations.

Encode and decode operations now have support for the following
encodings:
+ IBM EBCDIC US-Canada
+ IBM EBCDIC International
+ Windows-874 Thai
+ Japanese Shift-JIS
+ Simplified Chinese GBK
+ Korean
+ Traditional Chinese Big5
+ UTF-16, little endian
+ UTF-16, big endian
+ Windows-1250 Central European
+ Windows-1251 Cyrillic
+ Windows-1252 Latin
+ Windows-1253 Greek
+ Windows-1254 Turkish
+ Windows-1255 Hebrew
+ Windows-1256 Arabic
+ Windows-1257 Baltic
+ Windows-1258 Vietnam
+ US-ASCII
+ Russian Cyrillic KOI8-R
+ Simplified Chinese GB2312
+ KOI8-U Ukrainian Cyrillic
+ ISO-8859-1 Latin 1 (Western European)
+ ISO-8859-2 Latin 2 (Central European)
+ ISO-8859-3 Latin 3
+ ISO-8859-4 Baltic
+ ISO-8859-5 Cyrillic
+ ISO-8859-6 Arabic
+ ISO-8859-7 Greek
+ ISO-8859-8 Hebrew
+ ISO-8859-9 Turkish
+ ISO-8859-10 Latin 6
+ ISO-8859-11 Latin (Thai)
+ ISO-8859-13 Latin 7 (Estonian)
+ ISO-8859-14 Latin 8 (Celtic)
+ ISO-8859-15 Latin 9
+ ISO-8859-16 Latin 10
+ ISO-2022 JIS Japanese
+ EUC Japanese
+ EUC Korean
+ Simplified Chinese GB18030
+ UTF-7
+ UTF-8
2017-05-17 11:17:11 -04:00
n1474335
d87b14af13 5.4.1 2017-05-17 14:45:19 +00:00
n1474335
83623d23cf Merge branch 'bug-timestamp' 2017-05-17 14:45:10 +00:00
n1474335
07fba53b73 'To UNIX Timestamp' operation now defaults to UTC instead of your local timezone. 2017-05-17 14:37:36 +00:00
n1474335
823b276ef5 Changed bootstrap-sass back to bootstrap (with less). Theme now loads before the preloader is shown. 2017-05-13 16:45:19 +01:00
n1474335
0e72d78731 5.4.0 2017-05-13 16:10:26 +01:00
n1474335
768609e357 Whitespace 2017-05-13 16:09:32 +01:00
n1474335
526a157421 Merge branch 'tlwr-feature-exif' 2017-05-13 16:08:39 +01:00
n1474335
62154309fb Newlines 2017-05-13 16:08:14 +01:00
n1474335
ad74e6c475 Merge branch 'feature-exif' of https://github.com/tlwr/CyberChef into tlwr-feature-exif 2017-05-13 15:59:48 +01:00
toby
82d28242cc Add JSDoc to the runEXIF function in Image.js 2017-05-09 15:34:18 -04:00
toby
60fddf837d Change let to const in "Extract EXIF" 2017-05-08 12:49:13 -04:00
toby
ee25df0c28 Add desc and fix error message for "Extract EXIF" 2017-05-08 12:48:43 -04:00
toby
478af40359 Fix "Extract EXIF" tests 2017-05-08 12:45:42 -04:00
Toby Lorne
6bf06a9629 Merge branch 'master' into feature-ebcdic 2017-05-07 18:21:30 -04:00
toby
3c15bd9e29 Add "{To,From} EBCDIC" operations
This adds operations
+ "To EBCDIC"
+ "From EBCDIC"

This makes use of the npm codepage package but it is not installed as a
dependency.

Instead I used the `make.sh` script to export pages 37 and 500.

To my knowledge there is no way currently to only import individual code pages
from the npm package (hence the included script).

If we were to import the package directly it increases the build size by
2.7MB.
2017-05-07 18:07:56 -04:00
toby
71796e3dbf Merge remote-tracking branch 'upstream/master' into feature-exif 2017-05-06 23:38:04 -04:00
n1474335
280f1ee2df Dark theme tweaks and improvements 2017-05-07 01:13:47 +01:00
n1474335
0dc72d8301 Merged master 2017-05-06 16:22:25 +01:00
n1474335
c43b67ea90 5.3.5 2017-05-06 16:15:29 +01:00
n1474335
244421b69e Merge branch 'graingert-prefer-const' 2017-05-06 16:14:58 +01:00
n1474335
1adedff61a Filter out source-map warnings in webpack output 2017-05-06 16:14:30 +01:00
n1474335
6abd10f9e2 Tidying codebase 2017-05-06 16:12:09 +01:00
n1474335
a85096ea11 5.3.4 2017-05-06 15:00:46 +01:00
n1474335
f67157f0ad Fixed erroring dependency 2017-05-06 15:00:28 +01:00
n1474335
5efe9bd91d Merge branch 'prefer-const' of https://github.com/graingert/CyberChef into graingert-prefer-const 2017-05-06 14:11:38 +01:00
n1474335
dc7a7267c9 5.3.4 2017-05-06 14:00:41 +01:00
n1474335
17188b1e38 Merge branch 'tlwr-feature-async-ops-small' 2017-05-06 14:00:08 +01:00
n1474335
e9c3bebfff Fixed lint error 2017-05-06 13:59:33 +01:00
n1474335
03fc22d3da Merge conflicts 2017-05-06 13:47:26 +01:00
n1474335
5d52c49c31 5.3.3 2017-05-05 16:04:22 +00:00
n1474335
d53da4cfb5 Merge branch 'bug-x509-sig' 2017-05-05 16:03:40 +00:00
n1474335
76204f5f47 Fixed lint errors 2017-05-05 16:03:25 +00:00
n1474335
b68adbd9a8 Merge branch 'master' into bug-x509-sig 2017-05-05 16:02:12 +00:00
n1474335
951b168f3a 5.3.2 2017-05-05 16:00:40 +00:00
n1474335
53d89af459 Merge branch 'feature-key-derivation-hashers' 2017-05-05 15:58:00 +00:00
n1474335
4f844ea837 Merge branch 'master' into feature-key-derivation-hashers 2017-05-05 15:57:42 +00:00
n1474335
b010fd88e8 Fix X.509 signature breakout bug 2017-05-05 15:42:24 +00:00
n1474335
66a93b81c6 Added hasher argument to PBKDF2 and EVPKDF operations. 2017-05-05 15:38:38 +00:00
toby
274e1139fa Remove debounce from Utils 2017-05-03 10:43:30 -04:00
toby
6122e33f4f Removed debounced autobake & stop disabling input 2017-05-03 10:35:15 -04:00
Thomas Grainger
b365ce3195 fix the first 100 prefer-const errors 2017-05-03 00:41:01 +01:00
Thomas Grainger
0a3233d289 move spider images to .json file 2017-05-03 00:41:01 +01:00
Thomas Grainger
15aea9e9ea auto-fix prefer-const 2017-05-03 00:41:01 +01:00
n1474335
80cdf0c014 Merge conflict 2017-05-02 23:03:28 +01:00
n1474335
d1d394eec7 Fix search-results layout bug. 2017-05-02 20:56:57 +01:00
toby
1b8a25ec88 Add "Extract EXIF" operation 2017-04-29 16:06:16 -04:00
n1474335
2e4076bb75 Added option to change the theme. 2017-04-25 00:21:38 +01:00
n1474335
d71ac2e894 Moved from Sass to CSS with custom properties, allowing for dynamic theme changes. 2017-04-24 23:59:35 +01:00
toby
50784f2600 Debounce autobake in the web app.
Added debounce with guidance from the underscore.js implementation:
e944e0275a/underscore.js (L880)
2017-04-23 13:41:28 -04:00
toby
21c0fed833 Fix bug: baking error did not reset baking status 2017-04-23 13:14:59 -04:00
n1474335
e3f41fea9c Developing a dark theme. 2017-04-23 17:09:12 +01:00
toby
a13e2468db Added UI loading indications to the HTML app 2017-04-21 20:04:12 -04:00
toby
3fb660d816 Add jsdoc-babel plugin
This is to stop jsdoc parsing errors.

More information in this thread:
https://github.com/jsdoc3/jsdoc/issues/555
2017-04-21 18:05:30 -04:00
toby
9f60dc3dd6 Change ecmaVersion to 8 to make eslint happy 2017-04-21 17:56:16 -04:00
toby
02f855ff09 Add more tests for flow control ops 2017-04-21 17:49:10 -04:00
toby
c39622ed1e Add support for async ops using async/await 2017-04-21 17:48:42 -04:00
n1474335
a4d93f23d6 Added preloader to hide elements before they are correctly rendered 2017-04-15 20:46:57 +01:00
n1474335
e0e5670d0e Styles rewritten in a modular format with themable properties stored in variables. 2017-04-13 17:59:37 +01:00
n1474335
e120422b05 Styles now imported through Sass. Less removed. 2017-04-09 14:06:59 +01:00
65 changed files with 4918 additions and 1335 deletions

View File

@@ -1,6 +1,6 @@
{
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 8,
"ecmaFeatures": {
"impliedStrict": true
},

View File

@@ -9,7 +9,7 @@ script:
- grunt test
- grunt docs
- grunt node
- grunt prod
- grunt prod --msg="$COMPILE_MSG"
before_deploy:
- grunt copy:ghPages
deploy:

View File

@@ -54,7 +54,7 @@ module.exports = function (grunt) {
// Project configuration
const compileTime = grunt.template.today("dd/mm/yyyy HH:MM:ss") + " UTC",
const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
banner = "/**\n" +
"* CyberChef - The Cyber Swiss Army Knife\n" +
"*\n" +
@@ -74,7 +74,8 @@ module.exports = function (grunt) {
"* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
"* See the License for the specific language governing permissions and\n" +
"* limitations under the License.\n" +
"*/\n";
"*/\n",
pkg = grunt.file.readJSON("package.json");
/**
* Compiles a production build of CyberChef into a single, portable web page.
@@ -182,7 +183,10 @@ module.exports = function (grunt) {
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader?minimize"
use: [
{ loader: "css-loader?minimize" },
{ loader: "postcss-loader" },
]
})
},
{
@@ -190,6 +194,7 @@ module.exports = function (grunt) {
use: ExtractTextPlugin.extract({
use: [
{ loader: "css-loader?minimize" },
{ loader: "postcss-loader" },
{ loader: "less-loader" }
]
})
@@ -220,7 +225,8 @@ module.exports = function (grunt) {
]
},
stats: {
children: false
children: false,
warningsFilter: /source-map/
}
},
webDev: {
@@ -234,7 +240,8 @@ module.exports = function (grunt) {
new HtmlWebpackPlugin({
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime
compileTime: compileTime,
version: pkg.version,
})
],
watch: true
@@ -260,6 +267,7 @@ module.exports = function (grunt) {
filename: "index.html",
template: "./src/web/html/index.html",
compileTime: compileTime,
version: pkg.version,
minify: {
removeComments: true,
collapseWhitespace: true,
@@ -271,6 +279,7 @@ module.exports = function (grunt) {
filename: "cyberchef.htm",
template: "./src/web/html/index.html",
compileTime: compileTime,
version: pkg.version,
inline: true,
minify: {
removeComments: true,

View File

@@ -2,7 +2,10 @@
"tags": {
"allowUnknownTags": true
},
"plugins": ["plugins/markdown"],
"plugins": [
"plugins/markdown",
"node_modules/jsdoc-babel"
],
"templates": {
"systemName": "CyberChef",
"footer": "",

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "5.3.1",
"version": "5.7.2",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -51,8 +51,12 @@
"html-webpack-plugin": "^2.28.0",
"imports-loader": "^0.7.1",
"ink-docstrap": "^1.1.4",
"jsdoc-babel": "^0.3.0",
"less": "^2.7.2",
"less-loader": "^4.0.2",
"less-loader": "^4.0.3",
"postcss-css-variables": "^0.7.0",
"postcss-import": "^10.0.0",
"postcss-loader": "^2.0.5",
"style-loader": "^0.15.0",
"url-loader": "^0.5.8",
"web-resource-inliner": "^4.1.0",
@@ -68,10 +72,11 @@
"escodegen": "^1.8.1",
"esmangle": "^1.0.1",
"esprima": "^3.1.3",
"exif-parser": "^0.1.9",
"google-code-prettify": "^1.0.5",
"jquery": "^3.1.1",
"jsbn": "^1.1.0",
"jsrsasign": "^7.1.0",
"jsrsasign": "7.1.3",
"lodash": "^4.17.4",
"moment": "^2.17.1",
"moment-timezone": "^0.5.11",

15
postcss.config.js Normal file
View File

@@ -0,0 +1,15 @@
module.exports = {
plugins: [
require("postcss-import"),
require("autoprefixer")({
browsers: [
"Chrome >= 40",
"Firefox >= 35",
"Edge >= 14"
]
}),
require("postcss-css-variables")({
preserve: true
}),
]
};

View File

@@ -34,7 +34,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 = function(inputText, recipeConfig, options, progress, step) {
Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) {
let startTime = new Date().getTime(),
recipe = new Recipe(recipeConfig),
containsFc = recipe.containsFlowControl(),
@@ -72,7 +72,7 @@ Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step)
}
try {
progress = recipe.execute(this.dish, progress);
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.

View File

@@ -38,7 +38,7 @@ const FlowControl = {
* @param {Operation[]} state.opList - The list of operations in the recipe.
* @returns {Object} The updated state of the recipe.
*/
runFork: function(state) {
runFork: async function(state) {
let opList = state.opList,
inputType = opList[state.progress].inputType,
outputType = opList[state.progress].outputType,
@@ -74,7 +74,7 @@ const FlowControl = {
for (i = 0; i < inputs.length; i++) {
const dish = new Dish(inputs[i], inputType);
try {
progress = recipe.execute(dish, 0);
progress = await recipe.execute(dish, 0);
} catch (err) {
if (!ignoreErrors) {
throw err;

View File

@@ -145,7 +145,7 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
* @param {number} [startFrom=0] - The index of the Operation to start executing from
* @returns {number} - The final progress through the recipe
*/
Recipe.prototype.execute = function(dish, startFrom) {
Recipe.prototype.execute = async function(dish, startFrom) {
startFrom = startFrom || 0;
let op, input, output, numJumps = 0;
@@ -170,11 +170,11 @@ Recipe.prototype.execute = function(dish, startFrom) {
"numJumps" : numJumps
};
state = op.run(state);
state = await op.run(state);
i = state.progress;
numJumps = state.numJumps;
} else {
output = op.run(input, op.getIngValues());
output = await op.run(input, op.getIngValues());
dish.set(output, op.outputType);
}
} catch (err) {

View File

@@ -498,127 +498,6 @@ const Utils = {
},
/**
* Mapping of Unicode code points to Windows-1251
* @private
* @constant
*/
UNIC_WIN1251_MAP: {
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13,
14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24,
25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35,
36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46,
47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57,
58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68,
69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79,
80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90,
91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99, 100: 100, 101: 101,
102: 102, 103: 103, 104: 104, 105: 105, 106: 106, 107: 107, 108: 108, 109: 109, 110: 110,
111: 111, 112: 112, 113: 113, 114: 114, 115: 115, 116: 116, 117: 117, 118: 118, 119: 119,
120: 120, 121: 121, 122: 122, 123: 123, 124: 124, 125: 125, 126: 126, 127: 127, 1027: 129,
8225: 135, 1046: 198, 8222: 132, 1047: 199, 1168: 165, 1048: 200, 1113: 154, 1049: 201,
1045: 197, 1050: 202, 1028: 170, 160: 160, 1040: 192, 1051: 203, 164: 164, 166: 166,
167: 167, 169: 169, 171: 171, 172: 172, 173: 173, 174: 174, 1053: 205, 176: 176, 177: 177,
1114: 156, 181: 181, 182: 182, 183: 183, 8221: 148, 187: 187, 1029: 189, 1056: 208,
1057: 209, 1058: 210, 8364: 136, 1112: 188, 1115: 158, 1059: 211, 1060: 212, 1030: 178,
1061: 213, 1062: 214, 1063: 215, 1116: 157, 1064: 216, 1065: 217, 1031: 175, 1066: 218,
1067: 219, 1068: 220, 1069: 221, 1070: 222, 1032: 163, 8226: 149, 1071: 223, 1072: 224,
8482: 153, 1073: 225, 8240: 137, 1118: 162, 1074: 226, 1110: 179, 8230: 133, 1075: 227,
1033: 138, 1076: 228, 1077: 229, 8211: 150, 1078: 230, 1119: 159, 1079: 231, 1042: 194,
1080: 232, 1034: 140, 1025: 168, 1081: 233, 1082: 234, 8212: 151, 1083: 235, 1169: 180,
1084: 236, 1052: 204, 1085: 237, 1035: 142, 1086: 238, 1087: 239, 1088: 240, 1089: 241,
1090: 242, 1036: 141, 1041: 193, 1091: 243, 1092: 244, 8224: 134, 1093: 245, 8470: 185,
1094: 246, 1054: 206, 1095: 247, 1096: 248, 8249: 139, 1097: 249, 1098: 250, 1044: 196,
1099: 251, 1111: 191, 1055: 207, 1100: 252, 1038: 161, 8220: 147, 1101: 253, 8250: 155,
1102: 254, 8216: 145, 1103: 255, 1043: 195, 1105: 184, 1039: 143, 1026: 128, 1106: 144,
8218: 130, 1107: 131, 8217: 146, 1108: 186, 1109: 190
},
/**
* Mapping of Windows-1251 code points to Unicode
* @private
* @constant
*/
WIN1251_UNIC_MAP: {
0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13,
14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24,
25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35,
36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 44: 44, 45: 45, 46: 46,
47: 47, 48: 48, 49: 49, 50: 50, 51: 51, 52: 52, 53: 53, 54: 54, 55: 55, 56: 56, 57: 57,
58: 58, 59: 59, 60: 60, 61: 61, 62: 62, 63: 63, 64: 64, 65: 65, 66: 66, 67: 67, 68: 68,
69: 69, 70: 70, 71: 71, 72: 72, 73: 73, 74: 74, 75: 75, 76: 76, 77: 77, 78: 78, 79: 79,
80: 80, 81: 81, 82: 82, 83: 83, 84: 84, 85: 85, 86: 86, 87: 87, 88: 88, 89: 89, 90: 90,
91: 91, 92: 92, 93: 93, 94: 94, 95: 95, 96: 96, 97: 97, 98: 98, 99: 99, 100: 100, 101: 101,
102: 102, 103: 103, 104: 104, 105: 105, 106: 106, 107: 107, 108: 108, 109: 109, 110: 110,
111: 111, 112: 112, 113: 113, 114: 114, 115: 115, 116: 116, 117: 117, 118: 118, 119: 119,
120: 120, 121: 121, 122: 122, 123: 123, 124: 124, 125: 125, 126: 126, 127: 127, 160: 160,
164: 164, 166: 166, 167: 167, 169: 169, 171: 171, 172: 172, 173: 173, 174: 174, 176: 176,
177: 177, 181: 181, 182: 182, 183: 183, 187: 187, 168: 1025, 128: 1026, 129: 1027,
170: 1028, 189: 1029, 178: 1030, 175: 1031, 163: 1032, 138: 1033, 140: 1034, 142: 1035,
141: 1036, 161: 1038, 143: 1039, 192: 1040, 193: 1041, 194: 1042, 195: 1043, 196: 1044,
197: 1045, 198: 1046, 199: 1047, 200: 1048, 201: 1049, 202: 1050, 203: 1051, 204: 1052,
205: 1053, 206: 1054, 207: 1055, 208: 1056, 209: 1057, 210: 1058, 211: 1059, 212: 1060,
213: 1061, 214: 1062, 215: 1063, 216: 1064, 217: 1065, 218: 1066, 219: 1067, 220: 1068,
221: 1069, 222: 1070, 223: 1071, 224: 1072, 225: 1073, 226: 1074, 227: 1075, 228: 1076,
229: 1077, 230: 1078, 231: 1079, 232: 1080, 233: 1081, 234: 1082, 235: 1083, 236: 1084,
237: 1085, 238: 1086, 239: 1087, 240: 1088, 241: 1089, 242: 1090, 243: 1091, 244: 1092,
245: 1093, 246: 1094, 247: 1095, 248: 1096, 249: 1097, 250: 1098, 251: 1099, 252: 1100,
253: 1101, 254: 1102, 255: 1103, 184: 1105, 144: 1106, 131: 1107, 186: 1108, 190: 1109,
179: 1110, 191: 1111, 188: 1112, 154: 1113, 156: 1114, 158: 1115, 157: 1116, 162: 1118,
159: 1119, 165: 1168, 180: 1169, 150: 8211, 151: 8212, 145: 8216, 146: 8217, 130: 8218,
147: 8220, 148: 8221, 132: 8222, 134: 8224, 135: 8225, 149: 8226, 133: 8230, 137: 8240,
139: 8249, 155: 8250, 136: 8364, 185: 8470, 153: 8482
},
/**
* Converts a Unicode string to Windows-1251 encoding
*
* @param {string} unicStr
* @returns {string} String encoded in Windows-1251
*
* @example
* // returns "îáíîâëåííàÿ òåõíè÷êà ïî Áîèíãó. îðèãèíàë ó ìåíÿ. çàáåðåòå êîãäà áóäåòå â ÊÈ"
* Utils.unicodeToWin1251("обновленная техничка по Боингу. оригинал у меня. заберете когда будете в КИ");
*/
unicodeToWin1251: function(unicStr) {
const res = [];
for (let i = 0; i < unicStr.length; i++) {
const ord = unicStr.charCodeAt(i);
if (!(ord in Utils.UNIC_WIN1251_MAP))
throw "Character '" + unicStr.charAt(i) + "' isn't supported by Windows-1251";
res.push(String.fromCharCode(Utils.UNIC_WIN1251_MAP[ord]));
}
return res.join("");
},
/**
* Converts a Windows-1251 string to Unicode encoding
*
* @param {string} win1251Str
* @returns {string} String encoded in Unicode
*
* @example
* // returns "обновленная техничка по Боингу. оригинал у меня. заберете когда будете в КИ"
* Utils.unicodeToWin1251("îáíîâëåííàÿ òåõíè÷êà ïî Áîèíãó. îðèãèíàë ó ìåíÿ. çàáåðåòå êîãäà áóäåòå â ÊÈ");
*/
win1251ToUnicode: function(win1251Str) {
const res = [];
for (let i = 0; i < win1251Str.length; i++) {
const ord = win1251Str.charCodeAt(i);
if (!(ord in Utils.WIN1251_UNIC_MAP))
throw "Character '" + win1251Str.charAt(i) + "' isn't supported by Windows-1251";
res.push(String.fromCharCode(Utils.WIN1251_UNIC_MAP[ord]));
}
return res.join("");
},
/**
* Base64's the input byte array using the given alphabet, returning a string.
*

View File

@@ -61,7 +61,8 @@ const Categories = [
"Hex to PEM",
"Parse ASN.1 hex string",
"Change IP format",
"Text encoding",
"Encode text",
"Decode text",
"Swap endianness",
]
},
@@ -143,7 +144,8 @@ const Categories = [
{
name: "Language",
ops: [
"Text encoding",
"Encode text",
"Decode text",
"Unescape Unicode Characters",
]
},
@@ -207,6 +209,7 @@ const Categories = [
"Regular expression",
"XPath expression",
"CSS selector",
"Extract EXIF",
]
},
{
@@ -284,6 +287,7 @@ const Categories = [
"Detect File Type",
"Scan for Embedded Files",
"Generate UUID",
"Render Image",
"Numberwang",
]
},

View File

@@ -15,6 +15,7 @@ import Endian from "../operations/Endian.js";
import Entropy from "../operations/Entropy.js";
import Extract from "../operations/Extract.js";
import FileType from "../operations/FileType.js";
import Image from "../operations/Image.js";
import Hash from "../operations/Hash.js";
import Hexdump from "../operations/Hexdump.js";
import HTML from "../operations/HTML.js";
@@ -886,21 +887,43 @@ const OperationConfig = {
}
]
},
"Text encoding": {
description: "Translates the data between different character encodings.<br><br>Supported charsets are:<ul><li>UTF8</li><li>UTF16</li><li>UTF16LE (little-endian)</li><li>UTF16BE (big-endian)</li><li>Hex</li><li>Base64</li><li>Latin1 (ISO-8859-1)</li><li>Windows-1251</li></ul>",
run: CharEnc.run,
"Encode text": {
description: [
"Encodes text into the chosen character encoding.",
"<br><br>",
"Supported charsets are:",
"<ul>",
Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
"</ul>",
].join("\n"),
run: CharEnc.runEncode,
inputType: "string",
outputType: "byteArray",
args: [
{
name: "Encoding",
type: "option",
value: Object.keys(CharEnc.IO_FORMAT),
},
]
},
"Decode text": {
description: [
"Decodes text from the chosen character encoding.",
"<br><br>",
"Supported charsets are:",
"<ul>",
Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
"</ul>",
].join("\n"),
run: CharEnc.runDecode,
inputType: "byteArray",
outputType: "string",
args: [
{
name: "Input type",
name: "Encoding",
type: "option",
value: CharEnc.IO_FORMAT
},
{
name: "Output type",
type: "option",
value: CharEnc.IO_FORMAT
value: Object.keys(CharEnc.IO_FORMAT),
},
]
},
@@ -921,7 +944,6 @@ const OperationConfig = {
type: "toggleString",
value: "",
toggleValues: Cipher.IO_FORMAT1
},
{
name: "Salt",
@@ -968,7 +990,6 @@ const OperationConfig = {
type: "toggleString",
value: "",
toggleValues: Cipher.IO_FORMAT1
},
{
name: "Salt",
@@ -1401,6 +1422,11 @@ const OperationConfig = {
type: "number",
value: Cipher.KDF_ITERATIONS
},
{
name: "Hashing function",
type: "option",
value: Cipher.HASHERS
},
{
name: "Salt (hex)",
type: "string",
@@ -1434,6 +1460,11 @@ const OperationConfig = {
type: "number",
value: Cipher.KDF_ITERATIONS
},
{
name: "Hashing function",
type: "option",
value: Cipher.HASHERS
},
{
name: "Salt (hex)",
type: "string",
@@ -2213,7 +2244,7 @@ const OperationConfig = {
]
},
"To UNIX Timestamp": {
description: "Parses a datetime string and returns the corresponding UNIX timestamp.<br><br>e.g. <code>Mon 1 January 2001 11:00:00 UTC</code> becomes <code>978346800</code>",
description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.<br><br>e.g. <code>Mon 1 January 2001 11:00:00</code> becomes <code>978346800</code>",
run: DateTime.runToUnixTimestamp,
inputType: "string",
outputType: "number",
@@ -2222,6 +2253,11 @@ const OperationConfig = {
name: "Units",
type: "option",
value: DateTime.UNITS
},
{
name: "Treat as UTC",
type: "boolean",
value: DateTime.TREAT_AS_UTC
}
]
},
@@ -3326,6 +3362,32 @@ const OperationConfig = {
},
]
},
"Extract EXIF": {
description: [
"Extracts EXIF data from an image.",
"<br><br>",
"EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.",
"<br><br>",
"EXIF data from photos usually contains information about the image file itself as well as the device used to create it.",
].join("\n"),
run: Image.runEXIF,
inputType: "byteArray",
outputType: "string",
args: [],
},
"Render Image": {
description: "Displays the input as an image. Supports the following formats:<br><br><ul><li>jpg/jpeg</li><li>png</li><li>gif</li><li>webp</li><li>bmp</li><li>ico</li></ul>",
run: Image.runRenderImage,
inputType: "string",
outputType: "html",
args: [
{
name: "Input format",
type: "option",
value: Image.INPUT_FORMAT
}
]
},
};
export default OperationConfig;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,515 @@
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ft=javascript: */
/*jshint newcap: false */
(function(root, factory) {
"use strict";
if(typeof cptable === "undefined") {
if(typeof require !== "undefined"){
var cpt = require('./cptable');
if (typeof module !== 'undefined' && module.exports) module.exports = factory(cpt);
else root.cptable = factory(cpt);
} else throw new Error("cptable not found");
} else cptable = factory(cptable);
}(this, function(cpt){
"use strict";
var magic = {
"1200":"utf16le",
"1201":"utf16be",
"12000":"utf32le",
"12001":"utf32be",
"16969":"utf64le",
"20127":"ascii",
"65000":"utf7",
"65001":"utf8"
};
var sbcs_cache = [874,1250,1251,1252,1253,1254,1255,1256,10000];
var dbcs_cache = [932,936,949,950];
var magic_cache = [65001];
var magic_decode = {};
var magic_encode = {};
var cpdcache = {};
var cpecache = {};
var sfcc = function sfcc(x) { return String.fromCharCode(x); };
var cca = function cca(x) { return x.charCodeAt(0); };
var has_buf = (typeof Buffer !== 'undefined');
if(has_buf) {
var mdl = 1024, mdb = new Buffer(mdl);
var make_EE = function make_EE(E){
var EE = new Buffer(65536);
for(var i = 0; i < 65536;++i) EE[i] = 0;
var keys = Object.keys(E), len = keys.length;
for(var ee = 0, e = keys[ee]; ee < len; ++ee) {
if(!(e = keys[ee])) continue;
EE[e.charCodeAt(0)] = E[e];
}
return EE;
};
var sbcs_encode = function make_sbcs_encode(cp) {
var EE = make_EE(cpt[cp].enc);
return function sbcs_e(data, ofmt) {
var len = data.length;
var out, i=0, j=0, D=0, w=0;
if(typeof data === 'string') {
out = new Buffer(len);
for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)];
} else if(Buffer.isBuffer(data)) {
out = new Buffer(2*len);
j = 0;
for(i = 0; i < len; ++i) {
D = data[i];
if(D < 128) out[j++] = EE[D];
else if(D < 224) { out[j++] = EE[((D&31)<<6)+(data[i+1]&63)]; ++i; }
else if(D < 240) { out[j++] = EE[((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63)]; i+=2; }
else {
w = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3;
if(w < 65536) out[j++] = EE[w];
else { w -= 65536; out[j++] = EE[0xD800 + ((w>>10)&1023)]; out[j++] = EE[0xDC00 + (w&1023)]; }
}
}
out = out.slice(0,j);
} else {
out = new Buffer(len);
for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)];
}
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
};
var sbcs_decode = function make_sbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c="";
for(d=0;d<D.length;++d) {
if(!(c=D[d])) continue;
var w = c.charCodeAt(0);
DD[2*d] = w&255; DD[2*d+1] = w>>8;
}
return function sbcs_d(data) {
var len = data.length, i=0, j=0;
if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); }
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
} else if(typeof data === "string") {
for(i = 0; i < len; i++) {
j = 2*data.charCodeAt(i);
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
} else {
for(i = 0; i < len; i++) {
j = 2*data[i];
mdb[2*i] = DD[j]; mdb[2*i+1] = DD[j+1];
}
}
return mdb.slice(0, 2 * len).toString('ucs2');
};
};
var dbcs_encode = function make_dbcs_encode(cp) {
var E = cpt[cp].enc;
var EE = new Buffer(131072);
for(var i = 0; i < 131072; ++i) EE[i] = 0;
var keys = Object.keys(E);
for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) {
if(!(e = keys[ee])) continue;
var f = e.charCodeAt(0);
EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8;
}
return function dbcs_e(data, ofmt) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0;
if(typeof data === 'string') {
for(i = k = 0; i < len; ++i) {
j = data.charCodeAt(i)*2;
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
out = out.slice(0,k);
} else if(Buffer.isBuffer(data)) {
for(i = k = 0; i < len; ++i) {
D = data[i];
if(D < 128) j = D;
else if(D < 224) { j = ((D&31)<<6)+(data[i+1]&63); ++i; }
else if(D < 240) { j = ((D&15)<<12)+((data[i+1]&63)<<6)+(data[i+2]&63); i+=2; }
else { j = ((D&7)<<18)+((data[i+1]&63)<<12)+((data[i+2]&63)<<6)+(data[i+3]&63); i+=3; }
if(j<65536) { j*=2; out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j]; }
else { jj = j-65536;
j=2*(0xD800 + ((jj>>10)&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
j=2*(0xDC00 + (jj&1023)); out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
}
out = out.slice(0,k);
} else {
for(i = k = 0; i < len; i++) {
j = data[i].charCodeAt(0)*2;
out[k++] = EE[j+1] || EE[j]; if(EE[j+1] > 0) out[k++] = EE[j];
}
}
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
};
var dbcs_decode = function make_dbcs_decode(cp) {
var D = cpt[cp].dec;
var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0;
for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;}
for(d = 0; d < D.length; ++d) {
if(!(c=D[d])) continue;
w = c.charCodeAt(0);
j = 2*d;
DD[j] = w&255; DD[j+1] = w>>8;
}
return function dbcs_d(data) {
var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0;
if(Buffer.isBuffer(data)) {
for(i = 0; i < len; i++) {
j = 2*data[i];
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
} else if(typeof data === "string") {
for(i = 0; i < len; i++) {
j = 2*data.charCodeAt(i);
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data.charCodeAt(i)<<8)+data.charCodeAt(i+1)); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
} else {
for(i = 0; i < len; i++) {
j = 2*data[i];
if(DD[j]===0xFF && DD[j+1]===0xFD) { j=2*((data[i]<<8)+data[i+1]); ++i; }
out[k++] = DD[j]; out[k++] = DD[j+1];
}
}
return out.slice(0,k).toString('ucs2');
};
};
magic_decode[65001] = function utf8_d(data) {
if(typeof data === "string") return utf8_d(data.split("").map(cca));
var len = data.length, w = 0, ww = 0;
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
var i = 0;
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
j = 1; D = data[i];
if(D < 128) w = D;
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
else if(D < 240) { w=((D&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
else { w=(D&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
if(w < 65536) { mdb[k++] = w&255; mdb[k++] = w>>8; }
else {
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
mdb[k++] = ww&255; mdb[k++] = ww>>>8; mdb[k++] = w&255; mdb[k++] = (w>>>8)&255;
}
}
return mdb.slice(0,k).toString('ucs2');
};
magic_encode[65001] = function utf8_e(data, ofmt) {
if(has_buf && Buffer.isBuffer(data)) {
if(!ofmt || ofmt === 'buf') return data;
if(ofmt !== 'arr') return data.toString('binary');
return [].slice.call(data);
}
var len = data.length, w = 0, ww = 0, j = 0;
var direct = typeof data === "string";
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
for(var i = 0; i < len; ++i) {
w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) mdb[j++] = w;
else if(w <= 0x07FF) {
mdb[j++] = 192 + (w >> 6);
mdb[j++] = 128 + (w&63);
} else if(w >= 0xD800 && w <= 0xDFFF) {
w -= 0xD800; ++i;
ww = (direct ? data.charCodeAt(i) : data[i].charCodeAt(0)) - 0xDC00 + (w << 10);
mdb[j++] = 240 + ((ww>>>18) & 0x07);
mdb[j++] = 144 + ((ww>>>12) & 0x3F);
mdb[j++] = 128 + ((ww>>>6) & 0x3F);
mdb[j++] = 128 + (ww & 0x3F);
} else {
mdb[j++] = 224 + (w >> 12);
mdb[j++] = 128 + ((w >> 6)&63);
mdb[j++] = 128 + (w&63);
}
}
if(!ofmt || ofmt === 'buf') return mdb.slice(0,j);
if(ofmt !== 'arr') return mdb.slice(0,j).toString('binary');
return [].slice.call(mdb, 0, j);
};
}
var encache = function encache() {
if(has_buf) {
if(cpdcache[sbcs_cache[0]]) return;
var i=0, s=0;
for(i = 0; i < sbcs_cache.length; ++i) {
s = sbcs_cache[i];
if(cpt[s]) {
cpdcache[s] = sbcs_decode(s);
cpecache[s] = sbcs_encode(s);
}
}
for(i = 0; i < dbcs_cache.length; ++i) {
s = dbcs_cache[i];
if(cpt[s]) {
cpdcache[s] = dbcs_decode(s);
cpecache[s] = dbcs_encode(s);
}
}
for(i = 0; i < magic_cache.length; ++i) {
s = magic_cache[i];
if(magic_decode[s]) cpdcache[s] = magic_decode[s];
if(magic_encode[s]) cpecache[s] = magic_encode[s];
}
}
};
var null_enc = function(data, ofmt) { return ""; };
var cp_decache = function cp_decache(cp) { delete cpdcache[cp]; delete cpecache[cp]; };
var decache = function decache() {
if(has_buf) {
if(!cpdcache[sbcs_cache[0]]) return;
sbcs_cache.forEach(cp_decache);
dbcs_cache.forEach(cp_decache);
magic_cache.forEach(cp_decache);
}
last_enc = null_enc; last_cp = 0;
};
var cache = {
encache: encache,
decache: decache,
sbcs: sbcs_cache,
dbcs: dbcs_cache
};
encache();
var BM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var SetD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
var last_enc = null_enc, last_cp = 0;
var encode = function encode(cp, data, ofmt) {
if(cp === last_cp && last_enc) { return last_enc(data, ofmt); }
if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); }
if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8');
var len = data.length;
var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0;
var C = cpt[cp], E, M = "";
var isstr = typeof data === 'string';
if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) {
w = E[isstr? data.charAt(i) : data[i]];
if(w > 255) {
out[j] = w>>8;
out[++j] = w&255;
} else out[j] = w&255;
}
else if((M=magic[cp])) switch(M) {
case "utf8":
if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
else if(w <= 0x07FF) {
out[j] = 192 + (w >> 6);
out[++j] = 128 + (w&63);
} else if(w >= 0xD800 && w <= 0xDFFF) {
w -= 0xD800;
ww = (isstr ? data.charCodeAt(++i) : data[++i].charCodeAt(0)) - 0xDC00 + (w << 10);
out[j] = 240 + ((ww>>>18) & 0x07);
out[++j] = 144 + ((ww>>>12) & 0x3F);
out[++j] = 128 + ((ww>>>6) & 0x3F);
out[++j] = 128 + (ww & 0x3F);
} else {
out[j] = 224 + (w >> 12);
out[++j] = 128 + ((w >> 6)&63);
out[++j] = 128 + (w&63);
}
}
break;
case "ascii":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i, ++j) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w <= 0x007F) out[j] = w;
else throw new Error("bad ascii " + w);
}
break;
case "utf16le":
if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; }
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
out[j++] = w&255;
out[j++] = w>>8;
}
break;
case "utf16be":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
out[j++] = w>>8;
out[j++] = w&255;
}
break;
case "utf32le":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
out[j++] = w&255; w >>= 8;
out[j++] = w&255; w >>= 8;
out[j++] = w&255; w >>= 8;
out[j++] = w&255;
}
break;
case "utf32be":
for(i = 0; i < len; ++i) {
w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0);
if(w >= 0xD800 && w <= 0xDFFF) w = 0x10000 + ((w - 0xD800) << 10) + (data[++i].charCodeAt(0) - 0xDC00);
out[j+3] = w&255; w >>= 8;
out[j+2] = w&255; w >>= 8;
out[j+1] = w&255; w >>= 8;
out[j] = w&255;
j+=4;
}
break;
case "utf7":
for(i = 0; i < len; i++) {
var c = isstr ? data.charAt(i) : data[i].charAt(0);
if(c === "+") { out[j++] = 0x2b; out[j++] = 0x2d; continue; }
if(SetD.indexOf(c) > -1) { out[j++] = c.charCodeAt(0); continue; }
var tt = encode(1201, c);
out[j++] = 0x2b;
out[j++] = BM.charCodeAt(tt[0]>>2);
out[j++] = BM.charCodeAt(((tt[0]&0x03)<<4) + ((tt[1]||0)>>4));
out[j++] = BM.charCodeAt(((tt[1]&0x0F)<<2) + ((tt[2]||0)>>6));
out[j++] = 0x2d;
}
break;
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
}
else throw new Error("Unrecognized CP: " + cp);
out = out.slice(0,j);
if(!has_buf) return (ofmt == 'str') ? (out).map(sfcc).join("") : out;
if(!ofmt || ofmt === 'buf') return out;
if(ofmt !== 'arr') return out.toString('binary');
return [].slice.call(out);
};
var decode = function decode(cp, data) {
var F; if((F=cpdcache[cp])) return F(data);
if(typeof data === "string") return decode(cp, data.split("").map(cca));
var len = data.length, out = new Array(len), s="", w=0, i=0, j=1, k=0, ww=0;
var C = cpt[cp], D, M="";
if(C && (D=C.dec)) {
for(i = 0; i < len; i+=j) {
j = 2;
s = D[(data[i]<<8)+ data[i+1]];
if(!s) {
j = 1;
s = D[data[i]];
}
if(!s) throw new Error('Unrecognized code: ' + data[i] + ' ' + data[i+j-1] + ' ' + i + ' ' + j + ' ' + D[data[i]]);
out[k++] = s;
}
}
else if((M=magic[cp])) switch(M) {
case "utf8":
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(; i < len; i+=j) {
j = 1;
if(data[i] < 128) w = data[i];
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
else if(data[i] < 240) { w=((data[i]&15)<<12)+(data[i+1]&63)*64+(data[i+2]&63); j=3; }
else { w=(data[i]&7)*262144+((data[i+1]&63)<<12)+(data[i+2]&63)*64+(data[i+3]&63); j=4; }
if(w < 65536) { out[k++] = String.fromCharCode(w); }
else {
w -= 65536; ww = 0xD800 + ((w>>10)&1023); w = 0xDC00 + (w&1023);
out[k++] = String.fromCharCode(ww); out[k++] = String.fromCharCode(w);
}
}
break;
case "ascii":
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
k = len; break;
case "utf16le":
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
if(has_buf && Buffer.isBuffer(data)) return data.toString(M);
j = 2;
for(; i+1 < len; i+=j) {
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
}
break;
case "utf16be":
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
j = 2;
for(; i+1 < len; i+=j) {
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
}
break;
case "utf32le":
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] === 0 && data[3] === 0) i = 4;
j = 4;
for(; i < len; i+=j) {
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
if(w > 0xFFFF) {
w -= 0x10000;
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
}
else out[k++] = String.fromCharCode(w);
}
break;
case "utf32be":
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] === 0 && data[0] === 0) i = 4;
j = 4;
for(; i < len; i+=j) {
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
if(w > 0xFFFF) {
w -= 0x10000;
out[k++] = String.fromCharCode(0xD800 + ((w >> 10) & 0x3FF));
out[k++] = String.fromCharCode(0xDC00 + (w & 0x3FF));
}
else out[k++] = String.fromCharCode(w);
}
break;
case "utf7":
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
}
for(; i < len; i+=j) {
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
j=1;
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }
while(String.fromCharCode(data[i+j]).match(/[A-Za-z0-9+\/]/)) j++;
var dash = 0;
if(data[i+j] === 0x2d) { ++j; dash=1; }
var tt = [];
var o64 = "";
var c1=0, c2=0, c3=0;
var e1=0, e2=0, e3=0, e4=0;
for(var l = 1; l < j - dash;) {
e1 = BM.indexOf(String.fromCharCode(data[i+l++]));
e2 = BM.indexOf(String.fromCharCode(data[i+l++]));
c1 = e1 << 2 | e2 >> 4;
tt.push(c1);
e3 = BM.indexOf(String.fromCharCode(data[i+l++]));
if(e3 === -1) break;
c2 = (e2 & 15) << 4 | e3 >> 2;
tt.push(c2);
e4 = BM.indexOf(String.fromCharCode(data[i+l++]));
if(e4 === -1) break;
c3 = (e3 & 3) << 6 | e4;
if(e4 < 64) tt.push(c3);
}
o64 = decode(1201, tt);
for(l = 0; l < o64.length; ++l) out[k++] = o64.charAt(l);
}
break;
default: throw new Error("Unsupported magic: " + cp + " " + magic[cp]);
}
else throw new Error("Unrecognized CP: " + cp);
return out.slice(0,k).join("");
};
var hascp = function hascp(cp) { return !!(cpt[cp] || magic[cp]); };
cpt.utils = { decode: decode, encode: encode, hascp: hascp, magic: magic, cache:cache };
return cpt;
}));

View File

@@ -1,3 +1,4 @@
import cptable from "../lib/js-codepage/cptable.js";
import Utils from "../Utils.js";
import CryptoJS from "crypto-js";
@@ -17,34 +18,82 @@ const CharEnc = {
* @constant
* @default
*/
IO_FORMAT: ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Windows-1251", "Hex", "Base64"],
IO_FORMAT: {
"UTF-8 (65001)": 65001,
"UTF-7 (65000)": 65000,
"UTF16LE (1200)": 1200,
"UTF16BE (1201)": 1201,
"UTF16 (1201)": 1201,
"IBM EBCDIC International (500)": 500,
"IBM EBCDIC US-Canada (37)": 37,
"Windows-874 Thai (874)": 874,
"Japanese Shift-JIS (932)": 932,
"Simplified Chinese GBK (936)": 936,
"Korean (949)": 949,
"Traditional Chinese Big5 (950)": 950,
"Windows-1250 Central European (1250)": 1250,
"Windows-1251 Cyrillic (1251)": 1251,
"Windows-1252 Latin (1252)": 1252,
"Windows-1253 Greek (1253)": 1253,
"Windows-1254 Turkish (1254)": 1254,
"Windows-1255 Hebrew (1255)": 1255,
"Windows-1256 Arabic (1256)": 1256,
"Windows-1257 Baltic (1257)": 1257,
"Windows-1258 Vietnam (1258)": 1258,
"US-ASCII (20127)": 20127,
"Simplified Chinese GB2312 (20936)": 20936,
"KOI8-R Russian Cyrillic (20866)": 20866,
"KOI8-U Ukrainian Cyrillic (21866)": 21866,
"ISO-8859-1 Latin 1 Western European (28591)": 28591,
"ISO-8859-2 Latin 2 Central European (28592)": 28592,
"ISO-8859-3 Latin 3 South European (28593)": 28593,
"ISO-8859-4 Latin 4 North European (28594)": 28594,
"ISO-8859-5 Latin/Cyrillic (28595)": 28595,
"ISO-8859-6 Latin/Arabic (28596)": 28596,
"ISO-8859-7 Latin/Greek (28597)": 28597,
"ISO-8859-8 Latin/Hebrew (28598)": 28598,
"ISO-8859-9 Latin 5 Turkish (28599)": 28599,
"ISO-8859-10 Latin 6 Nordic (28600)": 28600,
"ISO-8859-11 Latin/Thai (28601)": 28601,
"ISO-8859-13 Latin 7 Baltic Rim (28603)": 28603,
"ISO-8859-14 Latin 8 Celtic (28604)": 28604,
"ISO-8859-15 Latin 9 (28605)": 28605,
"ISO-8859-16 Latin 10 (28606)": 28606,
"ISO-2022 JIS Japanese (50222)": 50222,
"EUC Japanese (51932)": 51932,
"EUC Korean (51949)": 51949,
"Simplified Chinese GB18030 (54936)": 54936,
},
/**
* Text encoding operation.
* Encode text operation.
* @author tlwr [toby@toby.codes]
*
* @param {string} input
* @param {Object[]} args
* @returns {string}
* @returns {byteArray}
*/
run: function(input, args) {
let inputFormat = args[0],
outputFormat = args[1];
if (inputFormat === "Windows-1251") {
input = Utils.win1251ToUnicode(input);
input = CryptoJS.enc.Utf8.parse(input);
} else {
input = Utils.format[inputFormat].parse(input);
}
if (outputFormat === "Windows-1251") {
input = CryptoJS.enc.Utf8.stringify(input);
return Utils.unicodeToWin1251(input);
} else {
return Utils.format[outputFormat].stringify(input);
}
runEncode: function(input, args) {
const format = CharEnc.IO_FORMAT[args[0]];
let encoded = cptable.utils.encode(format, input);
encoded = Array.from(encoded);
return encoded;
},
/**
* Decode text operation.
* @author tlwr [toby@toby.codes]
*
* @param {byteArray} input
* @param {Object[]} args
* @returns {string}
*/
runDecode: function(input, args) {
const format = CharEnc.IO_FORMAT[args[0]];
let decoded = cptable.utils.decode(format, input);
return decoded;
},
};
export default CharEnc;

View File

@@ -309,6 +309,11 @@ const Cipher = {
* @default
*/
KDF_ITERATIONS: 1,
/**
* @constant
* @default
*/
HASHERS: ["MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "RIPEMD160"],
/**
* Derive PBKDF2 key operation.
@@ -320,11 +325,16 @@ const Cipher = {
runPbkdf2: function (input, args) {
let keySize = args[0] / 32,
iterations = args[1],
salt = CryptoJS.enc.Hex.parse(args[2] || ""),
inputFormat = args[3],
outputFormat = args[4],
hasher = args[2],
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
inputFormat = args[4],
outputFormat = args[5],
passphrase = Utils.format[inputFormat].parse(input),
key = CryptoJS.PBKDF2(passphrase, salt, { keySize: keySize, iterations: iterations });
key = CryptoJS.PBKDF2(passphrase, salt, {
keySize: keySize,
hasher: CryptoJS.algo[hasher],
iterations: iterations,
});
return key.toString(Utils.format[outputFormat]);
},
@@ -340,11 +350,16 @@ const Cipher = {
runEvpkdf: function (input, args) {
let keySize = args[0] / 32,
iterations = args[1],
salt = CryptoJS.enc.Hex.parse(args[2] || ""),
inputFormat = args[3],
outputFormat = args[4],
hasher = args[2],
salt = CryptoJS.enc.Hex.parse(args[3] || ""),
inputFormat = args[4],
outputFormat = args[5],
passphrase = Utils.format[inputFormat].parse(input),
key = CryptoJS.EvpKDF(passphrase, salt, { keySize: keySize, iterations: iterations });
key = CryptoJS.EvpKDF(passphrase, salt, {
keySize: keySize,
hasher: CryptoJS.algo[hasher],
iterations: iterations,
});
return key.toString(Utils.format[outputFormat]);
},

View File

@@ -426,7 +426,7 @@ const Code = {
* @returns {string}
*/
_replaceVariableNames(input, replacer) {
let tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/ig;
const tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/ig;
return input.replace(tokenRegex, (...args) => {
let match = args[0],
@@ -450,7 +450,7 @@ const Code = {
*
*/
runToSnakeCase(input, args) {
let smart = args[0];
const smart = args[0];
if (smart) {
return Code._replaceVariableNames(input, snakeCase);
@@ -469,7 +469,7 @@ const Code = {
*
*/
runToCamelCase(input, args) {
let smart = args[0];
const smart = args[0];
if (smart) {
return Code._replaceVariableNames(input, camelCase);
@@ -488,7 +488,7 @@ const Code = {
*
*/
runToKebabCase(input, args) {
let smart = args[0];
const smart = args[0];
if (smart) {
return Code._replaceVariableNames(input, kebabCase);

View File

@@ -46,6 +46,12 @@ const DateTime = {
},
/**
* @constant
* @default
*/
TREAT_AS_UTC: true,
/**
* To UNIX Timestamp operation.
*
@@ -55,7 +61,8 @@ const DateTime = {
*/
runToUnixTimestamp: function(input, args) {
let units = args[0],
d = moment(input);
treatAsUTC = args[1],
d = treatAsUTC ? moment.utc(input) : moment(input);
if (units === "Seconds (s)") {
return d.unix();

View File

@@ -20,7 +20,7 @@ const FileType = {
* @returns {string}
*/
runDetect: function(input, args) {
const type = FileType._magicType(input);
const type = FileType.magicType(input);
if (!type) {
return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
@@ -59,7 +59,7 @@ const FileType = {
numCommonFound = 0;
for (let i = 0; i < input.length; i++) {
type = FileType._magicType(input.slice(i));
type = FileType.magicType(input.slice(i));
if (type) {
if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
numCommonFound++;
@@ -96,14 +96,13 @@ const FileType = {
* Given a buffer, detects magic byte sequences at specific positions and returns the
* extension and mime type.
*
* @private
* @param {byteArray} buf
* @returns {Object} type
* @returns {string} type.ext - File extension
* @returns {string} type.mime - Mime type
* @returns {string} [type.desc] - Description
*/
_magicType: function (buf) {
magicType: function (buf) {
if (!(buf && buf.length > 1)) {
return null;
}

View File

@@ -0,0 +1,99 @@
import * as ExifParser from "exif-parser";
import Utils from "../Utils.js";
import FileType from "./FileType.js";
/**
* Image operations.
*
* @author tlwr [toby@toby.codes]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*
* @namespace
*/
const Image = {
/**
* Extract EXIF operation.
*
* Extracts EXIF data from a byteArray, representing a JPG or a TIFF image.
*
* @param {byteArray} input
* @param {Object[]} args
* @returns {string}
*/
runEXIF(input, args) {
try {
const bytes = Uint8Array.from(input);
const parser = ExifParser.create(bytes.buffer);
const result = parser.parse();
let lines = [];
for (let tagName in result.tags) {
let value = result.tags[tagName];
lines.push(`${tagName}: ${value}`);
}
const numTags = lines.length;
lines.unshift(`Found ${numTags} tags.\n`);
return lines.join("\n");
} catch (err) {
throw "Could not extract EXIF data from image: " + err;
}
},
/**
* @constant
* @default
*/
INPUT_FORMAT: ["Raw", "Base64", "Hex"],
/**
* Render Image operation.
*
* @author n1474335 [n1474335@gmail.com]
* @param {string} input
* @param {Object[]} args
* @returns {html}
*/
runRenderImage(input, args) {
const inputFormat = args[0];
let dataURI = "data:";
if (!input.length) return "";
// Convert input to raw bytes
switch (inputFormat) {
case "Hex":
input = Utils.fromHex(input);
break;
case "Base64":
// Don't trust the Base64 entered by the user.
// Unwrap it first, then re-encode later.
input = Utils.fromBase64(input, null, "byteArray");
break;
case "Raw":
default:
input = Utils.strToByteArray(input);
break;
}
// Determine file type
const type = FileType.magicType(input);
if (type && type.mime.indexOf("image") === 0) {
dataURI += type.mime + ";";
} else {
throw "Invalid file type";
}
// Add image data to URI
dataURI += "base64," + Utils.toBase64(input);
return "<img src='" + dataURI + "'>";
},
};
export default Image;

View File

@@ -124,10 +124,17 @@ const PublicKey = {
}
// Signature fields
if (r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0) { // DSA or ECDSA
let breakoutSig = false;
try {
breakoutSig = r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0;
} catch (err) {
// Error processing signature, output without further breakout
}
if (breakoutSig) { // DSA or ECDSA
sigStr = " r: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [0]), 16, 18) + "\n" +
" s: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [1]), 16, 18) + "\n";
} else { // RSA
} else { // RSA or unknown
sigStr = " Signature: " + PublicKey._formatByteStr(certSig, 16, 18) + "\n";
}

View File

@@ -471,7 +471,7 @@ const StrUtils = {
number = args[1];
delimiter = Utils.charRep[delimiter];
let splitInput = input.split(delimiter);
const splitInput = input.split(delimiter);
return splitInput
.filter((line, lineIndex) => {
@@ -499,7 +499,7 @@ const StrUtils = {
number = args[1];
delimiter = Utils.charRep[delimiter];
let splitInput = input.split(delimiter);
const splitInput = input.split(delimiter);
return splitInput
.filter((line, lineIndex) => {

View File

@@ -30,6 +30,7 @@ const App = function(categories, operations, defaultFavourites, defaultOptions)
this.chef = new Chef();
this.manager = new Manager(this);
this.baking = false;
this.autoBake_ = false;
this.progress = 0;
this.ingId = 0;
@@ -52,6 +53,26 @@ App.prototype.setup = function() {
this.resetLayout();
this.setCompileMessage();
this.loadURIParams();
this.loaded();
};
/**
* Fires once all setup activities have completed.
*/
App.prototype.loaded = function() {
// Trigger CSS animations to remove preloader
document.body.classList.add("loaded");
// Wait for animations to complete then remove the preloader and loaded style
// so that the animations for existing elements don't play again.
setTimeout(function() {
document.getElementById("loader-wrapper").remove();
document.body.classList.remove("loaded");
}, 1000);
// Clear the loading message interval
clearInterval(window.loadingMsgInt);
};
@@ -67,17 +88,47 @@ App.prototype.handleError = function(err) {
};
/**
* Updates the UI to show if baking is in process or not.
*
* @param {bakingStatus}
*/
App.prototype.setBakingStatus = function(bakingStatus) {
this.baking = bakingStatus;
let inputLoadingIcon = document.querySelector("#input .title .loading-icon"),
outputLoadingIcon = document.querySelector("#output .title .loading-icon"),
outputElement = document.querySelector("#output-text");
if (bakingStatus) {
inputLoadingIcon.style.display = "inline-block";
outputLoadingIcon.style.display = "inline-block";
outputElement.classList.add("disabled");
outputElement.disabled = true;
} else {
inputLoadingIcon.style.display = "none";
outputLoadingIcon.style.display = "none";
outputElement.classList.remove("disabled");
outputElement.disabled = false;
}
};
/**
* Calls the Chef to bake the current input using the current recipe.
*
* @param {boolean} [step] - Set to true if we should only execute one operation instead of the
* whole recipe.
*/
App.prototype.bake = function(step) {
App.prototype.bake = async function(step) {
let response;
if (this.baking) return;
this.setBakingStatus(true);
try {
response = this.chef.bake(
response = await this.chef.bake(
this.getInput(), // The user's input
this.getRecipeConfig(), // The configuration of the recipe
this.options, // Options set by the user
@@ -88,6 +139,8 @@ App.prototype.bake = function(step) {
this.handleError(err);
}
this.setBakingStatus(false);
if (!response) return;
if (response.error) {

View File

@@ -23,14 +23,14 @@ const ControlsWaiter = function(app, manager) {
* without wrapping or overflowing.
*/
ControlsWaiter.prototype.adjustWidth = function() {
let controls = document.getElementById("controls"),
step = document.getElementById("step"),
clrBreaks = document.getElementById("clr-breaks"),
saveImg = document.querySelector("#save img"),
loadImg = document.querySelector("#load img"),
stepImg = document.querySelector("#step img"),
clrRecipImg = document.querySelector("#clr-recipe img"),
clrBreaksImg = document.querySelector("#clr-breaks img");
const controls = document.getElementById("controls");
const step = document.getElementById("step");
const clrBreaks = document.getElementById("clr-breaks");
const saveImg = document.querySelector("#save img");
const loadImg = document.querySelector("#load img");
const stepImg = document.querySelector("#step img");
const clrRecipImg = document.querySelector("#clr-recipe img");
const clrBreaksImg = document.querySelector("#clr-breaks img");
if (controls.clientWidth < 470) {
step.childNodes[1].nodeValue = " Step";
@@ -100,17 +100,17 @@ ControlsWaiter.prototype.stepClick = function() {
* Handler for changes made to the Auto Bake checkbox.
*/
ControlsWaiter.prototype.autoBakeChange = function() {
let autoBakeLabel = document.getElementById("auto-bake-label"),
autoBakeCheckbox = document.getElementById("auto-bake");
const autoBakeLabel = document.getElementById("auto-bake-label");
const autoBakeCheckbox = document.getElementById("auto-bake");
this.app.autoBake_ = autoBakeCheckbox.checked;
if (autoBakeCheckbox.checked) {
autoBakeLabel.classList.remove("btn-default");
autoBakeLabel.classList.add("btn-success");
autoBakeLabel.classList.remove("btn-default");
} else {
autoBakeLabel.classList.remove("btn-success");
autoBakeLabel.classList.add("btn-default");
autoBakeLabel.classList.remove("btn-success");
}
};
@@ -145,10 +145,10 @@ ControlsWaiter.prototype.clearBreaksClick = function() {
ControlsWaiter.prototype.initialiseSaveLink = function(recipeConfig) {
recipeConfig = recipeConfig || this.app.getRecipeConfig();
let includeRecipe = document.getElementById("save-link-recipe-checkbox").checked,
includeInput = document.getElementById("save-link-input-checkbox").checked,
saveLinkEl = document.getElementById("save-link"),
saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig);
const includeRecipe = document.getElementById("save-link-recipe-checkbox").checked;
const includeInput = document.getElementById("save-link-input-checkbox").checked;
const saveLinkEl = document.getElementById("save-link");
const saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig);
saveLinkEl.innerHTML = Utils.truncate(saveLink, 120);
saveLinkEl.setAttribute("href", saveLink);
@@ -167,23 +167,27 @@ ControlsWaiter.prototype.initialiseSaveLink = function(recipeConfig) {
ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput, recipeConfig, baseURL) {
recipeConfig = recipeConfig || this.app.getRecipeConfig();
let link = baseURL || window.location.protocol + "//" +
const link = baseURL || window.location.protocol + "//" +
window.location.host +
window.location.pathname,
recipeStr = JSON.stringify(recipeConfig),
inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
window.location.pathname;
const recipeStr = JSON.stringify(recipeConfig);
const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
includeRecipe = includeRecipe && (recipeConfig.length > 0);
includeInput = includeInput && (inputStr.length > 0) && (inputStr.length < 8000);
if (includeRecipe) {
link += "?recipe=" + encodeURIComponent(recipeStr);
}
const params = [
includeRecipe ? ["recipe", recipeStr] : undefined,
includeInput ? ["input", inputStr] : undefined,
];
if (includeRecipe && includeInput) {
link += "&input=" + encodeURIComponent(inputStr);
} else if (includeInput) {
link += "?input=" + encodeURIComponent(inputStr);
const query = params
.filter(v => v)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join("&");
if (query) {
return `${link}?${query}`;
}
return link;
@@ -205,8 +209,8 @@ ControlsWaiter.prototype.saveTextChange = function() {
* Handler for the 'Save' command. Pops up the save dialog box.
*/
ControlsWaiter.prototype.saveClick = function() {
let recipeConfig = this.app.getRecipeConfig(),
recipeStr = JSON.stringify(recipeConfig).replace(/},{/g, "},\n{");
const recipeConfig = this.app.getRecipeConfig();
const recipeStr = JSON.stringify(recipeConfig).replace(/},{/g, "},\n{");
document.getElementById("save-text").value = recipeStr;
@@ -244,8 +248,8 @@ ControlsWaiter.prototype.loadClick = function() {
* Saves the recipe specified in the save textarea to local storage.
*/
ControlsWaiter.prototype.saveButtonClick = function() {
let recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
let recipeStr = document.getElementById("save-text").value;
const recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
const recipeStr = document.getElementById("save-text").value;
if (!recipeName) {
this.app.alert("Please enter a recipe name", "danger", 2000);
@@ -303,13 +307,11 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
* Removes the currently selected recipe from local storage.
*/
ControlsWaiter.prototype.loadDeleteClick = function() {
let id = parseInt(document.getElementById("load-name").value, 10),
savedRecipes = localStorage.savedRecipes ?
const id = parseInt(document.getElementById("load-name").value, 10);
const rawSavedRecipes = localStorage.savedRecipes ?
JSON.parse(localStorage.savedRecipes) : [];
savedRecipes = savedRecipes.filter(function(r) {
return r.id !== id;
});
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
localStorage.savedRecipes = JSON.stringify(savedRecipes);
this.populateLoadRecipesList();
@@ -320,14 +322,12 @@ ControlsWaiter.prototype.loadDeleteClick = function() {
* Displays the selected recipe in the load text box.
*/
ControlsWaiter.prototype.loadNameChange = function(e) {
let el = e.target,
savedRecipes = localStorage.savedRecipes ?
JSON.parse(localStorage.savedRecipes) : [],
id = parseInt(el.value, 10);
const el = e.target;
const savedRecipes = localStorage.savedRecipes ?
JSON.parse(localStorage.savedRecipes) : [];
const id = parseInt(el.value, 10);
const recipe = savedRecipes.filter(function(r) {
return r.id === id;
})[0];
const recipe = savedRecipes.find(r => r.id === id);
document.getElementById("load-text").value = recipe.recipe;
};
@@ -352,8 +352,8 @@ ControlsWaiter.prototype.loadButtonClick = function() {
* Populates the bug report information box with useful technical info.
*/
ControlsWaiter.prototype.supportButtonClick = function() {
let reportBugInfo = document.getElementById("report-bug-info"),
saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
const reportBugInfo = document.getElementById("report-bug-info");
const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/");
reportBugInfo.innerHTML = "* CyberChef compile time: " + COMPILE_TIME + "\n" +
"* User-Agent: \n" + navigator.userAgent + "\n" +

View File

@@ -158,13 +158,12 @@ HTMLIngredient.prototype.toHtml = function() {
* @param {event} e
*/
HTMLIngredient.prototype.toggleDisableArgs = function(e) {
let el = e.target,
op = el.parentNode.parentNode,
args = op.querySelectorAll(".arg-group"),
els;
const el = e.target;
const op = el.parentNode.parentNode;
const args = op.querySelectorAll(".arg-group");
for (let i = 0; i < this.disableArgs.length; i++) {
els = args[this.disableArgs[i]].querySelectorAll("input, select, button");
const els = args[this.disableArgs[i]].querySelectorAll("input, select, button");
for (let j = 0; j < els.length; j++) {
if (els[j].getAttribute("disabled")) {
@@ -186,9 +185,9 @@ HTMLIngredient.prototype.toggleDisableArgs = function(e) {
* @param {event} e
*/
HTMLIngredient.prototype.populateOptionChange = function(e) {
let el = e.target,
op = el.parentNode.parentNode,
target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea");
const el = e.target;
const op = el.parentNode.parentNode;
const target = op.querySelectorAll(".arg-group")[this.target].querySelector("input, select, textarea");
target.value = el.childNodes[el.selectedIndex].getAttribute("populate-value");

View File

@@ -64,8 +64,8 @@ HighlighterWaiter.prototype._isSelectionBackwards = function() {
* @returns {number}
*/
HighlighterWaiter.prototype._getOutputHtmlOffset = function(node, offset) {
let sel = window.getSelection(),
range = document.createRange();
const sel = window.getSelection();
const range = document.createRange();
range.selectNodeContents(document.getElementById("output-html"));
range.setEnd(node, offset);
@@ -85,8 +85,8 @@ HighlighterWaiter.prototype._getOutputHtmlOffset = function(node, offset) {
* @returns {number} pos.end
*/
HighlighterWaiter.prototype._getOutputHtmlSelectionOffsets = function() {
let sel = window.getSelection(),
range,
const sel = window.getSelection();
let range,
start = 0,
end = 0,
backwards = false;
@@ -151,9 +151,9 @@ HighlighterWaiter.prototype.inputMousedown = function(e) {
this.mouseTarget = HighlighterWaiter.INPUT;
this.removeHighlights();
let el = e.target,
start = el.selectionStart,
end = el.selectionEnd;
const el = e.target;
const start = el.selectionStart;
const end = el.selectionEnd;
if (start !== 0 || end !== 0) {
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
@@ -173,9 +173,9 @@ HighlighterWaiter.prototype.outputMousedown = function(e) {
this.mouseTarget = HighlighterWaiter.OUTPUT;
this.removeHighlights();
let el = e.target,
start = el.selectionStart,
end = el.selectionEnd;
const el = e.target;
const start = el.selectionStart;
const end = el.selectionEnd;
if (start !== 0 || end !== 0) {
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end);
@@ -244,9 +244,9 @@ HighlighterWaiter.prototype.inputMousemove = function(e) {
this.mouseTarget !== HighlighterWaiter.INPUT)
return;
let el = e.target,
start = el.selectionStart,
end = el.selectionEnd;
const el = e.target;
const start = el.selectionStart;
const end = el.selectionEnd;
if (start !== 0 || end !== 0) {
document.getElementById("input-selection-info").innerHTML = this.selectionInfo(start, end);
@@ -268,9 +268,9 @@ HighlighterWaiter.prototype.outputMousemove = function(e) {
this.mouseTarget !== HighlighterWaiter.OUTPUT)
return;
let el = e.target,
start = el.selectionStart,
end = el.selectionEnd;
const el = e.target;
const start = el.selectionStart;
const end = el.selectionEnd;
if (start !== 0 || end !== 0) {
document.getElementById("output-selection-info").innerHTML = this.selectionInfo(start, end);
@@ -308,11 +308,11 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) {
* @returns {string}
*/
HighlighterWaiter.prototype.selectionInfo = function(start, end) {
let width = end.toString().length;
width = width < 2 ? 2 : width;
let startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, "&nbsp;"),
endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, "&nbsp;"),
lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, "&nbsp;");
const len = end.toString().length;
const width = len < 2 ? 2 : len;
const startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, "&nbsp;");
const endStr = Utils.pad(end.toString(), width, " ").replace(/ /g, "&nbsp;");
const lenStr = Utils.pad((end-start).toString(), width, " ").replace(/ /g, "&nbsp;");
return "start: " + startStr + "<br>end: " + endStr + "<br>length: " + lenStr;
};
@@ -339,8 +339,8 @@ HighlighterWaiter.prototype.removeHighlights = function() {
* @returns {Object[]} highlights[].args
*/
HighlighterWaiter.prototype.generateHighlightList = function() {
let recipeConfig = this.app.getRecipeConfig(),
highlights = [];
const recipeConfig = this.app.getRecipeConfig();
const highlights = [];
for (let i = 0; i < recipeConfig.length; i++) {
if (recipeConfig[i].disabled) continue;
@@ -452,11 +452,11 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
// be displayed by the HTML textarea and will mess up highlighting offsets.
if (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false;
let startPlaceholder = "[startHighlight]",
startPlaceholderRegex = /\[startHighlight\]/g,
endPlaceholder = "[endHighlight]",
endPlaceholderRegex = /\[endHighlight\]/g,
text = textarea.value;
const startPlaceholder = "[startHighlight]";
const startPlaceholderRegex = /\[startHighlight\]/g;
const endPlaceholder = "[endHighlight]";
const endPlaceholderRegex = /\[endHighlight\]/g;
let text = textarea.value;
// Put placeholders in position
// If there's only one value, select that

View File

@@ -92,8 +92,8 @@ InputWaiter.prototype.inputChange = function(e) {
this.app.progress = 0;
// Update the input metadata info
let inputText = this.get(),
lines = inputText.count("\n") + 1;
const inputText = this.get();
const lines = inputText.count("\n") + 1;
this.setInputInfo(inputText.length, lines);
@@ -149,13 +149,13 @@ InputWaiter.prototype.inputDrop = function(e) {
e.stopPropagation();
e.preventDefault();
let el = e.target,
file = e.dataTransfer.files[0],
text = e.dataTransfer.getData("Text"),
reader = new FileReader(),
inputCharcode = "",
offset = 0,
CHUNK_SIZE = 20480; // 20KB
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() {
if (inputCharcode.length > 100000 && this.app.autoBake_) {

View File

@@ -154,6 +154,7 @@ Manager.prototype.initialiseEventListeners = function() {
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));
// Misc
document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
@@ -261,15 +262,16 @@ Manager.prototype.addDynamicListener = function(selector, eventType, callback, s
* @param {Event} e - The event to be handled
*/
Manager.prototype.dynamicListenerHandler = function(e) {
let handlers = this.dynamicHandlers[e.type],
matches = e.target.matches ||
e.target.webkitMatchesSelector ||
e.target.mozMatchesSelector ||
e.target.msMatchesSelector ||
e.target.oMatchesSelector;
const { type, target } = e;
const handlers = this.dynamicHandlers[type];
const matches = target.matches ||
target.webkitMatchesSelector ||
target.mozMatchesSelector ||
target.msMatchesSelector ||
target.oMatchesSelector;
for (let i = 0; i < handlers.length; i++) {
if (matches && e.target[matches.name](handlers[i].selector)) {
if (matches && matches.call(target, handlers[i].selector)) {
handlers[i].callback(e);
}
}

View File

@@ -68,9 +68,9 @@ OperationsWaiter.prototype.searchOperations = function(e) {
ops[selected-1].classList.add("selected-op");
}
} else {
let searchResultsEl = document.getElementById("search-results"),
el = e.target,
str = el.value;
const searchResultsEl = document.getElementById("search-results");
const el = e.target;
const str = el.value;
while (searchResultsEl.firstChild) {
try {
@@ -81,12 +81,10 @@ OperationsWaiter.prototype.searchOperations = function(e) {
$("#categories .in").collapse("hide");
if (str) {
let matchedOps = this.filterOperations(str, true),
matchedOpsHtml = "";
for (let i = 0; i < matchedOps.length; i++) {
matchedOpsHtml += matchedOps[i].toStubHtml();
}
const matchedOps = this.filterOperations(str, true);
const matchedOpsHtml = matchedOps
.map(v => v.toStubHtml())
.join("");
searchResultsEl.innerHTML = matchedOpsHtml;
searchResultsEl.dispatchEvent(this.manager.oplistcreate);
@@ -103,16 +101,16 @@ OperationsWaiter.prototype.searchOperations = function(e) {
* name and description
* @returns {string[]}
*/
OperationsWaiter.prototype.filterOperations = function(searchStr, highlight) {
let matchedOps = [],
matchedDescs = [];
OperationsWaiter.prototype.filterOperations = function(inStr, highlight) {
const matchedOps = [];
const matchedDescs = [];
searchStr = searchStr.toLowerCase();
const searchStr = inStr.toLowerCase();
for (const opName in this.app.operations) {
let op = this.app.operations[opName],
namePos = opName.toLowerCase().indexOf(searchStr),
descPos = op.description.toLowerCase().indexOf(searchStr);
const op = this.app.operations[opName];
const namePos = opName.toLowerCase().indexOf(searchStr);
const descPos = op.description.toLowerCase().indexOf(searchStr);
if (namePos >= 0 || descPos >= 0) {
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
@@ -236,12 +234,8 @@ OperationsWaiter.prototype.editFavouritesClick = function(e) {
* Saves the selected favourites and reloads them.
*/
OperationsWaiter.prototype.saveFavouritesClick = function() {
let favouritesList = [],
favs = document.querySelectorAll("#edit-favourites-list li");
for (let i = 0; i < favs.length; i++) {
favouritesList.push(favs[i].textContent);
}
const favs = document.querySelectorAll("#edit-favourites-list li");
const favouritesList = Array.from(favs, e => e.textContent);
this.app.saveFavourites(favouritesList);
this.app.loadFavourites();
@@ -281,8 +275,8 @@ OperationsWaiter.prototype.opIconMouseover = function(e) {
* @param {event} e
*/
OperationsWaiter.prototype.opIconMouseleave = function(e) {
let opEl = e.target.parentNode,
toEl = e.toElement || e.relatedElement;
const opEl = e.target.parentNode;
const toEl = e.toElement || e.relatedElement;
if (e.target.getAttribute("data-toggle") === "popover" && toEl === opEl) {
$(opEl).popover("show");

View File

@@ -43,9 +43,12 @@ OptionsWaiter.prototype.load = function(options) {
const selects = document.querySelectorAll("#options-body select");
for (i = 0; i < selects.length; i++) {
selects[i].value = this.app.options[selects[i].getAttribute("option")];
const val = this.app.options[selects[i].getAttribute("option")];
if (val) {
selects[i].value = val;
selects[i].dispatchEvent(new CustomEvent("change", {bubbles: true}));
}
}
};
@@ -75,8 +78,8 @@ OptionsWaiter.prototype.resetOptionsClick = function() {
* @param {boolean} state
*/
OptionsWaiter.prototype.switchChange = function(e, state) {
let el = e.target,
option = el.getAttribute("option");
const el = e.target;
const option = el.getAttribute("option");
this.app.options[option] = state;
localStorage.setItem("options", JSON.stringify(this.app.options));
@@ -90,8 +93,8 @@ OptionsWaiter.prototype.switchChange = function(e, state) {
* @param {event} e
*/
OptionsWaiter.prototype.numberChange = function(e) {
let el = e.target,
option = el.getAttribute("option");
const el = e.target;
const option = el.getAttribute("option");
this.app.options[option] = parseInt(el.value, 10);
localStorage.setItem("options", JSON.stringify(this.app.options));
@@ -105,8 +108,8 @@ OptionsWaiter.prototype.numberChange = function(e) {
* @param {event} e
*/
OptionsWaiter.prototype.selectChange = function(e) {
let el = e.target,
option = el.getAttribute("option");
const el = e.target;
const option = el.getAttribute("option");
this.app.options[option] = el.value;
localStorage.setItem("options", JSON.stringify(this.app.options));
@@ -132,4 +135,14 @@ OptionsWaiter.prototype.setWordWrap = function() {
}
};
/**
* Changes the theme by setting the class of the <html> element.
*/
OptionsWaiter.prototype.themeChange = function (e) {
const themeClass = e.target.value;
document.querySelector(":root").className = themeClass;
};
export default OptionsWaiter;

View File

@@ -36,10 +36,10 @@ OutputWaiter.prototype.get = function() {
* @param {number} duration - The length of time (ms) it took to generate the output
*/
OutputWaiter.prototype.set = function(dataStr, type, duration) {
let outputText = document.getElementById("output-text"),
outputHtml = document.getElementById("output-html"),
outputHighlighter = document.getElementById("output-highlighter"),
inputHighlighter = document.getElementById("input-highlighter");
const outputText = document.getElementById("output-text");
const outputHtml = document.getElementById("output-html");
const outputHighlighter = document.getElementById("output-highlighter");
const inputHighlighter = document.getElementById("input-highlighter");
if (type === "html") {
outputText.style.display = "none";
@@ -103,11 +103,11 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
* without wrapping or overflowing.
*/
OutputWaiter.prototype.adjustWidth = function() {
let output = document.getElementById("output"),
saveToFile = document.getElementById("save-to-file"),
switchIO = document.getElementById("switch"),
undoSwitch = document.getElementById("undo-switch"),
maximiseOutput = document.getElementById("maximise-output");
const output = document.getElementById("output");
const saveToFile = document.getElementById("save-to-file");
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 = "";
@@ -129,8 +129,8 @@ OutputWaiter.prototype.adjustWidth = function() {
* Saves the current output to a file, downloaded as a URL octet stream.
*/
OutputWaiter.prototype.saveClick = function() {
let data = Utils.toBase64(this.app.dishStr),
filename = window.prompt("Please enter a filename:", "download.dat");
const data = Utils.toBase64(this.app.dishStr);
const filename = window.prompt("Please enter a filename:", "download.dat");
if (filename) {
const el = document.createElement("a");

View File

@@ -60,8 +60,8 @@ RecipeWaiter.prototype.initialiseOperationDragNDrop = function() {
}.bind(this));
Sortable.utils.on(recList, "touchend", function(e) {
let loc = e.changedTouches[0],
target = document.elementFromPoint(loc.clientX, loc.clientY);
const loc = e.changedTouches[0];
const target = document.elementFromPoint(loc.clientX, loc.clientY);
this.removeIntent = !recList.contains(target);
}.bind(this));
@@ -276,8 +276,9 @@ RecipeWaiter.prototype.operationChildDblclick = function(e) {
* @returns {recipeConfig}
*/
RecipeWaiter.prototype.getConfig = function() {
let config = [], ingredients, ingList, disabled, bp, item,
operations = document.querySelectorAll("#rec-list li.operation");
const config = [];
let ingredients, ingList, disabled, bp, item;
const operations = document.querySelectorAll("#rec-list li.operation");
for (let i = 0; i < operations.length; i++) {
ingredients = [];
@@ -402,8 +403,8 @@ RecipeWaiter.prototype.clearRecipe = function() {
* @param {event} e
*/
RecipeWaiter.prototype.dropdownToggleClick = function(e) {
let el = e.target,
button = el.parentNode.parentNode.previousSibling;
const el = e.target;
const button = el.parentNode.parentNode.previousSibling;
button.innerHTML = el.textContent + " <span class='caret'></span>";
this.ingChange();

View File

@@ -19,69 +19,12 @@ const SeasonalWaiter = function(app, manager) {
* Loads all relevant items depending on the current date.
*/
SeasonalWaiter.prototype.load = function() {
//var now = new Date();
// SpiderChef
// if (now.getMonth() === 3 && now.getDate() === 1) { // Apr 1
// this.insertSpiderIcons();
// this.insertSpiderText();
// }
// Konami code
this.kkeys = [];
window.addEventListener("keydown", this.konamiCodeListener.bind(this));
};
/**
* Replaces chef icons with spider icons.
* #spiderchef
*/
SeasonalWaiter.prototype.insertSpiderIcons = function() {
let spider16 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB3UlEQVQ4y2NgGJaAmYGBgVnf0oKJgYGBobWtXamqqoYTn2I4CI+LTzM2NTulpKbu+vPHz2dV5RWlluZmi3j5+KqFJSSEzpw8uQPdAEYYIzo5Kfjrl28rWFlZzjAzMYuEBQao3Lh+g+HGvbsMzExMDN++fWf4/PXLBzY2tqYNK1f2+4eHM2xcuRLigsT09Igf3384MTExbf767etBI319jU8fPsi+//jx/72HDxh5uLkZ7ty7y/Dz1687Avz8n2UUFR3Z2NjOySoqfmdhYGBg+PbtuwI7O8e5H79+8X379t357PnzYo+ePP7y6cuXc9++f69nYGRsvf/w4XdtLS2R799/bBUWFHr57sP7Jbs3b/ZkzswvUP3165fZ7z9//r988WIVAyPDr8tXr576+u3bpb9//7YwMjKeV1dV41NWVGoVEhDgPH761DJREeHaz1+/lqlpafUx6+jrRfz4+fPy+w8fTu/fsf3uw7t3L39+//4cv7DwGQYGhpdPbt9m4BcRFlNWVJC4fuvWASszs4C379792Ldt2xZBUdEdDP5hYSqQGIjDGa965uYKCalpZQwMDAxhMTG9DAwMDLaurhIkJY7A8IgGBgYGBgd3Dz2yUpeFo6O4rasrA9T24ZRxAAMTwMpgEJwLAAAAAElFTkSuQmCC",
spider32 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAACYVBMVEUAAAAcJSU2Pz85QkM9RUWEhIWMjI2MkJEcJSU2Pz85QkM9RUWWlpc9RUVXXl4cJSU2Pz85QkM8REU9RUVRWFh6ens9RUVCSkpNVFRdY2McJSU5QkM7REQ9RUVGTk5KUlJQVldcY2Rla2uTk5WampscJSVUWltZX2BrcHF1e3scJSUjLCw9RUVASEhFTU1HTk9bYWJeZGRma2xudHV1eHiZmZocJSUyOjpJUFFQVldSWlpTWVpXXl5YXl5rb3B9fX6RkZIcJSUmLy8tNTU9RUVFTU1IT1BOVldRV1hTWlp0enocJSUfKChJUFBWXV1hZ2hnbGwcJSVETExLUlJLU1NNVVVPVlZYXl9cY2RiaGlobW5rcXFyd3h0eHgcJSUpMTFDS0tQV1dRV1hSWFlWXF1bYWJma2tobW5uc3SsrK0cJSVJUFBMVFROVlZVW1xZX2BdYmNhZ2hjaGhla2tqcHBscHE4Pz9KUlJRWVlSWVlXXF1aYGFbYWFfZWZlampqbW4cJSUgKSkiKysuNjY0PD01PT07QkNES0tHTk5JUFBMUlNMU1NOU1ROVVVPVVZRVlZRV1dSWVlWXFxXXV5aX2BbYWFbYWJcYmJcYmNcY2RdYmNgZmZhZmdkaWpkampkamtlamtla2tma2tma2xnbG1obW5pbG1pb3Bqb3Brb3BtcXJudHVvcHFvcXJvc3NwcXNwdXVxc3RzeXl1eXp2eXl3ent6e3x+gYKAhISBg4SKi4yLi4yWlpeampudnZ6fn6CkpaanqKiur6+vr7C4uLm6urq6u7u8vLy9vb3Av8DR0dL2b74UAAAAgHRSTlMAEBAQEBAQECAgICAgMDBAQEBAQEBAUFBQUGBgYGBgYGBgYGBgcHBwcHCAgICAgICAgICAgICPj4+Pj4+Pj4+Pj5+fn5+fn5+fn5+vr6+vr6+/v7+/v7+/v7+/v7+/z8/Pz8/Pz8/Pz8/P39/f39/f39/f39/f7+/v7+/v7+/v78x6RlYAAAGBSURBVDjLY2AYWUCSgUGAk4GBTdlUhQebvP7yjIgCPQbWzBMnjx5wwJSX37Rwfm1isqj9/iPHTuxYlyeMJi+yunfptBkZOw/uWj9h3vatcycu8eRGlldb3Vsts3ph/cFTh7fN3bCoe2Vf8+TZoQhTvBa6REozVC7cuPvQnmULJm1e2z+308eyJieEBSLPXbKQIUqQIczk+N6eNaumtnZMaWhaHM89m8XVCqJA02Y5w0xmga6yfVsamtrN4xoXNzS0JTHkK3CXy4EVFMumcxUy2LbENTVkZfEzMDAudtJyTmNwS2XQreAFyvOlK9louDNVaXurmjkGgnTMkWDgXswtNouFISEX6Awv+RihQi5OcYY4DtVARpCCFCMGhiJ1hjwFBpagEAaWEpFoC0WQOCOjFMRRwXYMDB4BDLJ+QLYsg7GBGjtasLnEMjCIrWBgyAZ7058FI9x1SoFEnTCDsCyIhynPILYYSFgbYpUDA5bpQBluXzxpI1yYAbd2sCMYRhwAAHB9ZPztbuMUAAAAAElFTkSuQmCC",
spider64 = "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";
// Favicon
document.querySelector("link[rel=icon]").setAttribute("href", "data:image/png;base64," + spider16);
// Bake button
document.querySelector("#bake img").setAttribute("src", "data:image/png;base64," + spider32);
// About box
document.querySelector(".about-img-left").setAttribute("src", "data:image/png;base64," + spider64);
};
/**
* Replaces all instances of the word "cyber" with "spider".
* #spiderchef
*/
SeasonalWaiter.prototype.insertSpiderText = function() {
// Title
document.title = document.title.replace(/Cyber/g, "Spider");
// Body
SeasonalWaiter.treeWalk(document.body, function(node) {
// process only text nodes
if (node.nodeType === 3) {
node.nodeValue = node.nodeValue.replace(/Cyber/g, "Spider");
}
}, true);
// Bake button
SeasonalWaiter.treeWalk(document.getElementById("bake-group"), function(node) {
// process only text nodes
if (node.nodeType === 3) {
node.nodeValue = node.nodeValue.replace(/Bake/g, "Spin");
}
}, true);
// Recipe title
document.querySelector("#recipe .title").innerHTML = "Web";
};
/**
* Listen for the Konami code sequence of keys. Turn the page upside down if they are all heard in
* sequence.
@@ -102,53 +45,4 @@ SeasonalWaiter.prototype.konamiCodeListener = function(e) {
}
};
/**
* Walks through the entire DOM starting at the specified element and operates on each node.
*
* @static
* @param {element} parent - The DOM node to start from
* @param {Function} fn - The callback function to operate on each node
* @param {booleam} allNodes - Whether to operate on every node or not
*/
SeasonalWaiter.treeWalk = (function() {
// Create closure for constants
const skipTags = {
"SCRIPT": true, "IFRAME": true, "OBJECT": true,
"EMBED": true, "STYLE": true, "LINK": true, "META": true
};
return function(parent, fn, allNodes) {
let node = parent.firstChild;
while (node && node !== parent) {
if (allNodes || node.nodeType === 1) {
if (fn(node) === false) {
return false;
}
}
// If it's an element &&
// has children &&
// has a tagname && is not in the skipTags list
// then, we can enumerate children
if (node.nodeType === 1 &&
node.firstChild &&
!(node.tagName && skipTags[node.tagName])) {
node = node.firstChild;
} else if (node.nextSibling) {
node = node.nextSibling;
} else {
// No child and no nextsibling
// Find parent that has a nextSibling
while ((node = node.parentNode) !== parent) {
if (node.nextSibling) {
node = node.nextSibling;
break;
}
}
}
}
};
})();
export default SeasonalWaiter;

View File

@@ -1,18 +0,0 @@
/**
* CSS index
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import "google-code-prettify/src/prettify.css";
import "./lib/bootstrap.less";
import "bootstrap-switch/src/less/bootstrap3/build.less";
import "bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css";
import "./structure/overrides.css";
import "./structure/layout.css";
import "./structure/utils.css";
import "./themes/classic.css";

File diff suppressed because one or more lines are too long

View File

@@ -1,113 +0,0 @@
/* Bootstrap */
button,
a:focus {
outline: none;
-moz-outline-style: none;
}
.btn-default {
border-color: #ddd;
}
.btn-default:focus {
background-color: #fff;
border-color: #adadad;
}
.btn-default:hover,
.btn-default:active {
background-color: #ebebeb;
border-color: #adadad;
}
.btn,
.btn-lg,
.nav-tabs>li>a,
.form-control,
.popover,
.alert,
.modal-content,
.tooltip-inner,
.dropdown-menu {
border-radius: 0 !important;
}
input[type="search"] {
-webkit-appearance: searchfield;
box-shadow: none;
}
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
.modal {
overflow-y: auto;
}
.form-control {
background-color: transparent;
}
code {
border: 0;
white-space: pre-wrap;
font-family: Consolas, monospace;
}
pre {
border-radius: 0 !important;
}
blockquote {
font-size: inherit;
}
blockquote a {
cursor: pointer;
}
optgroup {
font-weight: bold;
}
.panel-body:before,
.panel-body:after {
content: "";
}
.table-nonfluid {
width: auto !important;
}
/* Bootstrap-switch */
.bootstrap-switch,
.bootstrap-switch-container,
.bootstrap-switch-handle-on,
.bootstrap-switch-handle-off,
.bootstrap-switch-label {
border-radius: 0 !important;
}
/* Sortable */
.sortable-ghost {
opacity: 0.6;
}
/* Bootstrap Colorpicker */
.colorpicker-element {
float: left;
margin-right: 15px;
}
.colorpicker-color,
.colorpicker-color div {
height: 100px;
}

View File

@@ -1,37 +0,0 @@
.word-wrap {
white-space: pre !important;
word-wrap: normal !important;
overflow-x: scroll !important;
}
.clearfix {
clear: both;
height: 0;
}
.blur {
color: transparent !important;
text-shadow: rgba(0, 0, 0, 0.95) 0 0 10px !important;
}
.no-select {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.konami {
-ms-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
-moz-transform: rotate(180deg);
}
.hl1, .hlyellow { background-color: #fff000; }
.hl2, .hlblue { background-color: #95dfff; }
.hl3, .hlred { background-color: #ffb6b6; } /* Half-Life 3 confirmed :O */
.hl4, .hlorange { background-color: #fcf8e3; }
.hl5, .hlgreen { background-color: #8de768; }

View File

@@ -1,258 +0,0 @@
#banner {
border-bottom: 1px solid #ddd;
}
.title {
border-bottom: 1px solid #ddd;
font-weight: bold;
color: #424242;
background-color: #fafafa;
}
.gutter {
background-color: #eee;
background-repeat: no-repeat;
background-position: 50%;
}
.gutter.gutter-horizontal {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAeCAYAAAAGos/EAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAlSURBVChTYzxz5sx/BiBgAhEgwPju3TtUEZZ79+6BGcNcDQMDACWJMFs4hNOSAAAAAElFTkSuQmCC');
cursor: ew-resize;
}
.gutter.gutter-vertical {
background-image: url('data:image/png;base64,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');
cursor: ns-resize;
}
.operation {
border: 1px solid #999;
border-top-width: 0;
}
.op-list .operation { /*blue*/
color: #3a87ad;
background-color: #d9edf7;
border-color: #bce8f1;
}
#rec-list .operation { /*green*/
color: #468847;
background-color: #dff0d8;
border-color: #d6e9c6;
}
#controls {
border-top: 1px solid #ddd;
background-color: #fafafa;
}
.textarea-wrapper textarea,
.textarea-wrapper div {
font-family: Consolas, monospace;
font-size: inherit;
}
.io-info {
font-family: Consolas, monospace;
font-weight: normal;
font-size: 8pt;
}
.arg-title {
font-weight: bold;
}
.arg-input {
height: 34px;
font-size: 15px;
line-height: 1.428571429;
color: #424242;
background-color: #fff;
border: 1px solid #ddd;
font-family: Consolas, monospace;
}
select {
padding: 6px 8px;
height: 34px;
border: 1px solid #ddd;
background-color: #fff;
color: #424242;
}
.arg[disabled] {
background-color: #eee;
}
textarea.arg {
color: #424242;
font-family: Consolas, monospace;
}
.break {
color: #b94a48 !important;
background-color: #f2dede !important;
border-color: #eed3d7 !important;
}
.category-title {
background-color: #fafafa;
border-bottom: 1px solid #eee;
font-weight: bold;
}
.category-title[href='#catFavourites'] {
border-bottom-color: #ddd;
}
.category-title[aria-expanded=true] {
border-bottom-color: #ddd;
}
.category-title.collapsed {
border-bottom-color: #eee;
}
.category-title:hover {
color: #3a87ad;
}
#search {
border-bottom: 1px solid #e3e3e3;
}
.dropping-file {
border: 5px dashed #3a87ad !important;
}
.selected-op {
color: #c09853 !important;
background-color: #fcf8e3 !important;
border-color: #fbeed5 !important;
}
.option-item input[type=number] {
font-size: 14px;
line-height: 1.428571429;
color: #555;
background-color: #fff;
border: 1px solid #ccc;
}
.favourites-hover {
color: #468847;
background-color: #dff0d8;
border: 2px dashed #468847 !important;
padding: 8px 8px 9px 8px;
}
#edit-favourites-list {
border: 1px solid #bce8f1;
}
#edit-favourites-list .operation {
border-left: none;
border-right: none;
}
#edit-favourites-list .operation:last-child {
border-bottom: none;
}
.subtext {
font-style: italic;
font-size: 13px;
color: #999;
}
#save-footer {
border-bottom: 1px solid #e5e5e5;
}
.flow-control-op {
color: #396f3a !important;
background-color: #c7e4ba !important;
border-color: #b3dba2 !important;
}
.flow-control-op.break {
color: #94312f !important;
background-color: #eabfbf !important;
border-color: #e2aeb5 !important;
}
#support-modal textarea {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
#save-text,
#load-text {
font-family: Consolas, monospace;
}
button.dropdown-toggle {
background-color: #f4f4f4;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background-color: #fafafa;
}
::-webkit-scrollbar-thumb {
background-color: #ccc;
}
::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
}
::-webkit-scrollbar-corner {
background-color: #fafafa;
}
.disabled {
color: #999 !important;
background-color: #dfdfdf !important;
border-color: #cdcdcd !important;
}
.grey {
color: #333;
background-color: #f5f5f5;
border-color: #ddd;
}
.dark-blue {
color: #fff;
background-color: #428bca;
border-color: #428bca;
}
.red {
color: #b94a48;
background-color: #f2dede;
border-color: #eed3d7;
}
.amber {
color: #c09853;
background-color: #fcf8e3;
border-color: #fbeed5;
}
.green {
color: #468847;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.blue {
color: #3a87ad;
background-color: #d9edf7;
border-color: #bce8f1;
}

View File

@@ -20,7 +20,7 @@
-->
<!-- htmlmin:ignore -->
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="classic">
<head>
<meta charset="UTF-8">
<title>CyberChef</title>
@@ -30,15 +30,50 @@
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
<script type="application/javascript">
// Load theme before the preloader is shown
document.querySelector(":root").className = JSON.parse(localStorage.getItem("options")).theme;
// Cycle loading messages
const loadingMsgs = [
"Proving P = NP...",
"Computing 6 x 9...",
"Mining bitcoin...",
"Dividing by 0...",
"Initialising Skynet...",
"[REDACTED]",
"Downloading more RAM...",
"Loading more loading messages...",
"Ordering 1s and 0s...",
"Navigating neural network...",
"Importing machine learning..."
];
function changeLoadingMsg() {
try {
const el = document.getElementById("preloader-msg");
el.className = "loading"; // Causes CSS transition on first message
el.innerHTML = loadingMsgs[Math.floor(Math.random()*loadingMsgs.length)];
} catch (err) {}
}
changeLoadingMsg();
window.loadingMsgsInt = setInterval(changeLoadingMsg, (Math.random()*500) + 500);
</script>
</head>
<body>
<!-- Preloader overlay -->
<div id="loader-wrapper">
<div id="preloader"></div>
<div id="preloader-msg"></div>
</div>
<!-- End preloader overlay -->
<span id="edit-favourites" class="btn btn-default btn-sm"><img aria-hidden="true" src="<%- require('../static/images/favourite-16x16.png') %>" alt="Star Icon"/> Edit</span>
<div id="alert" class="alert alert-danger">
<button type="button" class="close" id="alert-close">&times;</button>
<span id="alert-content"></span>
</div>
<div id="content-wrapper">
<div id="banner" class="green">
<div id="banner">
<% if (htmlWebpackPlugin.options.inline) { %>
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
<% } else { %>
@@ -57,17 +92,17 @@
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img aria-hidden="true" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/></a>
<a href="#" id="options" class="banner-right">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
</div>
<div id="wrapper">
<div id="workspace-wrapper">
<div id="operations" class="split split-horizontal no-select">
<div class="title no-select">Operations</div>
<input type="search" class="form-control" id="search" placeholder="Search..." autocomplete="off">
<ul class="op-list" id="search-results"></ul>
<div class="panel-group no-select" id="categories"></div>
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off">
<ul id="search-results" class="op-list"></ul>
<div id="categories" class="panel-group no-select"></div>
</div>
<div id="recipe" class="split split-horizontal no-select">
<div class="title no-select">Recipe</div>
<ul id="rec-list" class="no-select"></ul>
<ul id="rec-list" class="list-area no-select"></ul>
<div id="controls" class="no-select">
<div id="operational-controls">
@@ -100,6 +135,7 @@
<div id="input" class="split no-select">
<div class="title no-select">
<label for="input-text">Input</label>
<div class="loading-icon" style="display: none"></div>
<div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
@@ -116,6 +152,7 @@
<div id="output" class="split">
<div class="title no-select">
<label for="output-text">Output</label>
<div class="loading-icon" style="display: none"></div>
<div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
@@ -163,6 +200,7 @@
<input type="checkbox" id="save-link-recipe-checkbox" checked> <label for="save-link-recipe-checkbox"> Include recipe </label>
<input type="checkbox" id="save-link-input-checkbox" checked> <label for="save-link-input-checkbox"> Include input </label>
</div>
<br>
<a id="save-link" style="word-wrap: break-word;"></a>
</div>
</div>
@@ -205,6 +243,13 @@
</div>
<div class="modal-body" id="options-body">
<p style="font-weight: bold">Please note that these options will persist between sessions.</p>
<div class="option-item">
<select option="theme" id="theme">
<option value="classic">Classic</option>
<option value="dark">Dark</option>
</select>
<label for="theme"> Theme (only supported in modern browsers)</label>
</div>
<div class="option-item">
<input type="checkbox" option="update_url" id="update_url" checked />
<label for="update_url"> Update the URL when the input or recipe changes </label>
@@ -278,8 +323,11 @@
</div>
<div class="modal-body">
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
<p class="subtext">Compile time: <%= htmlWebpackPlugin.options.compileTime %></p>
<p>&copy Crown Copyright 2016.</p>
<p class="subtext">
Version <%= htmlWebpackPlugin.options.version %><br>
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
</p>
<p>&copy; Crown Copyright 2016.</p>
<p>Licenced under the Apache Licence, Version 2.0.</p>
<br>
<br>

View File

@@ -4,8 +4,8 @@
* @license Apache-2.0
*/
// CSS
import "./css/index.js";
// Styles
import "./stylesheets/index.js";
// Libs
import "babel-polyfill";
@@ -46,6 +46,7 @@ function main() {
errorTimeout : 4000,
autoBakeThreshold : 200,
attemptHighlight : true,
theme : "classic",
};
document.removeEventListener("DOMContentLoaded", main, false);

View File

@@ -0,0 +1,22 @@
/**
* Alert styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
#alert {
position: fixed;
width: 30%;
margin: 30px auto;
top: 10px;
left: 0;
right: 0;
z-index: 2000;
display: none;
}
#alert a {
text-decoration: underline;
}

View File

@@ -0,0 +1,13 @@
/**
* Button styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
button img,
span.btn img {
margin-right: 3px;
margin-bottom: 1px;
}

View File

@@ -0,0 +1,43 @@
/**
* Operation list styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
.op-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.category-title {
display: block;
padding: 10px;
background-color: var(--secondary-background-colour);
border-bottom: 1px solid var(--secondary-border-colour);
font-weight: var(--title-weight);
}
.category-title[href='#catFavourites'] {
border-bottom-color: var(--primary-border-colour);
}
.category-title[aria-expanded=true] {
border-bottom-color: var(--primary-border-colour);
}
.category-title.collapsed {
border-bottom-color: var(--secondary-border-colour);
}
.category-title:hover {
color: var(--op-list-operation-font-colour);
}
.category {
margin: 0 !important;
border-radius: 0 !important;
border: none;
}

View File

@@ -0,0 +1,196 @@
/**
* Operation styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
.operation {
cursor: pointer;
padding: 10px;
list-style-type: none;
position: relative;
border-width: 1px;
border-style: solid;
border-top: none;
border-left: none;
border-right: none;
}
.arg-group {
display: table;
width: 100%;
margin-top: 10px;
}
.arg-group-text {
display: block;
}
.inline-args {
float: left;
width: auto;
margin-right: 30px;
height: 34px;
}
.inline-args input[type="checkbox"] {
margin-top: 10px;
}
.inline-args input[type="number"] {
width: 100px;
}
.arg-title {
font-weight: var(--arg-title-font-weight);
}
.arg-input {
display: table-cell;
width: 100%;
padding: 6px 12px;
vertical-align: middle;
height: var(--arg-input-height);
font-size: var(--arg-input-font-size);
line-height: var(--arg-input-line-height);
color: var(--arg-font-colour);
background-color: var(--arg-background);
border: 1px solid var(--arg-border-colour);
font-family: var(--fixed-width-font-family);
}
.short-string {
width: 150px;
}
select {
display: block;
padding: 6px 8px;
height: 34px;
border: 1px solid var(--arg-border-colour);
background-color: var(--arg-background);
color: var(--arg-font-colour);
}
.arg[disabled] {
cursor: not-allowed;
opacity: 1;
background-color: var(--arg-disabled-background);
}
textarea.arg {
width: 100%;
min-height: 50px;
height: 70px;
margin-top: 5px;
border: 1px solid var(--arg-border-colour);
resize: vertical;
color: var(--arg-font-colour);
background-color: var(--arg-background);
font-family: var(--fixed-width-font-family);
}
.arg-label {
display: table-cell;
width: 1px;
padding-right: 10px;
font-weight: normal;
vertical-align: middle;
white-space: pre;
}
.editable-option {
position: relative;
display: inline-block;
}
.editable-option-select {
min-width: 250px;
}
.editable-option-input {
position: absolute;
top: 1px;
left: 1px;
width: calc(100% - 20px);
height: calc(100% - 2px) !important;
border: none !important;
}
button.dropdown-toggle {
background-color: var(--secondary-background-colour);
}
.op-icon {
float: right;
margin-left: 10px;
margin-top: 3px;
}
.recip-icons {
position: absolute;
top: 13px;
right: 10px;
height: 16px;
}
.recip-icon {
margin-right: 10px;
vertical-align: baseline;
float: right;
}
.disable-icon {
width: 16px;
height: 16px;
margin-top: -1px;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAACfElEQVQ4y6WTPWgTYRjHf8nlfVvuoDVIP4Yuki4WHKoUqggFRUTsUEGkVG2hmCq6OnTwIxYHB+eijZOKdLNDW1pKKyGigh8dBHUJElxyBgx3vEnukvdyDrUhRXDxGR+e/+/583xEwjDkfyIGwNVTzURm4tYAMA6MAoN/0tvAMrA48uL+l2bx4w0iYRjSuHKC6OnTZLqHk8CcaZq9bW1tSCkBqNVq+L5PpVIpAHdGfr5LN9bXiT7Z2nGgteb1/qFkLBJZ6OjowHEc8vk8pVIJgHg8TldXF52dnb2u6y5s7R/iuF5JSyAKkLl4eyAMwznLsrBtm1wu99Z13amk+BFJih8R13WXANrb27EsizAM5zIXbw+wC9Baj0spe5VSFAqFt4ZhXJ6ufXuK55E5cDKVSCTGenp6yGazKKWQUvZqrcebgCAIRqWUOI6DEOLR1K8POapVMgfPpoC7u2LLspYcx0FKSRAEo60OBg3DwPd9Jr5vPqWvj8zh83vEwL2J75vnfN/HMAy01oPNNQZBQBAEO1OvVsl0D/8lTuZfpYDd7gRBQKuD7XK5jGmarB679PIv8deVFJUKq8cuTZqmSblcRmu93QpYVkohhMCyrLE94n2/UlSrbJy5kRBCXBNCoJRCa73cClh0XbfgeR6WZZHNZunv719KvnmeYnWVVxdmJ2Ox2DMhxFHP83Bdt6C1XgR2LvHzQDvvb84npZQL8Xgc0zSJRqN7br7RaFCpVCiVStRqtZmhh9fTh754TQdMr82nPc+bsW27UCwWUUpRr9ep1+sopSgWi9i2XfA8b2Z6bT6ttabp4GMi0uz0aXbhn890+MFM85mO5MIdwP/Eb1pMUCdctYRzAAAAAElFTkSuQmCC') no-repeat;
}
.disable-icon-selected {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFUlEQVR4XqWTP0tbURjGn9zY3mjBwsUhBQtS6XKxiNypIGZJ6SKYUYdaKWg7OrrE3pYO+Qit3dpFuuQO6lI7Z4nESQdjlJbkJh0MksSb3Jvk9H0gjZFu9YWH83LO7zn/3nNCSincJobAeP1sEDBFi6J50UyPy4l2RNuioz756Ts0tt1OB4jH2a52Ne2HGh9PwrJm2EcxZx/HyPRYMDgB2u02/N3d1c7w8BZMM1ptNJBPp3GwsUExB/s4RoYsPf0JOkFgdoH34YkJ/D48xC/HyTTOzl5ayWSIktwxqlVo0SjIkKWnP0Hg+4swjGitVMJFNpu5o+svptfXv6DZBDIZezoWS3Db3A0ZsvRcH8H354dGR9EoFHA3EvlorqycwvOAXM4G8Pav+f7YmEOGLD1gsIzl54+V+vBK/Yw9ZAv1LQW1FrdFSnKVfQTK5liPUfRI9I8ArqiPjLAF9vcHVybyzlpasgcZeq7voNXKNSsV3DMMXB4fp/8xLyzYuLri2DIZsvQM3sFOzXURiUR4zsQNcyrFleFVKpNyP2/IkKVnsArbF65bbkqplJSJZrl5x5qbs7G3h3artSyV+arr+lMyZOnpP2Wp6ZFos3R+vvUgCGDNzgKalkA4rECIr07662J2i0X4nrfJJ33jJT6Zmvpcr9XWCicn5WI+j7rrAmKgmLOPY2TI0sPgb8TBZOi/PpN1qnDr7/wH3jxgB/FKIXkAAAAASUVORK5CYII=') no-repeat;
}
.breakpoint {
float: right;
width: 14px;
height: 14px;
background-color: #eee;
border: 1px solid #aaa;
}
.breakpoint-selected {
background: #eee url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAXVBMVEXIUkvzUVHzTEzzn5785eXrbW24BgbzWVnze3vzVVXzY2Pyion509PzbW3zXV1UMxj0l5f1srKbRTRgOxzJDg796ur74ODfIyP5zs6LLx3pNTXYGxuxdkVZNhn////sCC1eAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAABWSURBVBjTnc+7EoAgDERRTOQVxMEZFAf//z8FjAUFDbfb060QU2FwxngimxnCea3bjegSgz+0tguAfBgIy64QGfZQdg91dgAtqUZgnfz6IacYVWvu2AvR4wNAv0nxrAAAAABJRU5ErkJggg==') no-repeat -2px -2px;
}
.break {
color: var(--breakpoint-font-colour) !important;
background-color: var(--breakpoint-bg-colour) !important;
border-color: var(--breakpoint-border-colour) !important;
}
.selected-op {
color: var(--selected-operation-font-color) !important;
background-color: var(--selected-operation-bg-colour) !important;
border-color: var(--selected-operation-border-colour) !important;
}
.flow-control-op {
color: var(--fc-operation-font-colour) !important;
background-color: var(--fc-operation-bg-colour) !important;
border-color: var(--fc-operation-border-colour) !important;
}
.flow-control-op.break {
color: var(--fc-breakpoint-operation-font-colour) !important;
background-color: var(--fc-breakpoint-operation-bg-colour) !important;
border-color: var(--fc-breakpoint-operation-border-colour) !important;
}
.disabled {
color: var(--disabled-font-colour) !important;
background-color: var(--disabled-bg-colour) !important;
border-color: var(--disabled-border-colour) !important;
}

View File

@@ -0,0 +1,30 @@
/**
* Workspace pane styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
:root {
--title-height: 43px;
}
.title {
padding: 10px;
height: var(--title-height);
border-bottom: 1px solid var(--primary-border-colour);
font-weight: var(--title-weight);
color: var(--title-colour);
background-color: var(--title-background-colour);
}
.list-area {
position: absolute;
top: var(--title-height);
bottom: 0;
width: 100%;
list-style-type: none;
margin: 0;
padding: 0;
}

View File

@@ -0,0 +1,34 @@
/**
* CyberChef styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
/* Themes */
@import "./themes/_classic.css";
@import "./themes/_dark.css";
/* Utilities */
@import "./utils/_overrides.css";
@import "./utils/_general.css";
/* Preloader styles */
@import "./preloader.css";
/* Components */
@import "./components/_alert.css";
@import "./components/_button.css";
@import "./components/_list.css";
@import "./components/_operation.css";
@import "./components/_pane.css";
/* Layout */
@import "./layout/_banner.css";
@import "./layout/_controls.css";
@import "./layout/_io.css";
@import "./layout/_modals.css";
@import "./layout/_operations.css";
@import "./layout/_recipe.css";
@import "./layout/_structure.css";

View File

@@ -0,0 +1,18 @@
/**
* Styles index
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
/* Libraries */
import "google-code-prettify/src/prettify.css";
/* Frameworks */
import "./vendors/bootstrap.less";
import "bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.css";
import "bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css";
/* CyberChef styles */
import "./index.css";

View File

@@ -0,0 +1,28 @@
/**
* Banner area styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
#banner {
position: absolute;
height: 30px;
width: 100%;
text-align: center;
line-height: 30px;
border-bottom: 1px solid var(--primary-border-colour);
color: var(--banner-font-colour);
background-color: var(--banner-bg-colour);
}
.banner-right {
float: right;
margin-right: 10px;
}
#banner img {
margin-bottom: 2px;
margin-left: 8px;
}

View File

@@ -0,0 +1,65 @@
/**
* Controls area styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
:root {
--controls-height: 120px;
--controls-division: 65%;
}
#controls {
position: absolute;
width: 100%;
height: var(--controls-height);
bottom: 0;
padding: 10px;
border-top: 1px solid var(--primary-border-colour);
background-color: var(--secondary-background-colour);
}
#operational-controls {
width: var(--controls-division);
float: left;
text-align: center;
}
#bake-group {
display: table;
width: 100%;
}
#bake {
display: table-cell;
width: 100%;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
#auto-bake-label {
display: table-cell;
padding: 1px;
line-height: 1.35;
width: 60px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 1px solid var(--btn-success-bg-colour);
}
#auto-bake-label:hover {
border-left-color: var(--btn-success-hover-border-colour);
}
#auto-bake-label div {
font-size: 10px;
padding: 2px;
}
#extra-controls {
float: right;
width: calc(100% - var(--controls-division));
padding-left: 10px;
}

View File

@@ -0,0 +1,109 @@
/**
* Input/Output area styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
#input-text,
#output-text,
#output-html {
position: relative;
width: 100%;
height: 100%;
margin: 0;
padding: 3px;
-moz-padding-start: 3px;
-moz-padding-end: 3px;
border: none;
border-width: 0px;
resize: none;
background-color: transparent;
white-space: pre-wrap;
word-wrap: break-word;
}
#output-html {
display: none;
overflow-y: auto;
-moz-padding-start: 1px; /* Fixes bug in Firefox */
}
.textarea-wrapper {
position: absolute;
top: 43px;
bottom: 0;
width: 100%;
overflow: hidden;
}
.textarea-wrapper textarea,
.textarea-wrapper div {
font-family: var(--fixed-width-font-family);
font-size: var(--fixed-width-font-size);
color: var(--fixed-width-font-colour);
}
#input-highlighter,
#output-highlighter {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: 3px;
margin: 0;
overflow: hidden;
letter-spacing: normal;
white-space: pre-wrap;
word-wrap: break-word;
color: #fff;
background-color: transparent;
border: none;
}
.io-btn-group {
float: right;
margin-top: -4px;
}
.io-info {
margin-right: 20px;
margin-top: -4px;
float: right;
height: 30px;
text-align: right;
line-height: 10px;
font-family: var(--fixed-width-font-family);
font-weight: normal;
font-size: 8pt;
}
#input-info {
line-height: 15px;
}
.dropping-file {
border: 5px dashed var(--drop-file-border-colour) !important;
}
@keyframes spinner {
from {
transform:rotate(0deg);
}
to {
transform:rotate(359deg);
}
}
.loading-icon::before {
content: "\21bb";
}
.loading-icon {
animation-name: spinner;
animation-duration: 1000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}

View File

@@ -0,0 +1,80 @@
/**
* Modal layout styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
.option-item .bootstrap-switch {
margin: 15px 10px;
}
.option-item button {
margin: 10px;
}
.option-item input[type=number] {
margin: 15px 10px;
width: 80px;
height: 28px;
padding: 3px 10px;
vertical-align: middle;
font-size: calc(var(--arg-input-font-size) - 1px);
line-height: var(--arg-input-line-height);
color: var(--arg-font-colour);
background-color: var(--arg-background);
border: 1px solid var(--primary-border-colour);
}
.option-item select {
margin: 10px;
display: inline-block;
}
#edit-favourites-list {
margin: 10px;
border: 1px solid var(--op-list-operation-border-colour);
}
#edit-favourites-list .operation {
border-left: none;
border-right: none;
}
#edit-favourites-list .operation:last-child {
border-bottom: none;
}
.about-img-left {
float: left;
margin: 10px 20px 20px 0;
}
.about-img-right {
float: right;
margin: 10px 0 20px 20px;
}
.save-link-options {
float: right;
}
.save-link-options input{
margin-left: 10px;
}
#save-footer {
border-top: none;
margin-top: 0;
border-bottom: 1px solid var(--primary-border-colour);
}
#support-modal textarea {
font-family: var(--primary-font-family);
}
#save-text,
#load-text {
font-family: var(--fixed-width-font-family);
}

View File

@@ -0,0 +1,32 @@
/**
* Operation area styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
.op-list .operation {
color: var(--op-list-operation-font-colour);
background-color: var(--op-list-operation-bg-colour);
border-color: var(--op-list-operation-border-colour);
}
#search {
border-radius: 0;
border: none;
border-bottom: 1px solid var(--primary-border-colour);
color: var(--primary-font-colour);
}
#edit-favourites {
float: right;
margin-top: -5px;
}
.favourites-hover {
color: var(--rec-list-operation-font-colour);
background-color: var(--rec-list-operation-bg-colour);
border: 2px dashed var(--rec-list-operation-font-colour) !important;
padding: 8px 8px 9px 8px;
}

View File

@@ -0,0 +1,18 @@
/**
* Recipe area styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
#rec-list {
bottom: var(--controls-height);
overflow: auto;
}
#rec-list .operation {
color: var(--rec-list-operation-font-colour);
background-color: var(--rec-list-operation-bg-colour);
border-color: var(--rec-list-operation-border-colour);
}

View File

@@ -0,0 +1,65 @@
/**
* Overall page structure styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
body {
overflow: hidden;
}
#content-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#workspace-wrapper {
position: absolute;
top: 30px;
bottom: 0;
width: 100%;
}
div#operations,
div#recipe {
width: 50%;
height: 100%;
}
div#input,
div#output {
width: 100%;
height: 50%;
}
.split {
box-sizing: border-box;
overflow: auto;
position: relative;
}
.split.split-horizontal, .gutter.gutter-horizontal {
height: 100%;
float: left;
}
.gutter {
background-color: var(--secondary-border-colour);
background-repeat: no-repeat;
background-position: 50%;
}
.gutter.gutter-horizontal {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAeCAYAAAAGos/EAAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB+EFBhEwBDmIiYYAAAAjSURBVBjTYzxz5sx/BgYGBiYGKGB89+4dA4oIy71790aGGgCn+DBbOcAB0wAAAABJRU5ErkJggg==');
cursor: ew-resize;
}
.gutter.gutter-vertical {
background-image: url('data:image/png;base64,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');
cursor: ns-resize;
}

View File

@@ -0,0 +1,152 @@
/**
* Preloader styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
background-color: var(--secondary-border-colour);
}
#preloader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 3px solid transparent;
border-top-color: #3498db;
border-radius: 50%;
z-index: 1500;
animation: spin 2s linear infinite;
}
#preloader:before,
#preloader:after {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border: 3px solid transparent;
border-radius: 50%;
}
#preloader:before {
border-top-color: #e74c3c;
animation: spin 3s linear infinite;
}
#preloader:after {
border-top-color: #f9c922;
animation: spin 1.5s linear infinite;
}
#preloader-msg {
display: block;
position: relative;
width: 300px;
left: calc(50% - 150px);
top: calc(50% + 50px);
text-align: center;
margin-top: 50px;
opacity: 0;
}
#preloader-msg.loading {
opacity: 1;
transition: all 0.1s ease-in;
}
/* Loaded */
.loaded #preloader,
.loaded #preloader-msg {
opacity: 0;
transition: all 0.3s ease-out;
}
.loaded #loader-wrapper {
opacity: 0;
transition: all 0.5s 0.3s ease-out;
}
.loaded #rec-list li {
animation: bump 0.7s cubic-bezier(0.7, 0, 0.3, 1) both;
}
.loaded #content-wrapper {
animation-delay: 0.10s;
}
.loaded #rec-list li:first-child {
animation-delay: 0.20s;
}
.loaded #rec-list li:nth-child(2) {
animation-delay: 0.25s;
}
.loaded #rec-list li:nth-child(3) {
animation-delay: 0.30s;
}
.loaded #rec-list li:nth-child(4) {
animation-delay: 0.35s;
}
.loaded #rec-list li:nth-child(5) {
animation-delay: 0.40s;
}
.loaded #rec-list li:nth-child(6) {
animation-delay: 0.45s;
}
.loaded #rec-list li:nth-child(7) {
animation-delay: 0.50s;
}
.loaded #rec-list li:nth-child(8) {
animation-delay: 0.55s;
}
.loaded #rec-list li:nth-child(9) {
animation-delay: 0.60s;
}
.loaded #rec-list li:nth-child(10) {
animation-delay: 0.65s;
}
/* Animations */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes bump {
from {
opacity: 0;
transform: translate3d(0, 200px, 0);
}
}

View File

@@ -0,0 +1,116 @@
/**
* Classic theme definitions
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
:root,
:root.classic {
--primary-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
--primary-font-colour: #333;
--primary-font-size: 14px;
--primary-line-height: 20px;
--fixed-width-font-family: "Consolas", monospace;
--fixed-width-font-colour: inherit;
--fixed-width-font-size: inherit;
--subtext-font-colour: #999;
--subtext-font-size: 13px;
--primary-background-colour: #fff;
--secondary-background-colour: #fafafa;
--primary-border-colour: #ddd;
--secondary-border-colour: #eee;
--title-colour: #424242;
--title-weight: bold;
--title-background-colour: #fafafa;
--banner-font-colour: #468847;
--banner-bg-colour: #dff0d8;
/* Operation colours */
--op-list-operation-font-colour: #3a87ad;
--op-list-operation-bg-colour: #d9edf7;
--op-list-operation-border-colour: #bce8f1;
--rec-list-operation-font-colour: #468847;
--rec-list-operation-bg-colour: #dff0d8;
--rec-list-operation-border-colour: #d6e9c6;
--selected-operation-font-color: #c09853;
--selected-operation-bg-colour: #fcf8e3;
--selected-operation-border-colour: #fbeed5;
--breakpoint-font-colour: #b94a48;
--breakpoint-bg-colour: #f2dede;
--breakpoint-border-colour: #eed3d7;
--disabled-font-colour: #999;
--disabled-bg-colour: #dfdfdf;
--disabled-border-colour: #cdcdcd;
--fc-operation-font-colour: #396f3a;
--fc-operation-bg-colour: #c7e4ba;
--fc-operation-border-colour: #b3dba2;
--fc-breakpoint-operation-font-colour: #94312f;
--fc-breakpoint-operation-bg-colour: #eabfbf;
--fc-breakpoint-operation-border-colour: #e2aeb5;
/* Operation arguments */
--arg-title-font-weight: bold;
--arg-input-height: 34px;
--arg-input-line-height: 20px;
--arg-input-font-size: 15px;
--arg-font-colour: #424242;
--arg-background: #fff;
--arg-border-colour: #ddd;
--arg-disabled-background: #eee;
/* Buttons */
--btn-default-font-colour: #333;
--btn-default-bg-colour: #fff;
--btn-default-border-colour: #ddd;
--btn-default-hover-font-colour: #333;
--btn-default-hover-bg-colour: #ebebeb;
--btn-default-hover-border-colour: #adadad;
--btn-success-font-colour: #fff;
--btn-success-bg-colour: #5cb85c;
--btn-success-border-colour: #4cae4c;
--btn-success-hover-font-colour: #fff;
--btn-success-hover-bg-colour: #449d44;
--btn-success-hover-border-colour: #398439;
/* Highlighter colours */
--hl1: #fff000;
--hl2: #95dfff;
--hl3: #ffb6b6;
--hl4: #fcf8e3;
--hl5: #8de768;
/* Scrollbar */
--scrollbar-track: var(--secondary-background-colour);
--scrollbar-thumb: #ccc;
--scrollbar-hover: #bbb;
/* Misc. */
--drop-file-border-colour: #3a87ad;
--popover-background: #fff;
--popover-border-colour: #ccc;
--code-background: #f9f2f4;
--code-font-colour: #c7254e;
}

View File

@@ -0,0 +1,115 @@
/**
* Dark theme definitions
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
:root.dark {
--primary-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
--primary-font-colour: #c5c5c5;
--primary-font-size: 14px;
--primary-line-height: 20px;
--fixed-width-font-family: "Monaco", "Droid Sans Mono", "Consolas", monospace;
--fixed-width-font-colour: inherit;
--fixed-width-font-size: inherit;
--subtext-font-colour: #999;
--subtext-font-size: 13px;
--primary-background-colour: #1e1e1e;
--secondary-background-colour: #252525;
--primary-border-colour: #444;
--secondary-border-colour: #3c3c3c;
--title-colour: #fff;
--title-weight: bold;
--title-background-colour: #333;
--banner-font-colour: #c5c5c5;
--banner-bg-colour: #252525;
/* Operation colours */
--op-list-operation-font-colour: #c5c5c5;
--op-list-operation-bg-colour: #333;
--op-list-operation-border-colour: #444;
--rec-list-operation-font-colour: #c5c5c5;
--rec-list-operation-bg-colour: #252525;
--rec-list-operation-border-colour: #444;
--selected-operation-font-color: #c5c5c5;
--selected-operation-bg-colour: #3f3f3f;
--selected-operation-border-colour: #444;
--breakpoint-font-colour: #ddd;
--breakpoint-bg-colour: #073655;
--breakpoint-border-colour: #444;
--disabled-font-colour: #666;
--disabled-bg-colour: #444;
--disabled-border-colour: #444;
--fc-operation-font-colour: #c5c5c5;
--fc-operation-bg-colour: #2d2d2d;
--fc-operation-border-colour: #444;
--fc-breakpoint-operation-font-colour: #ddd;
--fc-breakpoint-operation-bg-colour: #072b49;
--fc-breakpoint-operation-border-colour: #444;
/* Operation arguments */
--arg-title-font-weight: bold;
--arg-input-height: 34px;
--arg-input-line-height: 20px;
--arg-input-font-size: 15px;
--arg-font-colour: #bbb;
--arg-background: #3c3c3c;
--arg-border-colour: #3c3c3c;
--arg-disabled-background: #4f4f4f;
/* Buttons */
--btn-default-font-colour: #c5c5c5;
--btn-default-bg-colour: #2d2d2d;
--btn-default-border-colour: #3c3c3c;
--btn-default-hover-font-colour: #c5c5c5;
--btn-default-hover-bg-colour: #2d2d2d;
--btn-default-hover-border-colour: #205375;
--btn-success-font-colour: #fff;
--btn-success-bg-colour: #073655;
--btn-success-border-colour: #0e639c;
--btn-success-hover-font-colour: #fff;
--btn-success-hover-bg-colour: #0e639c;
--btn-success-hover-border-colour: #0e639c;
/* Highlighter colours */
--hl1: #264f78;
--hl2: #675351;
--hl3: #ffb6b6;
--hl4: #fcf8e3;
--hl5: #8de768;
/* Scrollbar */
--scrollbar-track: #1e1e1e;
--scrollbar-thumb: #424242;
--scrollbar-hover: #4e4e4e;
/* Misc. */
--drop-file-border-colour: #0e639c;
--popover-background: #444;
--popover-border-colour: #555;
--code-background: #0e639c;
--code-font-colour: #fff;
}

View File

@@ -0,0 +1,73 @@
/**
* General styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
body {
font-family: var(--primary-font-family);
font-size: var(--primary-font-size);
line-height: var(--primary-line-height);
color: var(--primary-font-colour);
background-color: var(--primary-background-colour);
}
.subtext {
font-style: italic;
font-size: var(--subtext-font-size);
color: var(--subtext-font-colour);
}
.word-wrap {
white-space: pre !important;
word-wrap: normal !important;
overflow-x: scroll !important;
}
.clearfix {
clear: both;
height: 0;
}
.blur {
color: transparent !important;
text-shadow: rgba(0, 0, 0, 0.95) 0 0 10px !important;
}
.no-select {
user-select: none;
}
.konami {
transform: rotate(180deg);
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background-color: var(--scrollbar-track);
}
::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--scrollbar-hover);
}
::-webkit-scrollbar-corner {
background-color: var(--scrollbar-track);
}
/* Highlighters */
.hl1 { background-color: var(--hl1); }
.hl2 { background-color: var(--hl2); }
.hl3 { background-color: var(--hl3); } /* Half-Life 3 confirmed :O */
.hl4 { background-color: var(--hl4); }
.hl5 { background-color: var(--hl5); }

View File

@@ -0,0 +1,223 @@
/**
* Overrides for vendor styles
*
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
/* Bootstrap */
button,
a:focus {
outline: none;
}
.btn-default {
color: var(--btn-default-font-colour);
background-color: var(--btn-default-bg-colour);
border-color: var(--btn-default-border-colour);
}
.btn-default:hover,
.btn-default:active,
.btn-default:hover:active,
.open>.dropdown-toggle.btn-default {
color: var(--btn-default-hover-font-colour);
background-color: var(--btn-default-hover-bg-colour);
border-color: var(--btn-default-hover-border-colour);
}
.btn-default:focus,
.open>.dropdown-toggle.btn-default:hover,
.open>.dropdown-toggle.btn-default:focus {
color: var(--btn-default-font-colour);
background-color: var(--btn-default-bg-colour);
border-color: var(--btn-default-hover-border-colour);
}
.btn-default[disabled]:hover {
background-color: var(--primary-background-colour);
border-color: var(--primary-border-colour);
}
.btn-success {
color: var(--btn-success-font-colour);
background-color: var(--btn-success-bg-colour);
border-color: var(--btn-success-border-colour);
}
.btn-success:hover,
.btn-success:active,
.btn-success:focus,
.btn-success:hover:active {
color: var(--btn-success-hover-font-colour);
background-color: var(--btn-success-hover-bg-colour);
border-color: var(--btn-success-hover-border-colour);
}
.btn,
.btn-lg,
.nav-tabs>li>a,
.form-control,
.popover,
.alert,
.modal-content,
.tooltip-inner,
.dropdown-menu {
border-radius: 0 !important;
}
.btn.dropdown-toggle {
height: 34px;
}
input[type="search"] {
-webkit-appearance: searchfield;
box-shadow: none;
}
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
.modal {
overflow-y: auto;
}
.modal-content {
background-color: var(--primary-background-colour);
}
.modal-header,
.modal-footer {
border-color: var(--primary-border-colour);
}
.form-control {
background-color: transparent;
border-color: var(--primary-border-colour);
color: var(--primary-font-colour);
}
code {
border: 0;
white-space: pre-wrap;
font-family: var(--fixed-width-font-family);
background-color: var(--code-background);
color: var(--code-font-colour);
}
pre {
border-radius: 0 !important;
background-color: var(--secondary-background-colour);
border-color: var(--secondary-border-colour);
color: var(--fixed-width-font-colour);
}
blockquote {
font-size: inherit;
border-left-color: var(--secondary-border-colour);
}
blockquote a {
cursor: pointer;
}
optgroup {
font-weight: bold;
}
.panel-body:before,
.panel-body:after {
content: "";
}
.table-nonfluid {
width: auto !important;
}
.popover {
background-color: var(--popover-background);
border-color: var(--popover-border-colour);
}
.popover.right>.arrow {
border-right-color: var(--popover-border-colour);
}
.popover.right>.arrow:after {
border-right-color: var(--popover-background);
}
.nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover {
background-color: var(--primary-background-colour);
border-color: var(--primary-border-colour);
border-bottom-color: transparent;
color: var(--primary-font-colour);
}
.nav-tabs {
border-color: var(--primary-border-colour);
}
.nav>li>a:focus, .nav>li>a:hover {
background-color: var(--secondary-border-colour);
}
.nav-tabs>li>a:hover {
border-color: var(--secondary-border-colour) var(--secondary-border-colour) var(--primary-border-colour);
}
.dropdown-menu {
background-color: var(--primary-background-colour);
}
.dropdown-menu>li>a {
color: var(--primary-font-colour);
}
.dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover {
background-color: var(--secondary-background-colour);
color: var(--primary-font-colour);
}
/* Bootstrap-switch */
.bootstrap-switch,
.bootstrap-switch-container,
.bootstrap-switch-handle-on,
.bootstrap-switch-handle-off,
.bootstrap-switch-label {
border-radius: 0 !important;
}
.bootstrap-switch .bootstrap-switch-label {
background-color: transparent;
}
.bootstrap-switch {
border-color: var(--primary-border-colour);
}
/* Sortable */
.sortable-ghost {
opacity: 0.6;
}
/* Bootstrap Colorpicker */
.colorpicker-element {
float: left;
margin-right: 15px;
}
.colorpicker-color,
.colorpicker-color div {
height: 100px;
}

View File

@@ -38,17 +38,17 @@ import Chef from "../src/core/Chef.js";
TestRegister.prototype.runTests = function() {
return Promise.all(
this.tests.map(function(test, i) {
let chef = new Chef();
const chef = new Chef();
return Promise.resolve(chef.bake(
return chef.bake(
test.input,
test.recipeConfig,
{},
0,
false
))
)
.then(function(result) {
let ret = {
const ret = {
test: test,
status: null,
output: null,

View File

@@ -13,14 +13,16 @@ import "babel-polyfill";
import TestRegister from "./TestRegister.js";
import "./tests/operations/Base58.js";
import "./tests/operations/ByteRepr.js";
import "./tests/operations/CharEnc.js";
import "./tests/operations/Code.js";
import "./tests/operations/Compress.js";
import "./tests/operations/FlowControl.js";
import "./tests/operations/Image.js";
import "./tests/operations/MorseCode.js";
import "./tests/operations/StrUtils.js";
let allTestsPassing = true,
testStatusCounts = {
let allTestsPassing = true;
const testStatusCounts = {
total: 0,
};
@@ -32,7 +34,7 @@ let allTestsPassing = true,
* @returns {string}
*/
function statusToIcon(status) {
let icons = {
const icons = {
erroring: "🔥",
failing: "❌",
passing: "✔️️",
@@ -48,7 +50,7 @@ function statusToIcon(status) {
*/
function handleTestResult(testResult) {
allTestsPassing = allTestsPassing && testResult.status === "passing";
let newCount = (testStatusCounts[testResult.status] || 0) + 1;
const newCount = (testStatusCounts[testResult.status] || 0) + 1;
testStatusCounts[testResult.status] = newCount;
testStatusCounts.total += 1;
@@ -74,7 +76,7 @@ function handleTestResult(testResult) {
setTimeout(function() {
console.log("Tests took longer than 10 seconds to run, returning.");
process.exit(1);
}, 1 * 1000);
}, 10 * 1000);
TestRegister.runTests()
@@ -83,8 +85,8 @@ TestRegister.runTests()
console.log("\n");
for (let testStatus in testStatusCounts) {
let count = testStatusCounts[testStatus];
for (const testStatus in testStatusCounts) {
const count = testStatusCounts[testStatus];
if (count > 0) {
console.log(testStatus.toUpperCase(), count);
}

View File

@@ -0,0 +1,90 @@
/**
* CharEnc tests.
*
* @author tlwr [toby@toby.codes]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister.js";
TestRegister.addTests([
{
name: "Encode text, Decode text: nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
"op": "Encode text",
"args": ["UTF-8 (65001)"]
},
{
"op": "Decode text",
"args": ["UTF-8 (65001)"]
},
],
},
{
name: "Encode text, Decode text: hello",
input: "hello",
expectedOutput: "hello",
recipeConfig: [
{
"op": "Encode text",
"args": ["UTF-8 (65001)"]
},
{
"op": "Decode text",
"args": ["UTF-8 (65001)"]
},
],
},
{
name: "Encode text (EBCDIC): hello",
input: "hello",
expectedOutput: "88 85 93 93 96",
recipeConfig: [
{
"op": "Encode text",
"args": ["IBM EBCDIC International (500)"]
},
{
"op": "To Hex",
"args": ["Space"]
},
],
},
{
name: "Decode text (EBCDIC): 88 85 93 93 96",
input: "88 85 93 93 96",
expectedOutput: "hello",
recipeConfig: [
{
"op": "From Hex",
"args": ["Space"]
},
{
"op": "Decode text",
"args": ["IBM EBCDIC International (500)"]
},
],
},
{
name: "Generate Base64 Windows Powershell",
input: "ZABpAHIAIAAiAGMAOgBcAHAAcgBvAGcAcgBhAG0AIABmAGkAbABlAHMAIgAgAA==",
expectedOutput: "dir \"c:\\program files\" ",
recipeConfig: [
{
"op": "From Base64",
"args": ["A-Za-z0-9+/=", true]
},
{
"op": "Decode text",
"args": ["UTF16LE (1200)"]
},
{
"op": "Encode text",
"args": ["UTF-8 (65001)"]
},
],
},
]);

View File

@@ -66,6 +66,62 @@ TestRegister.addTests([
{"op":"To Base64", "args":["A-Za-z0-9+/="]}
]
},
{
name: "Jump: skips 0",
input: [
"should be changed",
].join("\n"),
expectedOutput: [
"should be changed was changed",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [0, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should be changed"
},
"should be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Jump: skips 1",
input: [
"shouldnt be changed",
].join("\n"),
expectedOutput: [
"shouldnt be changed",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [1, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "shouldnt be changed"
},
"shouldnt be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Conditional Jump: Skips 0",
input: [
@@ -141,4 +197,81 @@ TestRegister.addTests([
}
]
},
{
name: "Conditional Jump: Skips 1",
input: [
"match",
"should not be changed",
"should be changed",
].join("\n"),
expectedOutput: [
"match",
"should not be changed",
"should be changed was changed"
].join("\n"),
recipeConfig: [
{
op: "Conditional Jump",
args: ["match", 1, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should not be changed"
},
"should not be changed was changed",
true,
true,
true,
],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should be changed"
},
"should be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Conditional Jump: Skips negatively",
input: [
"match",
].join("\n"),
expectedOutput: [
"replaced",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [1],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "match"
},
"replaced",
true,
true,
true,
],
},
{
op: "Conditional Jump",
args: ["match", -2, 10],
},
],
},
]);

File diff suppressed because one or more lines are too long