Merge remote-tracking branch 'upstream/master' into base64Alphabets
15
.travis.yml
@ -2,6 +2,7 @@ language: node_js
|
||||
node_js:
|
||||
- lts/dubnium
|
||||
cache: npm
|
||||
os: linux
|
||||
addons:
|
||||
chrome: stable
|
||||
install: npm install
|
||||
@ -10,7 +11,7 @@ before_script:
|
||||
- export NODE_OPTIONS=--max_old_space_size=2048
|
||||
script:
|
||||
- grunt lint
|
||||
- grunt test
|
||||
- npm test
|
||||
- grunt testnodeconsumer
|
||||
- grunt prod --msg="$COMPILE_MSG"
|
||||
- xvfb-run --server-args="-screen 0 1200x800x24" grunt testui
|
||||
@ -19,16 +20,16 @@ before_deploy:
|
||||
- grunt copy:ghPages
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
github_token: $GITHUB_TOKEN
|
||||
edge: true
|
||||
token: $GITHUB_TOKEN
|
||||
local_dir: build/prod/
|
||||
target_branch: gh-pages
|
||||
on:
|
||||
repo: gchq/CyberChef
|
||||
branch: master
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
edge: true
|
||||
token:
|
||||
secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
|
||||
file_glob: true
|
||||
file:
|
||||
@ -38,9 +39,9 @@ deploy:
|
||||
repo: gchq/CyberChef
|
||||
tags: true
|
||||
- provider: npm
|
||||
skip_cleanup: true
|
||||
edge: true
|
||||
email: "n1474335@gmail.com"
|
||||
api_key:
|
||||
api_token:
|
||||
secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
|
||||
on:
|
||||
tags: true
|
||||
|
45
CHANGELOG.md
@ -2,6 +2,30 @@
|
||||
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
|
||||
|
||||
|
||||
### [9.20.0] - 2020-03-27
|
||||
- 'Parse ObjectID Timestamp' operation added [@dmfj] | [#987]
|
||||
|
||||
### [9.19.0] - 2020-03-24
|
||||
- Improvements to the 'Magic' operation, allowing it to recognise more data formats and provide more accurate results [@n1073645] [@n1474335] | [#966] [b765534b](https://github.com/gchq/CyberChef/commit/b765534b8b2a0454a5132a0a52d1d8844bcbdaaa)
|
||||
|
||||
### [9.18.0] - 2020-03-13
|
||||
- 'Convert to NATO alphabet' operation added [@MarvinJWendt] | [#674]
|
||||
|
||||
### [9.17.0] - 2020-03-13
|
||||
- 'Generate Image' operation added [@pointhi] | [#683]
|
||||
|
||||
### [9.16.0] - 2020-03-06
|
||||
- 'Colossus' operation added [@VirtualColossus] | [#917]
|
||||
|
||||
### [9.15.0] - 2020-03-05
|
||||
- 'CipherSaber2 Encrypt' and 'CipherSaber2 Decrypt' operations added [@n1073645] | [#952]
|
||||
|
||||
### [9.14.0] - 2020-03-05
|
||||
- 'Luhn Checksum' operation added [@n1073645] | [#965]
|
||||
|
||||
### [9.13.0] - 2020-02-13
|
||||
- 'Rail Fence Cipher Encode' and 'Rail Fence Cipher Decode' operations added [@Flavsditz] | [#948]
|
||||
|
||||
### [9.12.0] - 2019-12-20
|
||||
- 'Normalise Unicode' operation added [@matthieuxyz] | [#912]
|
||||
|
||||
@ -200,6 +224,14 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
|
||||
|
||||
[9.20.0]: https://github.com/gchq/CyberChef/releases/tag/v9.20.0
|
||||
[9.19.0]: https://github.com/gchq/CyberChef/releases/tag/v9.19.0
|
||||
[9.18.0]: https://github.com/gchq/CyberChef/releases/tag/v9.18.0
|
||||
[9.17.0]: https://github.com/gchq/CyberChef/releases/tag/v9.17.0
|
||||
[9.16.0]: https://github.com/gchq/CyberChef/releases/tag/v9.16.0
|
||||
[9.15.0]: https://github.com/gchq/CyberChef/releases/tag/v9.15.0
|
||||
[9.14.0]: https://github.com/gchq/CyberChef/releases/tag/v9.14.0
|
||||
[9.13.0]: https://github.com/gchq/CyberChef/releases/tag/v9.13.0
|
||||
[9.12.0]: https://github.com/gchq/CyberChef/releases/tag/v9.12.0
|
||||
[9.11.0]: https://github.com/gchq/CyberChef/releases/tag/v9.11.0
|
||||
[9.10.0]: https://github.com/gchq/CyberChef/releases/tag/v9.10.0
|
||||
@ -261,6 +293,7 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@n1474335]: https://github.com/n1474335
|
||||
[@d98762625]: https://github.com/d98762625
|
||||
[@j433866]: https://github.com/j433866
|
||||
[@n1073645]: https://github.com/n1073645
|
||||
[@GCHQ77703]: https://github.com/GCHQ77703
|
||||
[@h345983745]: https://github.com/h345983745
|
||||
[@s2224834]: https://github.com/s2224834
|
||||
@ -286,6 +319,10 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[@VirtualColossus]: https://github.com/VirtualColossus
|
||||
[@cbeuw]: https://github.com/cbeuw
|
||||
[@matthieuxyz]: https://github.com/matthieuxyz
|
||||
[@Flavsditz]: https://github.com/Flavsditz
|
||||
[@pointhi]: https://github.com/pointhi
|
||||
[@MarvinJWendt]: https://github.com/MarvinJWendt
|
||||
[@dmfj]: https://github.com/dmfj
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
@ -348,5 +385,13 @@ All major and minor version changes will be documented in this file. Details of
|
||||
[#627]: https://github.com/gchq/CyberChef/pull/627
|
||||
[#632]: https://github.com/gchq/CyberChef/pull/632
|
||||
[#653]: https://github.com/gchq/CyberChef/pull/653
|
||||
[#674]: https://github.com/gchq/CyberChef/pull/674
|
||||
[#683]: https://github.com/gchq/CyberChef/pull/683
|
||||
[#865]: https://github.com/gchq/CyberChef/pull/865
|
||||
[#912]: https://github.com/gchq/CyberChef/pull/912
|
||||
[#917]: https://github.com/gchq/CyberChef/pull/917
|
||||
[#948]: https://github.com/gchq/CyberChef/pull/948
|
||||
[#952]: https://github.com/gchq/CyberChef/pull/952
|
||||
[#965]: https://github.com/gchq/CyberChef/pull/965
|
||||
[#966]: https://github.com/gchq/CyberChef/pull/966
|
||||
[#987]: https://github.com/gchq/CyberChef/pull/987
|
||||
|
17
Gruntfile.js
@ -36,11 +36,10 @@ module.exports = function (grunt) {
|
||||
"clean:node", "clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex"
|
||||
]);
|
||||
|
||||
grunt.registerTask("test",
|
||||
"A task which runs all the operation tests in the tests directory.",
|
||||
grunt.registerTask("configTests",
|
||||
"A task which configures config files in preparation for tests to be run. Use `npm tests` to run tests.",
|
||||
[
|
||||
"clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex",
|
||||
"exec:nodeTests", "exec:opTests"
|
||||
"clean:config", "clean:nodeConfig", "exec:generateConfig", "exec:generateNodeIndex"
|
||||
]);
|
||||
|
||||
grunt.registerTask("testui",
|
||||
@ -55,7 +54,6 @@ module.exports = function (grunt) {
|
||||
"Lints the code base",
|
||||
["eslint", "exec:repoSize"]);
|
||||
|
||||
grunt.registerTask("tests", "test");
|
||||
grunt.registerTask("lint", "eslint");
|
||||
|
||||
grunt.registerTask("findModules",
|
||||
@ -219,6 +217,7 @@ module.exports = function (grunt) {
|
||||
options: {
|
||||
webpack: webpackConfig,
|
||||
host: "0.0.0.0",
|
||||
port: grunt.option("port") || 8080,
|
||||
disableHostCheck: true,
|
||||
overlay: true,
|
||||
inline: false,
|
||||
@ -275,7 +274,7 @@ module.exports = function (grunt) {
|
||||
connect: {
|
||||
prod: {
|
||||
options: {
|
||||
port: 8000,
|
||||
port: grunt.option("port") || 8000,
|
||||
base: "build/prod/"
|
||||
}
|
||||
}
|
||||
@ -384,15 +383,9 @@ module.exports = function (grunt) {
|
||||
]),
|
||||
sync: true
|
||||
},
|
||||
opTests: {
|
||||
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
|
||||
},
|
||||
browserTests: {
|
||||
command: "./node_modules/.bin/nightwatch --env prod"
|
||||
},
|
||||
nodeTests: {
|
||||
command: "node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs"
|
||||
},
|
||||
setupNodeConsumers: {
|
||||
command: chainCommands([
|
||||
"echo '\n--- Testing node consumers ---'",
|
||||
|
7800
package-lock.json
generated
93
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.12.0",
|
||||
"version": "9.20.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",
|
||||
@ -36,21 +36,22 @@
|
||||
"node >= 10"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.6",
|
||||
"autoprefixer": "^9.7.3",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"@babel/core": "^7.8.7",
|
||||
"@babel/plugin-transform-runtime": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.7",
|
||||
"autoprefixer": "^9.7.4",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"chromedriver": "^78.0.1",
|
||||
"chromedriver": "^80.0.1",
|
||||
"cli-progress": "^3.6.0",
|
||||
"colors": "^1.4.0",
|
||||
"copy-webpack-plugin": "^5.0.5",
|
||||
"css-loader": "^3.2.1",
|
||||
"eslint": "^6.7.2",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"eslint": "^6.8.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"file-loader": "^5.0.2",
|
||||
"grunt": "^1.0.4",
|
||||
"file-loader": "^6.0.0",
|
||||
"grunt": "^1.1.0",
|
||||
"grunt-accessibility": "~6.0.0",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-concurrent": "^3.0.0",
|
||||
@ -64,29 +65,29 @@
|
||||
"grunt-zip": "^0.18.2",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"mini-css-extract-plugin": "^0.8.0",
|
||||
"nightwatch": "^1.3.2",
|
||||
"node-sass": "^4.13.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"nightwatch": "^1.3.4",
|
||||
"node-sass": "^4.13.1",
|
||||
"postcss-css-variables": "^0.14.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"prompt": "^1.0.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"sitemap": "^5.1.0",
|
||||
"style-loader": "^1.0.1",
|
||||
"svg-url-loader": "^3.0.3",
|
||||
"url-loader": "^3.0.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-bundle-analyzer": "^3.6.0",
|
||||
"webpack-dev-server": "^3.9.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sitemap": "^6.1.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"svg-url-loader": "^5.0.0",
|
||||
"url-loader": "^4.0.0",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-bundle-analyzer": "^3.6.1",
|
||||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.7.0",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"@babel/polyfill": "^7.8.7",
|
||||
"@babel/runtime": "^7.8.7",
|
||||
"arrive": "^2.4.1",
|
||||
"avsc": "^5.4.16",
|
||||
"avsc": "^5.4.19",
|
||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"bignumber.js": "^9.0.0",
|
||||
@ -94,26 +95,26 @@
|
||||
"bootstrap": "4.4.1",
|
||||
"bootstrap-colorpicker": "^3.2.0",
|
||||
"bootstrap-material-design": "^4.1.2",
|
||||
"bson": "^4.0.2",
|
||||
"bson": "^4.0.3",
|
||||
"chi-squared": "^1.1.0",
|
||||
"codepage": "^1.14.0",
|
||||
"core-js": "^3.4.8",
|
||||
"core-js": "^3.6.4",
|
||||
"crypto-api": "^0.8.5",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"crypto-js": "^4.0.0",
|
||||
"ctph.js": "0.0.5",
|
||||
"d3": "^5.14.2",
|
||||
"d3": "^5.15.0",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"diff": "^4.0.1",
|
||||
"es6-promisify": "^6.0.2",
|
||||
"escodegen": "^1.12.0",
|
||||
"diff": "^4.0.2",
|
||||
"es6-promisify": "^6.1.0",
|
||||
"escodegen": "^1.14.1",
|
||||
"esm": "^3.2.25",
|
||||
"esmangle": "^1.0.1",
|
||||
"esprima": "^4.0.1",
|
||||
"exif-parser": "^0.1.12",
|
||||
"file-saver": "^2.0.2",
|
||||
"geodesy": "^1.1.3",
|
||||
"highlight.js": "^9.16.2",
|
||||
"jimp": "^0.9.3",
|
||||
"highlight.js": "^9.18.1",
|
||||
"jimp": "^0.9.5",
|
||||
"jquery": "3.4.1",
|
||||
"js-crc": "^0.2.0",
|
||||
"js-sha3": "^0.8.0",
|
||||
@ -122,44 +123,44 @@
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsqr": "^1.2.0",
|
||||
"jsrsasign": "8.0.12",
|
||||
"kbpgp": "2.1.6",
|
||||
"kbpgp": "2.1.13",
|
||||
"libbzip2-wasm": "0.0.4",
|
||||
"libyara-wasm": "^1.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"loglevel": "^1.6.6",
|
||||
"loglevel": "^1.6.7",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"markdown-it": "^10.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-timezone": "^0.5.27",
|
||||
"moment-timezone": "^0.5.28",
|
||||
"ngeohash": "^0.6.3",
|
||||
"node-forge": "^0.9.1",
|
||||
"node-md6": "^0.1.0",
|
||||
"nodom": "^2.4.0",
|
||||
"notepack.io": "^2.2.0",
|
||||
"notepack.io": "^2.3.0",
|
||||
"nwmatcher": "^1.4.4",
|
||||
"otp": "^0.1.3",
|
||||
"popper.js": "^1.16.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"qr-image": "^3.2.0",
|
||||
"scryptsy": "^2.1.0",
|
||||
"snackbarjs": "^1.1.0",
|
||||
"sortablejs": "^1.10.1",
|
||||
"sortablejs": "^1.10.2",
|
||||
"split.js": "^1.5.11",
|
||||
"ssdeep.js": "0.0.2",
|
||||
"tesseract.js": "^2.0.0-alpha.15",
|
||||
"ua-parser-js": "^0.7.20",
|
||||
"tesseract.js": "^2.0.2",
|
||||
"ua-parser-js": "^0.7.21",
|
||||
"unorm": "^1.6.0",
|
||||
"utf8": "^3.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xmldom": "^0.1.27",
|
||||
"xmldom": "^0.3.0",
|
||||
"xpath": "0.0.27",
|
||||
"xregexp": "^4.2.4",
|
||||
"xregexp": "^4.3.0",
|
||||
"zlibjs": "^0.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "grunt dev",
|
||||
"build": "grunt prod",
|
||||
"repl": "node src/node/repl.js",
|
||||
"test": "grunt test",
|
||||
"test": "grunt configTests && node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs && node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs",
|
||||
"test-node-consumer": "grunt testnodeconsumer",
|
||||
"testui": "grunt testui",
|
||||
"testuidev": "npx nightwatch --env=dev",
|
||||
|
@ -39,7 +39,7 @@ class Chef {
|
||||
*/
|
||||
async bake(input, recipeConfig, options) {
|
||||
log.debug("Chef baking");
|
||||
const startTime = new Date().getTime(),
|
||||
const startTime = Date.now(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
containsFc = recipe.containsFlowControl(),
|
||||
notUTF8 = options && "treatAsUtf8" in options && !options.treatAsUtf8;
|
||||
@ -84,7 +84,7 @@ class Chef {
|
||||
result: await this.dish.get(returnType, notUTF8),
|
||||
type: Dish.enumLookup(this.dish.type),
|
||||
progress: progress,
|
||||
duration: new Date().getTime() - startTime,
|
||||
duration: Date.now() - startTime,
|
||||
error: error
|
||||
};
|
||||
}
|
||||
@ -110,7 +110,7 @@ class Chef {
|
||||
silentBake(recipeConfig) {
|
||||
log.debug("Running silent bake");
|
||||
|
||||
const startTime = new Date().getTime(),
|
||||
const startTime = Date.now(),
|
||||
recipe = new Recipe(recipeConfig),
|
||||
dish = new Dish();
|
||||
|
||||
@ -119,7 +119,7 @@ class Chef {
|
||||
} catch (err) {
|
||||
// Suppress all errors
|
||||
}
|
||||
return new Date().getTime() - startTime;
|
||||
return Date.now() - startTime;
|
||||
}
|
||||
|
||||
|
||||
@ -146,7 +146,12 @@ class Chef {
|
||||
const func = direction === "forward" ? highlights[i].f : highlights[i].b;
|
||||
|
||||
if (typeof func == "function") {
|
||||
pos = func(pos, highlights[i].args);
|
||||
try {
|
||||
pos = func(pos, highlights[i].args);
|
||||
} catch (err) {
|
||||
// Throw away highlighting errors
|
||||
pos = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,7 @@ class Ingredient {
|
||||
return data;
|
||||
}
|
||||
case "number":
|
||||
if (data === null) return data;
|
||||
number = parseFloat(data);
|
||||
if (isNaN(number)) {
|
||||
const sample = Utils.truncate(data.toString(), 10);
|
||||
|
@ -1182,6 +1182,7 @@ class Utils {
|
||||
"CRLF": /\r\n/g,
|
||||
"Forward slash": /\//g,
|
||||
"Backslash": /\\/g,
|
||||
"0x with comma": /,?0x/g,
|
||||
"0x": /0x/g,
|
||||
"\\x": /\\x/g,
|
||||
"None": /\s+/g // Included here to remove whitespace when there shouldn't be any
|
||||
@ -1335,7 +1336,7 @@ export function sendStatusMessage(msg) {
|
||||
self.sendStatusMessage(msg);
|
||||
else if (isWebEnvironment())
|
||||
app.alert(msg, 10000);
|
||||
else if (isNodeEnvironment())
|
||||
else if (isNodeEnvironment() && !global.TESTING)
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug(msg);
|
||||
}
|
||||
|
@ -95,7 +95,11 @@
|
||||
"Affine Cipher Decode",
|
||||
"A1Z26 Cipher Encode",
|
||||
"A1Z26 Cipher Decode",
|
||||
"Rail Fence Cipher Encode",
|
||||
"Rail Fence Cipher Decode",
|
||||
"Atbash Cipher",
|
||||
"CipherSaber2 Encrypt",
|
||||
"CipherSaber2 Decrypt",
|
||||
"Substitute",
|
||||
"Derive PBKDF2 key",
|
||||
"Derive EVP key",
|
||||
@ -111,7 +115,8 @@
|
||||
"Bombe",
|
||||
"Multiple Bombe",
|
||||
"Typex",
|
||||
"Lorenz"
|
||||
"Lorenz",
|
||||
"Colossus"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -196,7 +201,8 @@
|
||||
"Encode text",
|
||||
"Decode text",
|
||||
"Remove Diacritics",
|
||||
"Unescape Unicode Characters"
|
||||
"Unescape Unicode Characters",
|
||||
"Convert to NATO alphabet"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -236,6 +242,7 @@
|
||||
"Convert co-ordinate format",
|
||||
"Show on map",
|
||||
"Parse UNIX file permissions",
|
||||
"Parse ObjectID timestamp",
|
||||
"Swap endianness",
|
||||
"Parse colour code",
|
||||
"Escape string",
|
||||
@ -330,6 +337,7 @@
|
||||
"Fletcher-32 Checksum",
|
||||
"Fletcher-64 Checksum",
|
||||
"Adler-32 Checksum",
|
||||
"Luhn Checksum",
|
||||
"CRC-8 Checksum",
|
||||
"CRC-16 Checksum",
|
||||
"CRC-32 Checksum",
|
||||
@ -389,6 +397,7 @@
|
||||
"ops": [
|
||||
"Render Image",
|
||||
"Play Media",
|
||||
"Generate Image",
|
||||
"Optical Character Recognition",
|
||||
"Remove EXIF",
|
||||
"Extract EXIF",
|
||||
|
@ -42,13 +42,10 @@ for (const opObj in Ops) {
|
||||
outputType: op.presentType,
|
||||
flowControl: op.flowControl,
|
||||
manualBake: op.manualBake,
|
||||
args: op.args
|
||||
args: op.args,
|
||||
checks: op.checks
|
||||
};
|
||||
|
||||
if ("patterns" in op) {
|
||||
operationConfig[op.name].patterns = op.patterns;
|
||||
}
|
||||
|
||||
if (!(op.module in modules))
|
||||
modules[op.module] = {};
|
||||
modules[op.module][op.name] = opObj;
|
||||
|
34
src/core/lib/CipherSaber2.mjs
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
export function encode(tempIVP, key, rounds, input) {
|
||||
const ivp = new Uint8Array(key.concat(tempIVP));
|
||||
const state = new Array(256).fill(0);
|
||||
let j = 0, i = 0;
|
||||
const result = [];
|
||||
|
||||
// Mixing states based off of IV.
|
||||
for (let i = 0; i < 256; i++)
|
||||
state[i] = i;
|
||||
const ivpLength = ivp.length;
|
||||
for (let r = 0; r < rounds; r ++) {
|
||||
for (let k = 0; k < 256; k++) {
|
||||
j = (j + state[k] + ivp[k % ivpLength]) % 256;
|
||||
[state[k], state[j]] = [state[j], state[k]];
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i = 0;
|
||||
|
||||
// XOR cipher with key.
|
||||
for (let x = 0; x < input.length; x++) {
|
||||
i = (++i) % 256;
|
||||
j = (j + state[i]) % 256;
|
||||
[state[i], state[j]] = [state[j], state[i]];
|
||||
const n = (state[i] + state[j]) % 256;
|
||||
result.push(state[n] ^ input[x]);
|
||||
}
|
||||
return result;
|
||||
}
|
417
src/core/lib/Colossus.mjs
Normal file
@ -0,0 +1,417 @@
|
||||
/**
|
||||
* Colossus - an emulation of the world's first electronic computer
|
||||
*
|
||||
* @author VirtualColossus [martin@virtualcolossus.co.uk]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import {INIT_PATTERNS, ITA2_TABLE, ROTOR_SIZES} from "../lib/Lorenz.mjs";
|
||||
|
||||
/**
|
||||
* Colossus simulator class.
|
||||
*/
|
||||
export class ColossusComputer {
|
||||
/**
|
||||
* Construct a Colossus.
|
||||
*
|
||||
* @param {string} ciphertext
|
||||
* @param {string} pattern - named pattern of Chi, Mu and Psi wheels
|
||||
* @param {Object} qbusin - which data inputs are being sent to q bus - each can be null, plain or delta
|
||||
* @param {Object[]} qbusswitches - Q bus calculation switches, multiple rows
|
||||
* @param {Object} control - control switches which specify stepping modes
|
||||
* @param {Object} starts - rotor start positions
|
||||
*/
|
||||
constructor(ciphertext, pattern, qbusin, qbusswitches, control, starts, settotal, limit) {
|
||||
this.ITAlookup = ITA2_TABLE;
|
||||
this.ReverseITAlookup = {};
|
||||
for (const letter in this.ITAlookup) {
|
||||
const code = this.ITAlookup[letter];
|
||||
this.ReverseITAlookup[code] = letter;
|
||||
}
|
||||
|
||||
this.initThyratrons(pattern);
|
||||
|
||||
this.ciphertext = ciphertext;
|
||||
this.qbusin = qbusin;
|
||||
this.qbusswitches = qbusswitches;
|
||||
this.control = control;
|
||||
this.starts = starts;
|
||||
this.settotal = settotal;
|
||||
this.limitations = limit;
|
||||
|
||||
|
||||
this.allCounters = [0, 0, 0, 0, 0];
|
||||
|
||||
this.Zbits = [0, 0, 0, 0, 0]; // Z input is the cipher tape
|
||||
this.ZbitsOneBack = [0, 0, 0, 0, 0]; // for delta
|
||||
this.Qbits = [0, 0, 0, 0, 0]; // input generated for placing onto the Q-bus (the logic processor)
|
||||
|
||||
this.Xbits = [0, 0, 0, 0, 0]; // X is the Chi wheel bits
|
||||
this.Xptr = [0, 0, 0, 0, 0]; // pointers to the current X bits (Chi wheels)
|
||||
this.XbitsOneBack = [0, 0, 0, 0, 0]; // the X bits one back (for delta)
|
||||
|
||||
this.Sbits = [0, 0, 0, 0, 0]; // S is the Psi wheel bits
|
||||
this.Sptr = [0, 0, 0, 0, 0]; // pointers to the current S bits (Psi wheels)
|
||||
this.SbitsOneBack = [0, 0, 0, 0, 0]; // the S bits one back (for delta)
|
||||
|
||||
this.Mptr = [0, 0];
|
||||
|
||||
this.rotorPtrs = {};
|
||||
|
||||
this.totalmotor = 0;
|
||||
this.P5Zbit = [0, 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a run
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
run() {
|
||||
const result = {
|
||||
printout: ""
|
||||
};
|
||||
|
||||
// loop until our start positions are back to the beginning
|
||||
this.rotorPtrs = {X1: this.starts.X1, X2: this.starts.X2, X3: this.starts.X3, X4: this.starts.X4, X5: this.starts.X5, M61: this.starts.M61, M37: this.starts.M37, S1: this.starts.S1, S2: this.starts.S2, S3: this.starts.S3, S4: this.starts.S4, S5: this.starts.S5};
|
||||
// this.rotorPtrs = this.starts;
|
||||
let runcount = 1;
|
||||
|
||||
const fast = this.control.fast;
|
||||
const slow = this.control.slow;
|
||||
|
||||
// Print Headers
|
||||
result.printout += fast + " " + slow + "\n";
|
||||
|
||||
do {
|
||||
this.allCounters = [0, 0, 0, 0, 0];
|
||||
this.ZbitsOneBack = [0, 0, 0, 0, 0];
|
||||
this.XbitsOneBack = [0, 0, 0, 0, 0];
|
||||
|
||||
// Run full tape loop and process counters
|
||||
this.runTape();
|
||||
|
||||
// Only print result if larger than set total
|
||||
let fastRef = "00";
|
||||
let slowRef = "00";
|
||||
if (fast !== "") fastRef = this.rotorPtrs[fast].toString().padStart(2, "0");
|
||||
if (slow !== "") slowRef = this.rotorPtrs[slow].toString().padStart(2, "0");
|
||||
let printline = "";
|
||||
for (let c=0;c<5;c++) {
|
||||
if (this.allCounters[c] > this.settotal) {
|
||||
printline += String.fromCharCode(c+97) + this.allCounters[c]+" ";
|
||||
}
|
||||
}
|
||||
if (printline !== "") {
|
||||
result.printout += fastRef + " " + slowRef + " : ";
|
||||
result.printout += printline;
|
||||
result.printout += "\n";
|
||||
}
|
||||
|
||||
// Step fast rotor if required
|
||||
if (fast !== "") {
|
||||
this.rotorPtrs[fast]++;
|
||||
if (this.rotorPtrs[fast] > ROTOR_SIZES[fast]) this.rotorPtrs[fast] = 1;
|
||||
}
|
||||
|
||||
// Step slow rotor if fast rotor has returned to initial start position
|
||||
if (slow !== "" && this.rotorPtrs[fast] === this.starts[fast]) {
|
||||
this.rotorPtrs[slow]++;
|
||||
if (this.rotorPtrs[slow] > ROTOR_SIZES[slow]) this.rotorPtrs[slow] = 1;
|
||||
}
|
||||
|
||||
runcount++;
|
||||
} while (JSON.stringify(this.rotorPtrs) !== JSON.stringify(this.starts));
|
||||
|
||||
result.counters = this.allCounters;
|
||||
result.runcount = runcount;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tape loop
|
||||
*/
|
||||
runTape() {
|
||||
let charZin = "";
|
||||
|
||||
this.Xptr = [this.rotorPtrs.X1, this.rotorPtrs.X2, this.rotorPtrs.X3, this.rotorPtrs.X4, this.rotorPtrs.X5];
|
||||
this.Mptr = [this.rotorPtrs.M37, this.rotorPtrs.M61];
|
||||
this.Sptr = [this.rotorPtrs.S1, this.rotorPtrs.S2, this.rotorPtrs.S3, this.rotorPtrs.S4, this.rotorPtrs.S5];
|
||||
|
||||
// Run full loop of all character on the input tape (Z)
|
||||
for (let i=0; i<this.ciphertext.length; i++) {
|
||||
charZin = this.ciphertext.charAt(i);
|
||||
|
||||
// Firstly, we check what inputs are specified on the Q-bus input switches
|
||||
this.getQbusInputs(charZin);
|
||||
|
||||
/*
|
||||
* Pattern conditions on individual impulses. Matching patterns of bits on the Q bus.
|
||||
* This is the top section on Colussus K rack - the Q bus programming switches
|
||||
*/
|
||||
const tmpcnt = this.runQbusProcessingConditional();
|
||||
|
||||
/*
|
||||
* Addition of impulses.
|
||||
* This is the bottom section of Colossus K rack.
|
||||
*/
|
||||
this.runQbusProcessingAddition(tmpcnt);
|
||||
|
||||
// Store Z bit impulse 5 two back required for P5 limitation
|
||||
this.P5Zbit[1] = this.P5Zbit[0];
|
||||
this.P5Zbit[0] = this.ITAlookup[charZin].split("")[4];
|
||||
|
||||
// Step rotors
|
||||
this.stepThyratrons();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step thyratron rings to simulate movement of Lorenz rotors
|
||||
* Chi rotors all step one per character
|
||||
* Motor M61 rotor steps one per character, M37 steps dependant on M61 setting
|
||||
* Psi rotors only step dependant on M37 setting + limitation
|
||||
*/
|
||||
stepThyratrons() {
|
||||
let X2bPtr = this.Xptr[1]-1;
|
||||
if (X2bPtr===0) X2bPtr = ROTOR_SIZES.X2;
|
||||
let S1bPtr = this.Sptr[0]-1;
|
||||
if (S1bPtr===0) S1bPtr = ROTOR_SIZES.S1;
|
||||
|
||||
// Get Chi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
|
||||
let X5bPtr=this.Xptr[4]-1;
|
||||
if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
|
||||
X5bPtr=X5bPtr-1;
|
||||
if (X5bPtr===0) X5bPtr=ROTOR_SIZES.X5;
|
||||
// Get Psi rotor 5 two back to calculate plaintext (Z+Chi+Psi=Plain)
|
||||
let S5bPtr=this.Sptr[4]-1;
|
||||
if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
|
||||
S5bPtr=S5bPtr-1;
|
||||
if (S5bPtr===0) S5bPtr=ROTOR_SIZES.S5;
|
||||
|
||||
const x2sw = this.limitations.X2;
|
||||
const s1sw = this.limitations.S1;
|
||||
const p5sw = this.limitations.P5;
|
||||
|
||||
// Limitation calculations
|
||||
let lim=1;
|
||||
if (x2sw) lim = this.rings.X[2][X2bPtr-1];
|
||||
if (s1sw) lim = lim ^ this.rings.S[1][S1bPtr-1];
|
||||
|
||||
// P5
|
||||
if (p5sw) {
|
||||
let p5lim = this.P5Zbit[1];
|
||||
p5lim = p5lim ^ this.rings.X[5][X5bPtr-1];
|
||||
p5lim = p5lim ^ this.rings.S[5][S5bPtr-1];
|
||||
lim = lim ^ p5lim;
|
||||
}
|
||||
|
||||
const basicmotor = this.rings.M[2][this.Mptr[0]-1];
|
||||
this.totalmotor = basicmotor;
|
||||
|
||||
if (x2sw || s1sw) {
|
||||
if (basicmotor===0 && lim===1) {
|
||||
this.totalmotor = 0;
|
||||
} else {
|
||||
this.totalmotor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Step Chi rotors
|
||||
for (let r=0; r<5; r++) {
|
||||
this.Xptr[r]++;
|
||||
if (this.Xptr[r] > ROTOR_SIZES["X"+(r+1)]) this.Xptr[r] = 1;
|
||||
}
|
||||
|
||||
if (this.totalmotor) {
|
||||
// Step Psi rotors
|
||||
for (let r=0; r<5; r++) {
|
||||
this.Sptr[r]++;
|
||||
if (this.Sptr[r] > ROTOR_SIZES["S"+(r+1)]) this.Sptr[r] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Move M37 rotor if M61 set
|
||||
if (this.rings.M[1][this.Mptr[1]-1]===1) this.Mptr[0]++;
|
||||
if (this.Mptr[0] > ROTOR_SIZES.M37) this.Mptr[0]=1;
|
||||
|
||||
// Always move M61 rotor
|
||||
this.Mptr[1]++;
|
||||
if (this.Mptr[1] > ROTOR_SIZES.M61) this.Mptr[1]=1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Q bus inputs
|
||||
*/
|
||||
getQbusInputs(charZin) {
|
||||
// Zbits - the bits from the current character from the cipher tape.
|
||||
this.Zbits = this.ITAlookup[charZin].split("");
|
||||
if (this.qbusin.Z === "Z") {
|
||||
// direct Z
|
||||
this.Qbits = this.Zbits;
|
||||
} else if (this.qbusin.Z === "ΔZ") {
|
||||
// delta Z, the Bitwise XOR of this character Zbits + last character Zbits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Qbits[b] = this.Zbits[b] ^ this.ZbitsOneBack[b];
|
||||
}
|
||||
}
|
||||
this.ZbitsOneBack = this.Zbits.slice(); // copy value of object, not reference
|
||||
|
||||
// Xbits - the current Chi wheel bits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Xbits[b] = this.rings.X[b+1][this.Xptr[b]-1];
|
||||
}
|
||||
if (this.qbusin.Chi !== "") {
|
||||
if (this.qbusin.Chi === "Χ") {
|
||||
// direct X added to Qbits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
|
||||
}
|
||||
} else if (this.qbusin.Chi === "ΔΧ") {
|
||||
// delta X
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Xbits[b];
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.XbitsOneBack[b];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.XbitsOneBack = this.Xbits.slice();
|
||||
|
||||
// Sbits - the current Psi wheel bits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Sbits[b] = this.rings.S[b+1][this.Sptr[b]-1];
|
||||
}
|
||||
if (this.qbusin.Psi !== "") {
|
||||
if (this.qbusin.Psi === "Ψ") {
|
||||
// direct S added to Qbits
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
|
||||
}
|
||||
} else if (this.qbusin.Psi === "ΔΨ") {
|
||||
// delta S
|
||||
for (let b=0;b<5;b++) {
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.Sbits[b];
|
||||
this.Qbits[b] = this.Qbits[b] ^ this.SbitsOneBack[b];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.SbitsOneBack = this.Sbits.slice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditional impulse Q bus section
|
||||
*/
|
||||
runQbusProcessingConditional() {
|
||||
const cnt = [-1, -1, -1, -1, -1];
|
||||
const numrows = this.qbusswitches.condition.length;
|
||||
|
||||
for (let r=0;r<numrows;r++) {
|
||||
const row = this.qbusswitches.condition[r];
|
||||
if (row.Counter !== "") {
|
||||
let result = true;
|
||||
const cPnt = row.Counter-1;
|
||||
const Qswitch = this.readBusSwitches(row.Qswitches);
|
||||
// Match switches to bit pattern
|
||||
for (let s=0;s<5;s++) {
|
||||
if (Qswitch[s] >= 0 && Qswitch[s] !== parseInt(this.Qbits[s], 10)) result = false;
|
||||
}
|
||||
// Check for NOT switch
|
||||
if (row.Negate) result = !result;
|
||||
|
||||
// AND each row to get final result
|
||||
if (cnt[cPnt] === -1) {
|
||||
cnt[cPnt] = result;
|
||||
} else if (!result) {
|
||||
cnt[cPnt] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Negate the whole column, this allows A OR B by doing NOT(NOT A AND NOT B)
|
||||
for (let c=0;c<5;c++) {
|
||||
if (this.qbusswitches.condNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Addition of impulses Q bus section
|
||||
*/
|
||||
runQbusProcessingAddition(cnt) {
|
||||
const row = this.qbusswitches.addition[0];
|
||||
const Qswitch = row.Qswitches.slice();
|
||||
|
||||
// To save making the arguments of this operation any larger, limiting addition counter to first one only
|
||||
// Colossus could actually add into any of the five counters.
|
||||
if (row.C1) {
|
||||
let addition = 0;
|
||||
for (let s=0;s<5;s++) {
|
||||
// XOR addition
|
||||
if (Qswitch[s]) {
|
||||
addition = addition ^ this.Qbits[s];
|
||||
}
|
||||
}
|
||||
const equals = (row.Equals===""?-1:(row.Equals==="."?0:1));
|
||||
if (addition === equals) {
|
||||
// AND with conditional rows to get final result
|
||||
if (cnt[0] === -1) cnt[0] = true;
|
||||
} else {
|
||||
cnt[0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Final check, check for addition section negate
|
||||
// then, if any column set, from top to bottom of rack, add to counter.
|
||||
for (let c=0;c<5;c++) {
|
||||
if (this.qbusswitches.addNegateAll && cnt[c] !== -1) cnt[c] = !cnt[c];
|
||||
|
||||
if (this.qbusswitches.totalMotor === "" || (this.qbusswitches.totalMotor === "x" && this.totalmotor === 0) || (this.qbusswitches.totalMotor === "." && this.totalmotor === 1)) {
|
||||
if (cnt[c] === true) this.allCounters[c]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise thyratron rings
|
||||
* These hold the pattern of 1s & 0s for each rotor on banks of thyraton GT1C valves which act as a one-bit store.
|
||||
*/
|
||||
initThyratrons(pattern) {
|
||||
this.rings = {
|
||||
X: {
|
||||
1: INIT_PATTERNS[pattern].X[1].slice().reverse(),
|
||||
2: INIT_PATTERNS[pattern].X[2].slice().reverse(),
|
||||
3: INIT_PATTERNS[pattern].X[3].slice().reverse(),
|
||||
4: INIT_PATTERNS[pattern].X[4].slice().reverse(),
|
||||
5: INIT_PATTERNS[pattern].X[5].slice().reverse()
|
||||
},
|
||||
M: {
|
||||
1: INIT_PATTERNS[pattern].M[1].slice().reverse(),
|
||||
2: INIT_PATTERNS[pattern].M[2].slice().reverse(),
|
||||
},
|
||||
S: {
|
||||
1: INIT_PATTERNS[pattern].S[1].slice().reverse(),
|
||||
2: INIT_PATTERNS[pattern].S[2].slice().reverse(),
|
||||
3: INIT_PATTERNS[pattern].S[3].slice().reverse(),
|
||||
4: INIT_PATTERNS[pattern].S[4].slice().reverse(),
|
||||
5: INIT_PATTERNS[pattern].S[5].slice().reverse()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Read argument bus switches X & . and convert to 1 & 0
|
||||
*/
|
||||
readBusSwitches(row) {
|
||||
const output = [-1, -1, -1, -1, -1];
|
||||
for (let c=0;c<5;c++) {
|
||||
if (row[c]===".") output[c] = 0;
|
||||
if (row[c]==="x") output[c] = 1;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
@ -468,6 +468,34 @@ export const FILE_SIGNATURES = {
|
||||
],
|
||||
extractor: null
|
||||
},
|
||||
{
|
||||
name: "Targa Image",
|
||||
extension: "tga",
|
||||
mime: "image/x-targa",
|
||||
description: "",
|
||||
signature: [
|
||||
{ // This signature is not at the beginning of the file. The extractor works backwards.
|
||||
0: 0x54,
|
||||
1: 0x52,
|
||||
2: 0x55,
|
||||
3: 0x45,
|
||||
4: 0x56,
|
||||
5: 0x49,
|
||||
6: 0x53,
|
||||
7: 0x49,
|
||||
8: 0x4f,
|
||||
9: 0x4e,
|
||||
10: 0x2d,
|
||||
11: 0x58,
|
||||
12: 0x46,
|
||||
13: 0x49,
|
||||
14: 0x4c,
|
||||
15: 0x45,
|
||||
16: 0x2e
|
||||
}
|
||||
],
|
||||
extractor: extractTARGA
|
||||
}
|
||||
],
|
||||
"Video": [
|
||||
{ // Place before webm
|
||||
@ -780,7 +808,7 @@ export const FILE_SIGNATURES = {
|
||||
1: 0xfb
|
||||
}
|
||||
],
|
||||
extractor: null
|
||||
extractor: extractMP3
|
||||
},
|
||||
{
|
||||
name: "MPEG-4 Part 14 audio",
|
||||
@ -1724,6 +1752,25 @@ export const FILE_SIGNATURES = {
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
{
|
||||
name: "Jar Archive",
|
||||
extension: "jar",
|
||||
mime: "application/java-archive",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x50,
|
||||
1: 0x4B,
|
||||
2: 0x03,
|
||||
3: 0x04,
|
||||
4: 0x14,
|
||||
5: 0x00,
|
||||
6: 0x08,
|
||||
7: 0x00,
|
||||
8: 0x08,
|
||||
9: 0x00
|
||||
},
|
||||
extractor: extractZIP
|
||||
},
|
||||
{
|
||||
name: "lzop compressed",
|
||||
extension: "lzop,lzo",
|
||||
@ -1739,8 +1786,40 @@ export const FILE_SIGNATURES = {
|
||||
6: 0x0a,
|
||||
7: 0x1a
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractLZOP
|
||||
},
|
||||
{
|
||||
name: "Linux deb package",
|
||||
extension: "deb",
|
||||
mime: "application/vnd.debian.binary-package",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x21,
|
||||
1: 0x3C,
|
||||
2: 0x61,
|
||||
3: 0x72,
|
||||
4: 0x63,
|
||||
5: 0x68,
|
||||
6: 0x3e
|
||||
},
|
||||
extractor: extractDEB
|
||||
},
|
||||
{
|
||||
name: "Apple Disk Image",
|
||||
extension: "dmg",
|
||||
mime: "application/x-apple-diskimage",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x78,
|
||||
1: 0x01,
|
||||
2: 0x73,
|
||||
3: 0x0d,
|
||||
4: 0x62,
|
||||
5: 0x62,
|
||||
6: 0x60
|
||||
},
|
||||
extractor: null
|
||||
}
|
||||
],
|
||||
"Miscellaneous": [
|
||||
{
|
||||
@ -2038,7 +2117,7 @@ export const FILE_SIGNATURES = {
|
||||
6: [0x4d, 0x36],
|
||||
7: [0x50, 0x34]
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractDMP
|
||||
},
|
||||
{
|
||||
name: "Windows Prefetch",
|
||||
@ -2055,7 +2134,7 @@ export const FILE_SIGNATURES = {
|
||||
6: 0x43,
|
||||
7: 0x41
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractPF
|
||||
},
|
||||
{
|
||||
name: "Windows Prefetch (Win 10)",
|
||||
@ -2069,7 +2148,7 @@ export const FILE_SIGNATURES = {
|
||||
3: 0x04,
|
||||
7: 0x0
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractPFWin10
|
||||
},
|
||||
{
|
||||
name: "PList (XML)",
|
||||
@ -2342,7 +2421,7 @@ export const FILE_SIGNATURES = {
|
||||
18: 0x00,
|
||||
19: 0x46
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractLNK
|
||||
},
|
||||
{
|
||||
name: "Bash",
|
||||
@ -2470,6 +2549,44 @@ export const FILE_SIGNATURES = {
|
||||
4: 0x70,
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
{
|
||||
name: "Smile",
|
||||
extension: "sml",
|
||||
mime: " application/x-jackson-smile",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x3a,
|
||||
1: 0x29,
|
||||
2: 0xa
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
{
|
||||
name: "Lua Bytecode",
|
||||
extension: "luac",
|
||||
mime: "application/x-lua",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x1b,
|
||||
1: 0x4c,
|
||||
2: 0x75,
|
||||
3: 0x61
|
||||
},
|
||||
extractor: null
|
||||
},
|
||||
{
|
||||
name: "WebAssembly binary",
|
||||
extension: "wasm",
|
||||
mime: "application/octet-stream",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x00,
|
||||
1: 0x61,
|
||||
2: 0x73,
|
||||
3: 0x6d
|
||||
},
|
||||
extractor: null
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -2958,6 +3075,90 @@ export function extractICO(bytes, offset) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TARGA extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {number} offset
|
||||
*/
|
||||
export function extractTARGA(bytes, offset) {
|
||||
// Need all the bytes since we do not know how far up the image goes.
|
||||
const stream = new Stream(bytes);
|
||||
stream.moveTo(offset - 8);
|
||||
|
||||
// Read in the offsets of the possible areas.
|
||||
const extensionOffset = stream.readInt(4, "le");
|
||||
const developerOffset = stream.readInt(4, "le");
|
||||
|
||||
stream.moveBackwardsBy(8);
|
||||
|
||||
/**
|
||||
* Moves backwards in the stream until it meet bytes that are the same as the amount of bytes moved.
|
||||
*
|
||||
* @param {number} sizeOfSize
|
||||
* @param {number} maxSize
|
||||
*/
|
||||
function moveBackwardsUntilSize(maxSize, sizeOfSize) {
|
||||
for (let i = 0; i < maxSize; i++) {
|
||||
stream.moveBackwardsBy(1);
|
||||
|
||||
// Read in sizeOfSize amount of bytes in.
|
||||
const size = stream.readInt(sizeOfSize, "le") - 1;
|
||||
stream.moveBackwardsBy(sizeOfSize);
|
||||
|
||||
// If the size matches.
|
||||
if (size === i)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves backwards in the stream until we meet bytes(when calculated) that are the same as the amount of bytes moved.
|
||||
*/
|
||||
function moveBackwardsUntilImageSize() {
|
||||
stream.moveBackwardsBy(5);
|
||||
|
||||
// The documentation said that 0x100000 was the largest the file could be.
|
||||
for (let i = 0; i < 0x100000; i++) {
|
||||
|
||||
// (Height * Width * pixel depth in bits)/8
|
||||
const total = (stream.readInt(2, "le") * stream.readInt(2, "le") * stream.readInt(1))/8;
|
||||
if (total === i-1)
|
||||
break;
|
||||
|
||||
stream.moveBackwardsBy(6);
|
||||
}
|
||||
}
|
||||
|
||||
if (extensionOffset || developerOffset) {
|
||||
if (extensionOffset) {
|
||||
// Size is stored in two bytes hence the maximum is 0xffff.
|
||||
moveBackwardsUntilSize(0xffff, 2);
|
||||
|
||||
// Move to where we think the start of the file is.
|
||||
stream.moveBackwardsBy(extensionOffset);
|
||||
} else if (developerOffset) {
|
||||
// Size is stored in 4 bytes hence the maxiumum is 0xffffffff.
|
||||
moveBackwardsUntilSize(0xffffffff, 4);
|
||||
|
||||
// Size is stored in byte position 6 so have to move back.
|
||||
stream.moveBackwardsBy(6);
|
||||
|
||||
// Move to where we think the start of the file is.
|
||||
stream.moveBackwardsBy(developerOffset);
|
||||
}
|
||||
} else {
|
||||
// Move backwards until size === number of bytes passed.
|
||||
moveBackwardsUntilImageSize();
|
||||
|
||||
// Move backwards over the reaminder of the header + the 5 we borrowed in moveBackwardsUntilImageSize().
|
||||
stream.moveBackwardsBy(0xc+5);
|
||||
}
|
||||
|
||||
return stream.carve(stream.position, offset+0x12);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WAV extractor.
|
||||
*
|
||||
@ -2972,12 +3173,85 @@ export function extractWAV(bytes, offset) {
|
||||
stream.moveTo(4);
|
||||
|
||||
// Move to file size.
|
||||
stream.moveTo(stream.readInt(4, "le"));
|
||||
stream.moveTo(stream.readInt(4, "le") + 8);
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MP3 extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractMP3(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Constants for flag byte.
|
||||
const bitRateIndexes = ["free", 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, "bad"];
|
||||
|
||||
const samplingRateFrequencyIndex = [44100, 48000, 32000, "reserved"];
|
||||
|
||||
// ID3 tag, move over it.
|
||||
if ((stream.getBytes(3).toString() === [0x49, 0x44, 0x33].toString())) {
|
||||
stream.moveTo(6);
|
||||
const tagSize = (stream.readInt(1) << 21) | (stream.readInt(1) << 14) | (stream.readInt(1) << 7) | stream.readInt(1);
|
||||
stream.moveForwardsBy(tagSize);
|
||||
} else {
|
||||
stream.moveTo(0);
|
||||
}
|
||||
|
||||
// Loop over all the frame headers in the file.
|
||||
while (stream.hasMore()) {
|
||||
|
||||
// If it has an old TAG frame at the end of it, fixed size, 128 bytes.
|
||||
if (stream.getBytes(3) === [0x54, 0x41, 0x47].toString()) {
|
||||
stream.moveForwardsBy(125);
|
||||
break;
|
||||
}
|
||||
|
||||
// If not start of frame.
|
||||
if (stream.getBytes(2).toString() !== [0xff, 0xfb].toString()) {
|
||||
stream.moveBackwardsBy(2);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read flag byte.
|
||||
const flags = stream.readInt(1);
|
||||
|
||||
// Extract frame bit rate from flag byte.
|
||||
const bitRate = bitRateIndexes[flags >> 4];
|
||||
|
||||
// Extract frame sample rate from flag byte.
|
||||
const sampleRate = samplingRateFrequencyIndex[(flags & 0x0f) >> 2];
|
||||
|
||||
// Padding if the frame size is not a multiple of the bitrate.
|
||||
const padding = (flags & 0x02) >> 1;
|
||||
|
||||
// Things that are either not standard or undocumented.
|
||||
if (bitRate === "free" || bitRate === "bad" || sampleRate === "reserved") {
|
||||
stream.moveBackwardsBy(1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Formula: FrameLength = (144 * BitRate / SampleRate ) + Padding
|
||||
const frameSize = Math.floor(((144 * bitRate) / sampleRate) + padding);
|
||||
|
||||
// If the next move goes past the end of the bytestream then extract the entire bytestream.
|
||||
// We assume complete frames in the above formula because there is no field that suggests otherwise.
|
||||
if ((stream.position + frameSize) > stream.length) {
|
||||
stream.moveTo(stream.length);
|
||||
break;
|
||||
} else {
|
||||
stream.moveForwardsBy(frameSize - 3);
|
||||
}
|
||||
}
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FLV extractor.
|
||||
*
|
||||
@ -3378,6 +3652,37 @@ export function extractXZ(bytes, offset) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DEB extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
*/
|
||||
export function extractDEB(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move past !<arch>
|
||||
stream.moveForwardsBy(8);
|
||||
while (stream.hasMore()) {
|
||||
|
||||
// Move to size field.
|
||||
stream.moveForwardsBy(48);
|
||||
let fsize= "";
|
||||
|
||||
// Convert size to a usable number.
|
||||
for (const elem of stream.getBytes(10)) {
|
||||
fsize += String.fromCharCode(elem);
|
||||
}
|
||||
fsize = parseInt(fsize.trim(), 10);
|
||||
|
||||
// Move past `\n
|
||||
stream.moveForwardsBy(2);
|
||||
stream.moveForwardsBy(fsize);
|
||||
}
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ELF extractor.
|
||||
*
|
||||
@ -3679,3 +3984,158 @@ export function extractEVT(bytes, offset) {
|
||||
stream.moveForwardsBy(eofSize-4);
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DMP extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractDMP(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to fileSize field.
|
||||
stream.moveTo(0x70);
|
||||
|
||||
// Multiply number of pages by page size. Plus 1 since the header is a page.
|
||||
stream.moveTo((stream.readInt(4, "le") + 1) * 0x1000);
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PF extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractPF(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to file size.
|
||||
stream.moveTo(12);
|
||||
stream.moveTo(stream.readInt(4, "be"));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PF (Win 10) extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractPFWin10(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Read in file size.
|
||||
stream.moveTo(stream.readInt(4, "be"));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LNK extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractLNK(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to file size field.
|
||||
stream.moveTo(0x34);
|
||||
stream.moveTo(stream.readInt(4, "le"));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LZOP extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {Number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractLZOP(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Flag bits.
|
||||
const F_ADLER32_D = 0x00000001;
|
||||
const F_ADLER32_C = 0x00000002;
|
||||
const F_CRC32_D = 0x00000100;
|
||||
const F_CRC32_C = 0x00000200;
|
||||
const F_H_FILTER = 0x00000800;
|
||||
const F_H_EXTRA_FIELD = 0x00000040;
|
||||
|
||||
let numCheckSumC = 0, numCheckSumD = 0;
|
||||
|
||||
// Move over magic bytes.
|
||||
stream.moveForwardsBy(9);
|
||||
|
||||
const version = stream.readInt(2, "be");
|
||||
|
||||
// Move to flag register offset.
|
||||
stream.moveForwardsBy(6);
|
||||
const flags = stream.readInt(4, "be");
|
||||
|
||||
if (version & F_H_FILTER)
|
||||
stream.moveForwardsBy(4);
|
||||
|
||||
if (flags & F_ADLER32_C)
|
||||
numCheckSumC++;
|
||||
|
||||
if (flags & F_CRC32_C)
|
||||
numCheckSumC++;
|
||||
|
||||
if (flags & F_ADLER32_D)
|
||||
numCheckSumD++;
|
||||
|
||||
if (flags & F_CRC32_D)
|
||||
numCheckSumD++;
|
||||
|
||||
// Move over the mode, mtime_low
|
||||
stream.moveForwardsBy(8);
|
||||
|
||||
if (version >= 0x0940)
|
||||
stream.moveForwardsBy(4);
|
||||
|
||||
const fnameSize = stream.readInt(1, "be");
|
||||
|
||||
// Move forwards by size of file name and the following 4 byte checksum.
|
||||
stream.moveForwardsBy(fnameSize);
|
||||
|
||||
if (flags & F_H_EXTRA_FIELD) {
|
||||
const extraSize = stream.readInt(4, "be");
|
||||
stream.moveForwardsBy(extraSize);
|
||||
}
|
||||
|
||||
// Move past checksum.
|
||||
stream.moveForwardsBy(4);
|
||||
|
||||
while (stream.hasMore()) {
|
||||
const uncompSize = stream.readInt(4, "be");
|
||||
|
||||
// If data has no length, break.
|
||||
if (uncompSize === 0)
|
||||
break;
|
||||
|
||||
const compSize = stream.readInt(4, "be");
|
||||
|
||||
const numCheckSumSkip = (uncompSize === compSize) ? numCheckSumD : numCheckSumD + numCheckSumC;
|
||||
|
||||
// skip forwards by compressed data size and the size of the checksum(s).
|
||||
stream.moveForwardsBy(compSize + (numCheckSumSkip * 4));
|
||||
}
|
||||
return stream.carve();
|
||||
|
||||
}
|
||||
|
@ -23,25 +23,39 @@ import Utils from "../Utils.mjs";
|
||||
*
|
||||
* // returns "0a:14:1e"
|
||||
* toHex([10,20,30], ":");
|
||||
*
|
||||
* // returns "0x0a,0x14,0x1e"
|
||||
* toHex([10,20,30], "0x", 2, ",")
|
||||
*/
|
||||
export function toHex(data, delim=" ", padding=2) {
|
||||
export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
|
||||
let output = "";
|
||||
const prepend = (delim === "0x" || delim === "\\x");
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += data[i].toString(16).padStart(padding, "0") + delim;
|
||||
const hex = data[i].toString(16).padStart(padding, "0");
|
||||
output += prepend ? delim + hex : hex + delim;
|
||||
|
||||
if (extraDelim) {
|
||||
output += extraDelim;
|
||||
}
|
||||
// Add LF after each lineSize amount of bytes but not at the end
|
||||
if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) {
|
||||
output += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Add \x or 0x to beginning
|
||||
if (delim === "0x") output = "0x" + output;
|
||||
if (delim === "\\x") output = "\\x" + output;
|
||||
|
||||
if (delim.length)
|
||||
return output.slice(0, -delim.length);
|
||||
else
|
||||
// Remove the extraDelim at the end (if there is one)
|
||||
// and remove the delim at the end, but if it's prepended there's nothing to remove
|
||||
const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length);
|
||||
if (rTruncLen) {
|
||||
// If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing
|
||||
return output.slice(0, -rTruncLen);
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +101,7 @@ export function toHexFast(data) {
|
||||
*/
|
||||
export function fromHex(data, delim="Auto", byteLen=2) {
|
||||
if (delim !== "None") {
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep(delim);
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim);
|
||||
data = data.replace(delimRegex, "");
|
||||
}
|
||||
|
||||
@ -102,7 +116,7 @@ export function fromHex(data, delim="Auto", byteLen=2) {
|
||||
/**
|
||||
* To Hexadecimal delimiters.
|
||||
*/
|
||||
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"];
|
||||
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"];
|
||||
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,7 @@ export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allo
|
||||
let output = "";
|
||||
|
||||
if (cidrRange < 0 || cidrRange > 31) {
|
||||
return "IPv4 CIDR must be less than 32";
|
||||
throw new OperationError("IPv4 CIDR must be less than 32");
|
||||
}
|
||||
|
||||
const mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
@ -64,7 +64,7 @@ export function ipv6CidrRange(cidr, includeNetworkInfo) {
|
||||
cidrRange = parseInt(cidr[cidr.length-1], 10);
|
||||
|
||||
if (cidrRange < 0 || cidrRange > 127) {
|
||||
return "IPv6 CIDR must be less than 128";
|
||||
throw new OperationError("IPv6 CIDR must be less than 128");
|
||||
}
|
||||
|
||||
const ip1 = new Array(8),
|
||||
@ -211,7 +211,7 @@ export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, a
|
||||
const network = strToIpv4(ipv4CidrList[i].split("/")[0]);
|
||||
const cidrRange = parseInt(ipv4CidrList[i].split("/")[1], 10);
|
||||
if (cidrRange < 0 || cidrRange > 31) {
|
||||
return "IPv4 CIDR must be less than 32";
|
||||
throw new OperationError("IPv4 CIDR must be less than 32");
|
||||
}
|
||||
const mask = ~(0xFFFFFFFF >>> cidrRange),
|
||||
cidrIp1 = network & mask,
|
||||
@ -254,7 +254,7 @@ export function ipv6ListedRange(match, includeNetworkInfo) {
|
||||
const cidrRange = parseInt(ipv6CidrList[i].split("/")[1], 10);
|
||||
|
||||
if (cidrRange < 0 || cidrRange > 127) {
|
||||
return "IPv6 CIDR must be less than 128";
|
||||
throw new OperationError("IPv6 CIDR must be less than 128");
|
||||
}
|
||||
|
||||
const cidrIp1 = new Array(8),
|
||||
|
156
src/core/lib/Lorenz.mjs
Normal file
@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Resources required by the Lorenz SZ40/42 and Colossus
|
||||
*
|
||||
* @author VirtualColossus [martin@virtualcolossus.co.uk]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
export const SWITCHES = [
|
||||
{name: "Up (.)", value: "."},
|
||||
{name: "Centre", value: ""},
|
||||
{name: "Down (x)", value: "x"}
|
||||
];
|
||||
|
||||
export const VALID_ITA2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ34589+-./";
|
||||
|
||||
export const ITA2_TABLE = {
|
||||
"A": "11000",
|
||||
"B": "10011",
|
||||
"C": "01110",
|
||||
"D": "10010",
|
||||
"E": "10000",
|
||||
"F": "10110",
|
||||
"G": "01011",
|
||||
"H": "00101",
|
||||
"I": "01100",
|
||||
"J": "11010",
|
||||
"K": "11110",
|
||||
"L": "01001",
|
||||
"M": "00111",
|
||||
"N": "00110",
|
||||
"O": "00011",
|
||||
"P": "01101",
|
||||
"Q": "11101",
|
||||
"R": "01010",
|
||||
"S": "10100",
|
||||
"T": "00001",
|
||||
"U": "11100",
|
||||
"V": "01111",
|
||||
"W": "11001",
|
||||
"X": "10111",
|
||||
"Y": "10101",
|
||||
"Z": "10001",
|
||||
"3": "00010",
|
||||
"4": "01000",
|
||||
"9": "00100",
|
||||
"/": "00000",
|
||||
" ": "00100",
|
||||
".": "00100",
|
||||
"8": "11111",
|
||||
"5": "11011",
|
||||
"-": "11111",
|
||||
"+": "11011"
|
||||
};
|
||||
|
||||
export const ROTOR_SIZES = {
|
||||
S1: 43,
|
||||
S2: 47,
|
||||
S3: 51,
|
||||
S4: 53,
|
||||
S5: 59,
|
||||
M37: 37,
|
||||
M61: 61,
|
||||
X1: 41,
|
||||
X2: 31,
|
||||
X3: 29,
|
||||
X4: 26,
|
||||
X5: 23
|
||||
};
|
||||
|
||||
/**
|
||||
* Initial rotor patterns
|
||||
*/
|
||||
export const INIT_PATTERNS = {
|
||||
"No Pattern": {
|
||||
"X": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
4: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
},
|
||||
"M": {
|
||||
1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
2: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
}
|
||||
|
||||
},
|
||||
"KH Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0],
|
||||
2: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0],
|
||||
3: [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0],
|
||||
4: [1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0],
|
||||
5: [1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1],
|
||||
2: [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1],
|
||||
3: [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1],
|
||||
4: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
|
||||
5: [1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0]
|
||||
},
|
||||
"M": {
|
||||
1: [0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||
2: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0]
|
||||
}
|
||||
},
|
||||
"ZMUG Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0],
|
||||
2: [1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0],
|
||||
3: [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0],
|
||||
4: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
|
||||
5: [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1]
|
||||
},
|
||||
"S": {
|
||||
1: [1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0],
|
||||
2: [0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
|
||||
3: [0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
|
||||
4: [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1],
|
||||
5: [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0]
|
||||
},
|
||||
"M": {
|
||||
1: [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
|
||||
2: [0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1]
|
||||
}
|
||||
},
|
||||
"BREAM Pattern": {
|
||||
"X": {
|
||||
1: [0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
|
||||
2: [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1],
|
||||
3: [1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
||||
4: [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0],
|
||||
5: [0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0]
|
||||
},
|
||||
"S": {
|
||||
1: [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0],
|
||||
2: [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0],
|
||||
3: [1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
|
||||
4: [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1],
|
||||
5: [1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
|
||||
},
|
||||
"M": {
|
||||
1: [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1],
|
||||
2: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1]
|
||||
}
|
||||
}
|
||||
};
|
@ -2,7 +2,7 @@ import OperationConfig from "../config/OperationConfig.json";
|
||||
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
|
||||
import Recipe from "../Recipe.mjs";
|
||||
import Dish from "../Dish.mjs";
|
||||
import {detectFileType} from "./FileType.mjs";
|
||||
import {detectFileType, isType} from "./FileType.mjs";
|
||||
import chiSquared from "chi-squared";
|
||||
|
||||
/**
|
||||
@ -19,31 +19,38 @@ class Magic {
|
||||
* Magic constructor.
|
||||
*
|
||||
* @param {ArrayBuffer} buf
|
||||
* @param {Object[]} [opPatterns]
|
||||
* @param {Object[]} [opCriteria]
|
||||
* @param {Object} [prevOp]
|
||||
*/
|
||||
constructor(buf, opPatterns) {
|
||||
constructor(buf, opCriteria=Magic._generateOpCriteria(), prevOp=null) {
|
||||
this.inputBuffer = new Uint8Array(buf);
|
||||
this.inputStr = Utils.arrayBufferToStr(buf);
|
||||
this.opPatterns = opPatterns || Magic._generateOpPatterns();
|
||||
this.opCriteria = opCriteria;
|
||||
this.prevOp = prevOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds operations that claim to be able to decode the input based on regular
|
||||
* expression matches.
|
||||
* Finds operations that claim to be able to decode the input based on various criteria.
|
||||
*
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
findMatchingOps() {
|
||||
const matches = [];
|
||||
findMatchingInputOps() {
|
||||
const matches = [],
|
||||
inputEntropy = this.calcEntropy();
|
||||
|
||||
for (let i = 0; i < this.opPatterns.length; i++) {
|
||||
const pattern = this.opPatterns[i],
|
||||
regex = new RegExp(pattern.match, pattern.flags);
|
||||
this.opCriteria.forEach(check => {
|
||||
// If the input doesn't lie in the required entropy range, move on
|
||||
if (check.entropyRange &&
|
||||
(inputEntropy < check.entropyRange[0] ||
|
||||
inputEntropy > check.entropyRange[1]))
|
||||
return;
|
||||
// If the input doesn't match the pattern, move on
|
||||
if (check.pattern &&
|
||||
!check.pattern.test(this.inputStr))
|
||||
return;
|
||||
|
||||
if (regex.test(this.inputStr)) {
|
||||
matches.push(pattern);
|
||||
}
|
||||
}
|
||||
matches.push(check);
|
||||
});
|
||||
|
||||
return matches;
|
||||
}
|
||||
@ -185,8 +192,10 @@ class Magic {
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
calcEntropy() {
|
||||
const prob = this._freqDist();
|
||||
calcEntropy(data=this.inputBuffer, standalone=false) {
|
||||
if (!standalone && this.inputEntropy) return this.inputEntropy;
|
||||
|
||||
const prob = this._freqDist(data, standalone);
|
||||
let entropy = 0,
|
||||
p;
|
||||
|
||||
@ -195,6 +204,8 @@ class Magic {
|
||||
if (p === 0) continue;
|
||||
entropy += p * Math.log(p) / Math.log(2);
|
||||
}
|
||||
|
||||
if (!standalone) this.inputEntropy = -entropy;
|
||||
return -entropy;
|
||||
}
|
||||
|
||||
@ -264,25 +275,59 @@ class Magic {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the data passes output criteria for an operation check
|
||||
*
|
||||
* @param {ArrayBuffer} data
|
||||
* @param {Object} criteria
|
||||
* @returns {boolean}
|
||||
*/
|
||||
outputCheckPasses(data, criteria) {
|
||||
if (criteria.pattern) {
|
||||
const dataStr = Utils.arrayBufferToStr(data),
|
||||
regex = new RegExp(criteria.pattern, criteria.flags);
|
||||
if (!regex.test(dataStr))
|
||||
return false;
|
||||
}
|
||||
if (criteria.entropyRange) {
|
||||
const dataEntropy = this.calcEntropy(data, true);
|
||||
if (dataEntropy < criteria.entropyRange[0] || dataEntropy > criteria.entropyRange[1])
|
||||
return false;
|
||||
}
|
||||
if (criteria.mime &&
|
||||
!isType(criteria.mime, data))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Speculatively executes matching operations, recording metadata of each result.
|
||||
*
|
||||
* @param {number} [depth=0] - How many levels to try to execute
|
||||
* @param {boolean} [extLang=false] - Extensive language support (false = only check the most
|
||||
* common Internet languages)
|
||||
* common Internet languages)
|
||||
* @param {boolean} [intensive=false] - Run brute-forcing on each branch (significantly affects
|
||||
* performance)
|
||||
* performance)
|
||||
* @param {Object[]} [recipeConfig=[]] - The recipe configuration up to this point
|
||||
* @param {boolean} [useful=false] - Whether the current recipe should be scored highly
|
||||
* @param {string} [crib=null] - The regex crib provided by the user, for filtering the operation output
|
||||
* @param {string} [crib=null] - The regex crib provided by the user, for filtering the operation
|
||||
* output
|
||||
* @returns {Object[]} - A sorted list of the recipes most likely to result in correct decoding
|
||||
*/
|
||||
async speculativeExecution(depth=0, extLang=false, intensive=false, recipeConfig=[], useful=false, crib=null) {
|
||||
async speculativeExecution(
|
||||
depth=0,
|
||||
extLang=false,
|
||||
intensive=false,
|
||||
recipeConfig=[],
|
||||
useful=false,
|
||||
crib=null) {
|
||||
|
||||
// If we have reached the recursion depth, return
|
||||
if (depth < 0) return [];
|
||||
|
||||
// Find any operations that can be run on this data
|
||||
const matchingOps = this.findMatchingOps();
|
||||
|
||||
const matchingOps = this.findMatchingInputOps();
|
||||
let results = [];
|
||||
|
||||
// Record the properties of the current data
|
||||
@ -308,17 +353,21 @@ class Magic {
|
||||
},
|
||||
output = await this._runRecipe([opConfig]);
|
||||
|
||||
// If the recipe is repeating and returning the same data, do not continue
|
||||
if (prevOp && op.op === prevOp.op && _buffersEqual(output, this.inputBuffer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the recipe returned an empty buffer, do not continue
|
||||
if (_buffersEqual(output, new ArrayBuffer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const magic = new Magic(output, this.opPatterns),
|
||||
// If the recipe is repeating and returning the same data, do not continue
|
||||
if (prevOp && op.op === prevOp.op && _buffersEqual(output, this.inputBuffer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the output criteria for this op doesn't match the output, do not continue
|
||||
if (op.output && !this.outputCheckPasses(output, op.output))
|
||||
return;
|
||||
|
||||
const magic = new Magic(output, this.opCriteria, OperationConfig[op.op]),
|
||||
speculativeResults = await magic.speculativeExecution(
|
||||
depth-1, extLang, intensive, [...recipeConfig, opConfig], op.useful, crib);
|
||||
|
||||
@ -330,7 +379,7 @@ class Magic {
|
||||
const bfEncodings = await this.bruteForce();
|
||||
|
||||
await Promise.all(bfEncodings.map(async enc => {
|
||||
const magic = new Magic(enc.data, this.opPatterns),
|
||||
const magic = new Magic(enc.data, this.opCriteria, undefined),
|
||||
bfResults = await magic.speculativeExecution(
|
||||
depth-1, extLang, false, [...recipeConfig, enc.conf], false, crib);
|
||||
|
||||
@ -345,7 +394,8 @@ class Magic {
|
||||
r.languageScores[0].probability > 0 || // Some kind of language was found
|
||||
r.fileType || // A file was found
|
||||
r.isUTF8 || // UTF-8 was found
|
||||
r.matchingOps.length // A matching op was found
|
||||
r.matchingOps.length || // A matching op was found
|
||||
r.matchesCrib // The crib matches
|
||||
)
|
||||
);
|
||||
|
||||
@ -376,9 +426,10 @@ class Magic {
|
||||
bScore += b.entropy;
|
||||
|
||||
// A result with no recipe but matching ops suggests there are better options
|
||||
if ((!a.recipe.length && a.matchingOps.length) &&
|
||||
b.recipe.length)
|
||||
if ((!a.recipe.length && a.matchingOps.length) && b.recipe.length)
|
||||
return 1;
|
||||
if ((!b.recipe.length && b.matchingOps.length) && a.recipe.length)
|
||||
return -1;
|
||||
|
||||
return aScore - bScore;
|
||||
});
|
||||
@ -417,14 +468,16 @@ class Magic {
|
||||
* Calculates the number of times each byte appears in the input as a percentage
|
||||
*
|
||||
* @private
|
||||
* @param {ArrayBuffer} [data]
|
||||
* @param {boolean} [standalone]
|
||||
* @returns {number[]}
|
||||
*/
|
||||
_freqDist() {
|
||||
if (this.freqDist) return this.freqDist;
|
||||
_freqDist(data=this.inputBuffer, standalone=false) {
|
||||
if (!standalone && this.freqDist) return this.freqDist;
|
||||
|
||||
const len = this.inputBuffer.length;
|
||||
const len = data.length,
|
||||
counts = new Array(256).fill(0);
|
||||
let i = len;
|
||||
const counts = new Array(256).fill(0);
|
||||
|
||||
if (!len) {
|
||||
this.freqDist = counts;
|
||||
@ -432,13 +485,15 @@ class Magic {
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
counts[this.inputBuffer[i]]++;
|
||||
counts[data[i]]++;
|
||||
}
|
||||
|
||||
this.freqDist = counts.map(c => {
|
||||
const result = counts.map(c => {
|
||||
return c / len * 100;
|
||||
});
|
||||
return this.freqDist;
|
||||
|
||||
if (!standalone) this.freqDist = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,24 +502,29 @@ class Magic {
|
||||
* @private
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
static _generateOpPatterns() {
|
||||
const opPatterns = [];
|
||||
static _generateOpCriteria() {
|
||||
const opCriteria = [];
|
||||
|
||||
for (const op in OperationConfig) {
|
||||
if (!("patterns" in OperationConfig[op])) continue;
|
||||
if (!("checks" in OperationConfig[op]))
|
||||
continue;
|
||||
|
||||
OperationConfig[op].patterns.forEach(pattern => {
|
||||
opPatterns.push({
|
||||
OperationConfig[op].checks.forEach(check => {
|
||||
// Add to the opCriteria list.
|
||||
// Compile the regex here and cache the compiled version so we
|
||||
// don't have to keep calculating it.
|
||||
opCriteria.push({
|
||||
op: op,
|
||||
match: pattern.match,
|
||||
flags: pattern.flags,
|
||||
args: pattern.args,
|
||||
useful: pattern.useful || false
|
||||
pattern: check.pattern ? new RegExp(check.pattern, check.flags) : null,
|
||||
args: check.args,
|
||||
useful: check.useful,
|
||||
entropyRange: check.entropyRange,
|
||||
output: check.output
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return opPatterns;
|
||||
return opCriteria;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,11 +303,13 @@ export default class Stream {
|
||||
/**
|
||||
* Returns a slice of the stream up to the current position.
|
||||
*
|
||||
* @param {number} [start=0]
|
||||
* @param {number} [finish=this.position]
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
carve() {
|
||||
if (this.bitPos > 0) this.position++;
|
||||
return this.bytes.slice(0, this.position);
|
||||
carve(start=0, finish=this.position) {
|
||||
if (this.bitPos > 0) finish++;
|
||||
return this.bytes.slice(start, finish);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,38 @@ class A1Z26CipherDecode extends Operation {
|
||||
value: DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9] )+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Space"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9],)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Comma"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9];)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]:)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Colon"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["Line feed"]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([12]?[0-9]\\r\\n)+[12]?[0-9]\\s*$",
|
||||
flags: "",
|
||||
args: ["CRLF"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,48 @@ class BaconCipherDecode extends Operation {
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*([01]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Standard (I=J and U=V)", "0/1", false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([01]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Standard (I=J and U=V)", "0/1", true]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([AB]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Standard (I=J and U=V)", "A/B", false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([AB]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Standard (I=J and U=V)", "A/B", true]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([01]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Complete", "0/1", false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([01]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Complete", "0/1", true]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([AB]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Complete", "A/B", false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*([AB]{5}\\s?)+$",
|
||||
flags: "",
|
||||
args: ["Complete", "A/B", true]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,9 +33,9 @@ class Bzip2Decompress extends Operation {
|
||||
value: false
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
"match": "^\\x42\\x5a\\x68",
|
||||
"pattern": "^\\x42\\x5a\\x68",
|
||||
"flags": "",
|
||||
"args": []
|
||||
}
|
||||
|
61
src/core/operations/CipherSaber2Decrypt.mjs
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import { encode } from "../lib/CipherSaber2.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* CipherSaber2 Decrypt operation
|
||||
*/
|
||||
class CipherSaber2Decrypt extends Operation {
|
||||
|
||||
/**
|
||||
* CipherSaber2Decrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "CipherSaber2 Decrypt";
|
||||
this.module = "Crypto";
|
||||
this.description = "CipherSaber is a simple symmetric encryption protocol based on the RC4 stream cipher. It gives reasonably strong protection of message confidentiality, yet it's designed to be simple enough that even novice programmers can memorize the algorithm and implement it from scratch.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "Rounds",
|
||||
type: "number",
|
||||
value: 20
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
run(input, args) {
|
||||
input = new Uint8Array(input);
|
||||
const result = [],
|
||||
key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||
rounds = args[1];
|
||||
|
||||
const tempIVP = input.slice(0, 10);
|
||||
input = input.slice(10);
|
||||
return new Uint8Array(result.concat(encode(tempIVP, key, rounds, input))).buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CipherSaber2Decrypt;
|
65
src/core/operations/CipherSaber2Encrypt.mjs
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import crypto from "crypto";
|
||||
import { encode } from "../lib/CipherSaber2.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* CipherSaber2 Encrypt operation
|
||||
*/
|
||||
class CipherSaber2Encrypt extends Operation {
|
||||
|
||||
/**
|
||||
* CipherSaber2Encrypt constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "CipherSaber2 Encrypt";
|
||||
this.module = "Crypto";
|
||||
this.description = "CipherSaber is a simple symmetric encryption protocol based on the RC4 stream cipher. It gives reasonably strong protection of message confidentiality, yet it's designed to be simple enough that even novice programmers can memorize the algorithm and implement it from scratch.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/CipherSaber";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "toggleString",
|
||||
value: "",
|
||||
toggleValues: ["Hex", "UTF8", "Latin1", "Base64"]
|
||||
},
|
||||
{
|
||||
name: "Rounds",
|
||||
type: "number",
|
||||
value: 20
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
run(input, args) {
|
||||
input = new Uint8Array(input);
|
||||
const result = [],
|
||||
key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||
rounds = args[1];
|
||||
|
||||
// Assign into initialisation vector based on cipher mode.
|
||||
const tempIVP = crypto.randomBytes(10);
|
||||
for (let m = 0; m < 10; m++)
|
||||
result.push(tempIVP[m]);
|
||||
|
||||
return new Uint8Array(result.concat(encode(tempIVP, key, rounds, input))).buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CipherSaber2Encrypt;
|
572
src/core/operations/Colossus.mjs
Normal file
@ -0,0 +1,572 @@
|
||||
/**
|
||||
* Emulation of Colossus.
|
||||
*
|
||||
* @author VirtualColossus [martin@virtualcolossus.co.uk]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import { ColossusComputer } from "../lib/Colossus.mjs";
|
||||
import { SWITCHES, VALID_ITA2 } from "../lib/Lorenz.mjs";
|
||||
|
||||
/**
|
||||
* Colossus operation
|
||||
*/
|
||||
class Colossus extends Operation {
|
||||
|
||||
/**
|
||||
* Colossus constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.name = "Colossus";
|
||||
this.module = "Bletchley";
|
||||
this.description = "Colossus is the name of the world's first electronic computer. Ten Colossi were designed by Tommy Flowers and built at the Post Office Research Labs at Dollis Hill in 1943 during World War 2. They assisted with the breaking of the German Lorenz cipher attachment, a machine created to encipher communications between Hitler and his generals on the front lines.<br><br>To learn more, Virtual Colossus, an online, browser based simulation of a Colossus computer is available at <a href='https://virtualcolossus.co.uk' target='_blank'>virtualcolossus.co.uk</a>.<br><br>A more detailed description of this operation can be found <a href='https://github.com/gchq/CyberChef/wiki/Colossus' target='_blank'>here</a>.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Colossus_computer";
|
||||
this.inputType = "string";
|
||||
this.outputType = "JSON";
|
||||
this.presentType = "html";
|
||||
this.args = [
|
||||
{
|
||||
name: "Input",
|
||||
type: "label"
|
||||
},
|
||||
{
|
||||
name: "Pattern",
|
||||
type: "option",
|
||||
value: ["KH Pattern", "ZMUG Pattern", "BREAM Pattern"]
|
||||
},
|
||||
{
|
||||
name: "QBusZ",
|
||||
type: "option",
|
||||
value: ["", "Z", "ΔZ"]
|
||||
},
|
||||
{
|
||||
name: "QBusΧ",
|
||||
type: "option",
|
||||
value: ["", "Χ", "ΔΧ"]
|
||||
},
|
||||
{
|
||||
name: "QBusΨ",
|
||||
type: "option",
|
||||
value: ["", "Ψ", "ΔΨ"]
|
||||
},
|
||||
{
|
||||
name: "Limitation",
|
||||
type: "option",
|
||||
value: ["None", "Χ2", "Χ2 + P5", "X2 + Ψ1", "X2 + Ψ1 + P5"]
|
||||
},
|
||||
{
|
||||
name: "K Rack Option",
|
||||
type: "argSelector",
|
||||
value: [
|
||||
{
|
||||
name: "Select Program",
|
||||
on: [7],
|
||||
off: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
|
||||
},
|
||||
{
|
||||
name: "Top Section - Conditional",
|
||||
on: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
|
||||
off: [7, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
|
||||
},
|
||||
{
|
||||
name: "Bottom Section - Addition",
|
||||
on: [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
|
||||
off: [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
|
||||
},
|
||||
{
|
||||
name: "Advanced",
|
||||
on: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
|
||||
off: [7]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Program to run",
|
||||
type: "option",
|
||||
value: ["", "Letter Count", "1+2=. (1+2 Break In, Find X1,X2)", "4=5=/1=2 (Given X1,X2 find X4,X5)", "/,5,U (Count chars to find X3)"]
|
||||
},
|
||||
{
|
||||
name: "K Rack: Conditional",
|
||||
type: "label"
|
||||
},
|
||||
{
|
||||
name: "R1-Q1",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R1-Q2",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R1-Q3",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R1-Q4",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R1-Q5",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R1-Negate",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "R1-Counter",
|
||||
type: "option",
|
||||
value: ["", "1", "2", "3", "4", "5"]
|
||||
},
|
||||
{
|
||||
name: "R2-Q1",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R2-Q2",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R2-Q3",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R2-Q4",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R2-Q5",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R2-Negate",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "R2-Counter",
|
||||
type: "option",
|
||||
value: ["", "1", "2", "3", "4", "5"]
|
||||
},
|
||||
{
|
||||
name: "R3-Q1",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R3-Q2",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R3-Q3",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R3-Q4",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R3-Q5",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "R3-Negate",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "R3-Counter",
|
||||
type: "option",
|
||||
value: ["", "1", "2", "3", "4", "5"]
|
||||
},
|
||||
{
|
||||
name: "Negate All",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "K Rack: Addition",
|
||||
type: "label"
|
||||
},
|
||||
{
|
||||
name: "Add-Q1",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add-Q2",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add-Q3",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add-Q4",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add-Q5",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add-Equals",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "Add-Counter1",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Add Negate All",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "Total Motor",
|
||||
type: "editableOptionShort",
|
||||
value: SWITCHES,
|
||||
defaultIndex: 1
|
||||
},
|
||||
{
|
||||
name: "Master Control Panel",
|
||||
type: "label"
|
||||
},
|
||||
{
|
||||
name: "Set Total",
|
||||
type: "number",
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
name: "Fast Step",
|
||||
type: "option",
|
||||
value: ["", "X1", "X2", "X3", "X4", "X5", "M37", "M61", "S1", "S2", "S3", "S4", "S5"]
|
||||
},
|
||||
{
|
||||
name: "Slow Step",
|
||||
type: "option",
|
||||
value: ["", "X1", "X2", "X3", "X4", "X5", "M37", "M61", "S1", "S2", "S3", "S4", "S5"]
|
||||
},
|
||||
{
|
||||
name: "Start Χ1",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Χ2",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Χ3",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Χ4",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Χ5",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start M61",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start M37",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Ψ1",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Ψ2",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Ψ3",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Ψ4",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Start Ψ5",
|
||||
type: "number",
|
||||
value: 1
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {Object}
|
||||
*/
|
||||
run(input, args) {
|
||||
input = input.toUpperCase();
|
||||
for (const character of input) {
|
||||
if (VALID_ITA2.indexOf(character) === -1) {
|
||||
let errltr = character;
|
||||
if (errltr === "\n") errltr = "Carriage Return";
|
||||
if (errltr === " ") errltr = "Space";
|
||||
throw new OperationError("Invalid ITA2 character : " + errltr);
|
||||
}
|
||||
}
|
||||
|
||||
const pattern = args[1];
|
||||
const qbusin = {
|
||||
"Z": args[2],
|
||||
"Chi": args[3],
|
||||
"Psi": args[4],
|
||||
};
|
||||
|
||||
const limitation = args[5];
|
||||
const lm = [false, false, false];
|
||||
if (limitation.includes("Χ2")) lm[0] = true;
|
||||
if (limitation.includes("Ψ1")) lm[1] = true;
|
||||
if (limitation.includes("P5")) lm[2] = true;
|
||||
const limit = {
|
||||
X2: lm[0], S1: lm[1], P5: lm[2]
|
||||
};
|
||||
|
||||
const KRackOpt = args[6];
|
||||
const setProgram = args[7];
|
||||
|
||||
if (KRackOpt === "Select Program" && setProgram !== "") {
|
||||
args = this.selectProgram(setProgram, args);
|
||||
}
|
||||
|
||||
const re = new RegExp("^$|^[.x]$");
|
||||
for (let qr=0;qr<3;qr++) {
|
||||
for (let a=0;a<5;a++) {
|
||||
if (!re.test(args[((qr*7)+(a+9))]))
|
||||
throw new OperationError("Switch R"+(qr+1)+"-Q"+(a+1)+" can only be set to blank, . or x");
|
||||
}
|
||||
}
|
||||
|
||||
if (!re.test(args[37])) throw new OperationError("Switch Add-Equals can only be set to blank, . or x");
|
||||
if (!re.test(args[40])) throw new OperationError("Switch Total Motor can only be set to blank, . or x");
|
||||
|
||||
// Q1,Q2,Q3,Q4,Q5,negate,counter1
|
||||
const qbusswitches = {
|
||||
condition: [
|
||||
{Qswitches: [args[9], args[10], args[11], args[12], args[13]], Negate: args[14], Counter: args[15]},
|
||||
{Qswitches: [args[16], args[17], args[18], args[19], args[20]], Negate: args[21], Counter: args[22]},
|
||||
{Qswitches: [args[23], args[24], args[25], args[26], args[27]], Negate: args[28], Counter: args[29]}
|
||||
],
|
||||
condNegateAll: args[30],
|
||||
addition: [
|
||||
{Qswitches: [args[32], args[33], args[34], args[35], args[36]], Equals: args[37], C1: args[38]}
|
||||
],
|
||||
addNegateAll: args[39],
|
||||
totalMotor: args[40]
|
||||
};
|
||||
|
||||
const settotal = parseInt(args[42], 10);
|
||||
if (settotal < 0 || settotal > 9999)
|
||||
throw new OperationError("Set Total must be between 0000 and 9999");
|
||||
|
||||
// null|fast|slow for each of S1-5,M1-2,X1-5
|
||||
const control = {
|
||||
fast: args[43],
|
||||
slow: args[44]
|
||||
};
|
||||
|
||||
// Start positions
|
||||
if (args[52]<1 || args[52]>43) throw new OperationError("Ψ1 start must be between 1 and 43");
|
||||
if (args[53]<1 || args[53]>47) throw new OperationError("Ψ2 start must be between 1 and 47");
|
||||
if (args[54]<1 || args[54]>51) throw new OperationError("Ψ3 start must be between 1 and 51");
|
||||
if (args[55]<1 || args[55]>53) throw new OperationError("Ψ4 start must be between 1 and 53");
|
||||
if (args[56]<1 || args[57]>59) throw new OperationError("Ψ5 start must be between 1 and 59");
|
||||
if (args[51]<1 || args[51]>37) throw new OperationError("Μ37 start must be between 1 and 37");
|
||||
if (args[50]<1 || args[50]>61) throw new OperationError("Μ61 start must be between 1 and 61");
|
||||
if (args[45]<1 || args[45]>41) throw new OperationError("Χ1 start must be between 1 and 41");
|
||||
if (args[46]<1 || args[46]>31) throw new OperationError("Χ2 start must be between 1 and 31");
|
||||
if (args[47]<1 || args[47]>29) throw new OperationError("Χ3 start must be between 1 and 29");
|
||||
if (args[48]<1 || args[48]>26) throw new OperationError("Χ4 start must be between 1 and 26");
|
||||
if (args[49]<1 || args[49]>23) throw new OperationError("Χ5 start must be between 1 and 23");
|
||||
|
||||
const starts = {
|
||||
X1: args[45], X2: args[46], X3: args[47], X4: args[48], X5: args[49],
|
||||
M61: args[50], M37: args[51],
|
||||
S1: args[52], S2: args[53], S3: args[54], S4: args[55], S5: args[56]
|
||||
};
|
||||
|
||||
const colossus = new ColossusComputer(input, pattern, qbusin, qbusswitches, control, starts, settotal, limit);
|
||||
const result = colossus.run();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select Program
|
||||
*
|
||||
* @param {string} progname
|
||||
* @param {Object[]} args
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
selectProgram(progname, args) {
|
||||
|
||||
// Basic Letter Count
|
||||
if (progname === "Letter Count") {
|
||||
// Set Conditional R1 : count every character into counter 1
|
||||
args[9] = "";
|
||||
args[10] = "";
|
||||
args[11] = "";
|
||||
args[12] = "";
|
||||
args[13] = "";
|
||||
args[14] = false;
|
||||
args[15] = "1";
|
||||
// clear Conditional R2 & R3
|
||||
args[22] = "";
|
||||
args[29] = "";
|
||||
// Clear Negate result
|
||||
args[30] = false;
|
||||
// Clear Addition row counter
|
||||
args[38] = false;
|
||||
}
|
||||
|
||||
// Bill Tutte's 1+2 Break In
|
||||
if (progname === "1+2=. (1+2 Break In, Find X1,X2)") {
|
||||
// Clear any other counters
|
||||
args[15] = ""; // Conditional R1
|
||||
args[22] = ""; // Conditional R2
|
||||
args[29] = ""; // Conditional R3
|
||||
// Set Add Q1+Q2=. into Counter 1
|
||||
args[32] = true;
|
||||
args[33] = true;
|
||||
args[34] = false;
|
||||
args[35] = false;
|
||||
args[36] = false;
|
||||
args[37] = ".";
|
||||
args[38] = true;
|
||||
}
|
||||
|
||||
// 4=3=/1=2 : Find X4 & X5 where X1 & X2 are known
|
||||
if (progname === "4=5=/1=2 (Given X1,X2 find X4,X5)") {
|
||||
// Set Conditional R1 : Match NOT ..?.. into counter 1
|
||||
args[9] = ".";
|
||||
args[10] = ".";
|
||||
args[11] = "";
|
||||
args[12] = ".";
|
||||
args[13] = ".";
|
||||
args[14] = true;
|
||||
args[15] = "1";
|
||||
// Set Conditional R2 : AND Match NOT xx?xx into counter 1
|
||||
args[16] = "x";
|
||||
args[17] = "x";
|
||||
args[18] = "";
|
||||
args[19] = "x";
|
||||
args[20] = "x";
|
||||
args[21] = true;
|
||||
args[22] = "1";
|
||||
// clear Conditional R3
|
||||
args[29] = "";
|
||||
// Negate result, giving NOT(NOT Q1 AND NOT Q2) which is equivalent to Q1 OR Q2
|
||||
args[30] = true;
|
||||
// Clear Addition row counter
|
||||
args[38] = false;
|
||||
}
|
||||
|
||||
// /,5,U : Count number of matches of /, 5 & U to find X3
|
||||
if (progname === "/,5,U (Count chars to find X3)") {
|
||||
// Set Conditional R1 : Match / char, ITA2 = ..... into counter 1
|
||||
args[9] = ".";
|
||||
args[10] = ".";
|
||||
args[11] = ".";
|
||||
args[12] = ".";
|
||||
args[13] = ".";
|
||||
args[14] = false;
|
||||
args[15] = "1";
|
||||
// Set Conditional R2 : Match 5 char, ITA2 = xx.xx into counter 2
|
||||
args[16] = "x";
|
||||
args[17] = "x";
|
||||
args[18] = ".";
|
||||
args[19] = "x";
|
||||
args[20] = "x";
|
||||
args[21] = false;
|
||||
args[22] = "2";
|
||||
// Set Conditional R3 : Match U char, ITA2 = xxx.. into counter 3
|
||||
args[23] = "x";
|
||||
args[24] = "x";
|
||||
args[25] = "x";
|
||||
args[26] = ".";
|
||||
args[27] = ".";
|
||||
args[28] = false;
|
||||
args[29] = "3";
|
||||
// Clear Negate result
|
||||
args[30] = false;
|
||||
// Clear Addition row counter
|
||||
args[38] = false;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays Colossus results in an HTML table
|
||||
*
|
||||
* @param {Object} output
|
||||
* @param {Object[]} output.counters
|
||||
* @returns {html}
|
||||
*/
|
||||
present(output) {
|
||||
let html = "Colossus Printer\n\n";
|
||||
html += output.printout + "\n\n";
|
||||
html += "Colossus Counters\n\n";
|
||||
html += "<table class='table table-hover table-sm table-bordered table-nonfluid'><tr><th>C1</th> <th>C2</th> <th>C3</th> <th>C4</th> <th>C5</th></tr>\n";
|
||||
html += "<tr>";
|
||||
for (const ct of output.counters) {
|
||||
html += `<td>${ct}</td>\n`;
|
||||
}
|
||||
html += "</tr>";
|
||||
html += "</table>";
|
||||
return html;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Colossus;
|
82
src/core/operations/ConvertToNATOAlphabet.mjs
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @author MarvinJWendt [git@marvinjwendt.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
|
||||
/**
|
||||
* Convert to NATO alphabet operation
|
||||
*/
|
||||
class ConvertToNATOAlphabet extends Operation {
|
||||
/**
|
||||
* ConvertToNATOAlphabet constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Convert to NATO alphabet";
|
||||
this.module = "Default";
|
||||
this.description = "Converts characters to their representation in the NATO phonetic alphabet.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/NATO_phonetic_alphabet";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return input.replace(/[a-z0-9,/.]/ig, letter => {
|
||||
return lookup[letter.toUpperCase()];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const lookup = {
|
||||
"A": "Alfa ",
|
||||
"B": "Bravo ",
|
||||
"C": "Charlie ",
|
||||
"D": "Delta ",
|
||||
"E": "Echo ",
|
||||
"F": "Foxtrot ",
|
||||
"G": "Golf ",
|
||||
"H": "Hotel ",
|
||||
"I": "India ",
|
||||
"J": "Juliett ",
|
||||
"K": "Kilo ",
|
||||
"L": "Lima ",
|
||||
"M": "Mike ",
|
||||
"N": "November ",
|
||||
"O": "Oscar ",
|
||||
"P": "Papa ",
|
||||
"Q": "Quebec ",
|
||||
"R": "Romeo ",
|
||||
"S": "Sierra ",
|
||||
"T": "Tango ",
|
||||
"U": "Uniform ",
|
||||
"V": "Victor ",
|
||||
"W": "Whiskey ",
|
||||
"X": "X-ray ",
|
||||
"Y": "Yankee ",
|
||||
"Z": "Zulu ",
|
||||
"0": "Zero ",
|
||||
"1": "One ",
|
||||
"2": "Two ",
|
||||
"3": "Three ",
|
||||
"4": "Four ",
|
||||
"5": "Five ",
|
||||
"6": "Six ",
|
||||
"7": "Seven ",
|
||||
"8": "Eight ",
|
||||
"9": "Nine ",
|
||||
",": "Comma ",
|
||||
"/": "Fraction bar ",
|
||||
".": "Full stop ",
|
||||
};
|
||||
|
||||
export default ConvertToNATOAlphabet;
|
@ -24,6 +24,13 @@ class DechunkHTTPResponse extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^[0-9A-F]+\r\n",
|
||||
flags: "i",
|
||||
args: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,13 @@ class DecodeNetBIOSName extends Operation {
|
||||
"value": 65
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*\\S{32}$",
|
||||
flags: "",
|
||||
args: [65]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,17 @@ class DefangIPAddresses extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*(([0-9]{1,3}\\.){3}[0-9]{1,3}|([0-9a-f]{4}:){7}[0-9a-f]{4})\\s*$",
|
||||
flags: "i",
|
||||
args: [],
|
||||
output: {
|
||||
pattern: "^\\s*(([0-9]{1,3}\\[\\.\\]){3}[0-9]{1,3}|([0-9a-f]{4}\\[\\:\\]){7}[0-9a-f]{4})\\s*$",
|
||||
flags: "i"
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,22 +44,22 @@ class EscapeUnicodeCharacters extends Operation {
|
||||
"value": true
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "\\\\u(?:[\\da-f]{4,6})",
|
||||
pattern: "\\\\u(?:[\\da-f]{4,6})",
|
||||
flags: "i",
|
||||
args: ["\\u"]
|
||||
},
|
||||
{
|
||||
match: "%u(?:[\\da-f]{4,6})",
|
||||
pattern: "%u(?:[\\da-f]{4,6})",
|
||||
flags: "i",
|
||||
args: ["%u"]
|
||||
},
|
||||
{
|
||||
match: "U\\+(?:[\\da-f]{4,6})",
|
||||
pattern: "U\\+(?:[\\da-f]{4,6})",
|
||||
flags: "i",
|
||||
args: ["U+"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,9 @@ class FromBCD extends Operation {
|
||||
"value": FORMAT
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:\\d{4} ){3,}\\d{4}$",
|
||||
pattern: "^(?:\\d{4} ){3,}\\d{4}$",
|
||||
flags: "",
|
||||
args: ["8 4 2 1", true, false, "Nibbles"]
|
||||
},
|
||||
|
@ -36,12 +36,12 @@ class FromBase32 extends Operation {
|
||||
value: true
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
|
||||
pattern: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$",
|
||||
flags: "",
|
||||
args: ["A-Z2-7=", false]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -38,14 +38,14 @@ class FromBase58 extends Operation {
|
||||
"value": true
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
|
||||
pattern: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
|
||||
flags: "",
|
||||
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false]
|
||||
},
|
||||
{
|
||||
match: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
|
||||
pattern: "^[1-9A-HJ-NP-Za-km-z]{20,}$",
|
||||
flags: "",
|
||||
args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false]
|
||||
},
|
||||
|
@ -36,69 +36,69 @@ class FromBase64 extends Operation {
|
||||
value: true
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9+/=", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*[A-Z\\d\\-_]{20,}\\s*$",
|
||||
pattern: "^\\s*[A-Z\\d\\-_]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9-_", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9+\\-=", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["./0-9A-Za-z=", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*[A-Z\\d_.]{20,}\\s*$",
|
||||
pattern: "^\\s*[A-Z\\d_.]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9_.", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9._-", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["0-9a-zA-Z+/=", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["0-9A-Za-z+/=", true]
|
||||
},
|
||||
{
|
||||
match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$",
|
||||
pattern: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$",
|
||||
flags: "",
|
||||
args: [" -_", false]
|
||||
},
|
||||
{
|
||||
match: "^\\s*[A-Z\\d+\\-]{20,}\\s*$",
|
||||
pattern: "^\\s*[A-Z\\d+\\-]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["+\\-0-9A-Za-z", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}\\s*$",
|
||||
pattern: "^\\s*[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}\\s*$",
|
||||
flags: "",
|
||||
args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?\\s*$",
|
||||
pattern: "^\\s*(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["N-ZA-Mn-za-m0-9+/=", true]
|
||||
},
|
||||
{
|
||||
match: "^\\s*[A-Z\\d./]{20,}\\s*$",
|
||||
pattern: "^\\s*[A-Z\\d./]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["./0-9A-Za-z", true]
|
||||
},
|
||||
|
@ -33,39 +33,39 @@ class FromBinary extends Operation {
|
||||
"value": BIN_DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:[01]{8})+$",
|
||||
pattern: "^(?:[01]{8})+$",
|
||||
flags: "",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?: [01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?: [01]{8})*$",
|
||||
flags: "",
|
||||
args: ["Space"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?:,[01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?:,[01]{8})*$",
|
||||
flags: "",
|
||||
args: ["Comma"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?:;[01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?:;[01]{8})*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?::[01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?::[01]{8})*$",
|
||||
flags: "",
|
||||
args: ["Colon"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?:\\n[01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?:\\n[01]{8})*$",
|
||||
flags: "",
|
||||
args: ["Line feed"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$",
|
||||
pattern: "^(?:[01]{8})(?:\\r\\n[01]{8})*$",
|
||||
flags: "",
|
||||
args: ["CRLF"]
|
||||
},
|
||||
|
@ -36,37 +36,37 @@ class FromDecimal extends Operation {
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["Space", false]
|
||||
},
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["Comma", false]
|
||||
},
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon", false]
|
||||
},
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["Colon", false]
|
||||
},
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["Line feed", false]
|
||||
},
|
||||
{
|
||||
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
pattern: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
|
||||
flags: "",
|
||||
args: ["CRLF", false]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,12 @@ class FromHTMLEntity extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});",
|
||||
pattern: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});",
|
||||
flags: "i",
|
||||
args: []
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -32,49 +32,54 @@ class FromHex extends Operation {
|
||||
value: FROM_HEX_DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:[\\dA-F]{2})+$",
|
||||
pattern: "^(?:[\\dA-F]{2})+$",
|
||||
flags: "i",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["Space"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["Comma"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["Semi-colon"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["Colon"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["Line feed"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$",
|
||||
pattern: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["CRLF"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:0x[\\dA-F]{2})*$",
|
||||
pattern: "^(?:0x[\\dA-F]{2})+$",
|
||||
flags: "i",
|
||||
args: ["0x"]
|
||||
},
|
||||
{
|
||||
match: "^[\\dA-F]{2}(?:\\\\x[\\dA-F]{2})*$",
|
||||
pattern: "^0x[\\dA-F]{2}(?:,0x[\\dA-F]{2})*$",
|
||||
flags: "i",
|
||||
args: ["0x with comma"]
|
||||
},
|
||||
{
|
||||
pattern: "^(?:\\\\x[\\dA-F]{2})+$",
|
||||
flags: "i",
|
||||
args: ["\\x"]
|
||||
}
|
||||
|
@ -26,6 +26,13 @@ class FromHexContent extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "\\|([\\da-f]{2} ?)+\\|",
|
||||
flags: "i",
|
||||
args: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,9 +27,9 @@ class FromHexdump extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:(?:[\\dA-F]{4,16}h?:?)?[ \\t]*((?:[\\dA-F]{2} ){1,8}(?:[ \\t]|[\\dA-F]{2}-)(?:[\\dA-F]{2} ){1,8}|(?:[\\dA-F]{4} )*[\\dA-F]{4}|(?:[\\dA-F]{2} )*[\\dA-F]{2})[^\\n]*\\n?){2,}$",
|
||||
pattern: "^(?:(?:[\\dA-F]{4,16}h?:?)?[ \\t]*((?:[\\dA-F]{2} ){1,8}(?:[ \\t]|[\\dA-F]{2}-)(?:[\\dA-F]{2} ){1,8}|(?:[\\dA-F]{4} )*[\\dA-F]{4}|(?:[\\dA-F]{2} )*[\\dA-F]{2})[^\\n]*\\n?){2,}$",
|
||||
flags: "i",
|
||||
args: []
|
||||
},
|
||||
|
@ -37,12 +37,12 @@ class FromMorseCode extends Operation {
|
||||
"value": WORD_DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)",
|
||||
pattern: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)",
|
||||
flags: "i",
|
||||
args: ["Space", "Line feed"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -32,37 +32,37 @@ class FromOctal extends Operation {
|
||||
"value": DELIM_OPTIONS
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["Space"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["Comma"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["Semi-colon"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["Colon"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["Line feed"]
|
||||
},
|
||||
{
|
||||
match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$",
|
||||
flags: "",
|
||||
args: ["CRLF"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,9 @@ class FromQuotedPrintable extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "byteArray";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]{0,76}(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$",
|
||||
pattern: "^[\\x21-\\x3d\\x3f-\\x7e \\t]{0,76}(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$",
|
||||
flags: "i",
|
||||
args: []
|
||||
},
|
||||
|
@ -33,27 +33,27 @@ class FromUNIXTimestamp extends Operation {
|
||||
"value": UNITS
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^1?\\d{9}$",
|
||||
pattern: "^1?\\d{9}$",
|
||||
flags: "",
|
||||
args: ["Seconds (s)"]
|
||||
},
|
||||
{
|
||||
match: "^1?\\d{12}$",
|
||||
pattern: "^1?\\d{12}$",
|
||||
flags: "",
|
||||
args: ["Milliseconds (ms)"]
|
||||
},
|
||||
{
|
||||
match: "^1?\\d{15}$",
|
||||
pattern: "^1?\\d{15}$",
|
||||
flags: "",
|
||||
args: ["Microseconds (μs)"]
|
||||
},
|
||||
{
|
||||
match: "^1?\\d{18}$",
|
||||
pattern: "^1?\\d{18}$",
|
||||
flags: "",
|
||||
args: ["Nanoseconds (ns)"]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
184
src/core/operations/GenerateImage.mjs
Normal file
@ -0,0 +1,184 @@
|
||||
/**
|
||||
* @author pointhi [thomas.pointhuber@gmx.at]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import {isImage} from "../lib/FileType";
|
||||
import {toBase64} from "../lib/Base64";
|
||||
import jimp from "jimp";
|
||||
import {isWorkerEnvironment} from "../Utils";
|
||||
|
||||
/**
|
||||
* Generate Image operation
|
||||
*/
|
||||
class GenerateImage extends Operation {
|
||||
|
||||
/**
|
||||
* GenerateImage constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Generate Image";
|
||||
this.module = "Image";
|
||||
this.description = "Generates an image using the input as pixel values.";
|
||||
this.infoURL = "";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.presentType = "html";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Mode",
|
||||
"type": "option",
|
||||
"value": ["Greyscale", "RG", "RGB", "RGBA", "Bits"]
|
||||
},
|
||||
{
|
||||
"name": "Pixel Scale Factor",
|
||||
"type": "number",
|
||||
"value": 8,
|
||||
},
|
||||
{
|
||||
"name": "Pixels per row",
|
||||
"type": "number",
|
||||
"value": 64,
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
async run(input, args) {
|
||||
const [mode, scale, width] = args;
|
||||
input = new Uint8Array(input);
|
||||
|
||||
if (scale <= 0) {
|
||||
throw new OperationError("Pixel Scale Factor needs to be > 0");
|
||||
}
|
||||
|
||||
if (width <= 0) {
|
||||
throw new OperationError("Pixels per Row needs to be > 0");
|
||||
}
|
||||
|
||||
const bytePerPixelMap = {
|
||||
"Greyscale": 1,
|
||||
"RG": 2,
|
||||
"RGB": 3,
|
||||
"RGBA": 4,
|
||||
"Bits": 1/8,
|
||||
};
|
||||
|
||||
const bytesPerPixel = bytePerPixelMap[mode];
|
||||
|
||||
if (bytesPerPixel > 0 && input.length % bytesPerPixel !== 0) {
|
||||
throw new OperationError(`Number of bytes is not a divisor of ${bytesPerPixel}`);
|
||||
}
|
||||
|
||||
const height = Math.ceil(input.length / bytesPerPixel / width);
|
||||
const image = await new jimp(width, height, (err, image) => {});
|
||||
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage("Generating image from data...");
|
||||
|
||||
if (mode === "Bits") {
|
||||
let index = 0;
|
||||
for (let j = 0; j < input.length; j++) {
|
||||
const curByte = Utils.bin(input[j]);
|
||||
for (let k = 0; k < 8; k++, index++) {
|
||||
const x = index % width;
|
||||
const y = Math.floor(index / width);
|
||||
|
||||
const value = curByte[k] === "0" ? 0xFF : 0x00;
|
||||
const pixel = jimp.rgbaToInt(value, value, value, 0xFF);
|
||||
image.setPixelColor(pixel, x, y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let i = 0;
|
||||
while (i < input.length) {
|
||||
const index = i / bytesPerPixel;
|
||||
const x = index % width;
|
||||
const y = Math.floor(index / width);
|
||||
|
||||
let red = 0x00;
|
||||
let green = 0x00;
|
||||
let blue = 0x00;
|
||||
let alpha = 0xFF;
|
||||
|
||||
switch (mode) {
|
||||
case "Greyscale":
|
||||
red = green = blue = input[i++];
|
||||
break;
|
||||
|
||||
case "RG":
|
||||
red = input[i++];
|
||||
green = input[i++];
|
||||
break;
|
||||
|
||||
case "RGB":
|
||||
red = input[i++];
|
||||
green = input[i++];
|
||||
blue = input[i++];
|
||||
break;
|
||||
|
||||
case "RGBA":
|
||||
red = input[i++];
|
||||
green = input[i++];
|
||||
blue = input[i++];
|
||||
alpha = input[i++];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new OperationError(`Unsupported Mode: (${mode})`);
|
||||
}
|
||||
|
||||
try {
|
||||
const pixel = jimp.rgbaToInt(red, green, blue, alpha);
|
||||
image.setPixelColor(pixel, x, y);
|
||||
} catch (err) {
|
||||
throw new OperationError(`Error while generating image from pixel values. (${err})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scale !== 1) {
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage("Scaling image...");
|
||||
|
||||
image.scaleToFit(width*scale, height*scale, jimp.RESIZE_NEAREST_NEIGHBOR);
|
||||
}
|
||||
|
||||
try {
|
||||
const imageBuffer = await image.getBufferAsync(jimp.MIME_PNG);
|
||||
return imageBuffer.buffer;
|
||||
} catch (err) {
|
||||
throw new OperationError(`Error generating image. (${err})`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the generated image using HTML for web apps
|
||||
* @param {ArrayBuffer} data
|
||||
* @returns {html}
|
||||
*/
|
||||
present(data) {
|
||||
if (!data.byteLength) return "";
|
||||
const dataArray = new Uint8Array(data);
|
||||
|
||||
const type = isImage(dataArray);
|
||||
if (!type) {
|
||||
throw new OperationError("Invalid file type.");
|
||||
}
|
||||
|
||||
return `<img src="data:${type};base64,${toBase64(dataArray)}">`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GenerateImage;
|
@ -27,12 +27,12 @@ class Gunzip extends Operation {
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "ArrayBuffer";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^\\x1f\\x8b\\x08",
|
||||
pattern: "^\\x1f\\x8b\\x08",
|
||||
flags: "",
|
||||
args: []
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ class Lorenz extends Operation {
|
||||
|
||||
this.name = "Lorenz";
|
||||
this.module = "Bletchley";
|
||||
this.description = "The Lorenz SZ40/42 cipher attachment was a WW2 German rotor cipher machine with twelve rotors which attached in-line between remote teleprinters.<br><br>It used the Vernam cipher with two groups of five rotors (named the psi(ψ) wheels and chi(χ) wheels at Bletchley Park) to create two pseudorandom streams of five bits, encoded in ITA2, which were XOR added to the plaintext. Two other rotors, dubbed the mu(μ) or motor wheels, could hold up the stepping of the psi wheels meaning they stepped intermittently.<br><br>Each rotor has a different number of cams/lugs around their circumference which could be set active or inactive changing the key stream.<br><br>Three models of the Lorenz are emulated, SZ40, SZ42a and SZ42b and three example wheel patterns (the lug settings) are included (KH, ZMUG & BREAM) with the option to set a custom set using the letter 'x' for active or '.' for an inactive lug.<br><br>The input can either be plaintext or ITA2 when sending and ITA2 when receiving.<br><br>To learn more, Virtual Lorenz, an online, browser based simulation of the Lorenz SZ40/42 is available at <a href='https://lorenz.virtualcolossus.co.uk' target='_blank'>https://lorenz.virtualcolossus.co.uk</a>.<br><br>A more detailed description of this operation can be found <a href='https://github.com/gchq/CyberChef/wiki/Lorenz-SZ' target='_blank'>here</a>.";
|
||||
this.description = "The Lorenz SZ40/42 cipher attachment was a WW2 German rotor cipher machine with twelve rotors which attached in-line between remote teleprinters.<br><br>It used the Vernam cipher with two groups of five rotors (named the psi(ψ) wheels and chi(χ) wheels at Bletchley Park) to create two pseudorandom streams of five bits, encoded in ITA2, which were XOR added to the plaintext. Two other rotors, dubbed the mu(μ) or motor wheels, could hold up the stepping of the psi wheels meaning they stepped intermittently.<br><br>Each rotor has a different number of cams/lugs around their circumference which could be set active or inactive changing the key stream.<br><br>Three models of the Lorenz are emulated, SZ40, SZ42a and SZ42b and three example wheel patterns (the lug settings) are included (KH, ZMUG & BREAM) with the option to set a custom set using the letter 'x' for active or '.' for an inactive lug.<br><br>The input can either be plaintext or ITA2 when sending and ITA2 when receiving.<br><br>To learn more, Virtual Lorenz, an online, browser based simulation of the Lorenz SZ40/42 is available at <a href='https://lorenz.virtualcolossus.co.uk' target='_blank'>lorenz.virtualcolossus.co.uk</a>.<br><br>A more detailed description of this operation can be found <a href='https://github.com/gchq/CyberChef/wiki/Lorenz-SZ' target='_blank'>here</a>.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Lorenz_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
@ -293,8 +293,8 @@ class Lorenz extends Operation {
|
||||
chosenSetting.S[3] = this.readLugs(lugs3);
|
||||
chosenSetting.S[4] = this.readLugs(lugs4);
|
||||
chosenSetting.S[5] = this.readLugs(lugs5);
|
||||
chosenSetting.M[1] = this.readLugs(lugm37);
|
||||
chosenSetting.M[2] = this.readLugs(lugm61);
|
||||
chosenSetting.M[1] = this.readLugs(lugm61);
|
||||
chosenSetting.M[2] = this.readLugs(lugm37);
|
||||
chosenSetting.X[1] = this.readLugs(lugx1);
|
||||
chosenSetting.X[2] = this.readLugs(lugx2);
|
||||
chosenSetting.X[3] = this.readLugs(lugx3);
|
||||
|
77
src/core/operations/LuhnChecksum.mjs
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Luhn Checksum operation
|
||||
*/
|
||||
class LuhnChecksum extends Operation {
|
||||
|
||||
/**
|
||||
* LuhnChecksum constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Luhn Checksum";
|
||||
this.module = "Default";
|
||||
this.description = "The Luhn algorithm, also known as the modulus 10 or mod 10 algorithm, is a simple checksum formula used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers and Canadian Social Insurance Numbers.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Luhn_algorithm";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Luhn Checksum from the input.
|
||||
*
|
||||
* @param {string} inputStr
|
||||
* @returns {number}
|
||||
*/
|
||||
checksum(inputStr) {
|
||||
let even = false;
|
||||
return inputStr.split("").reverse().reduce((acc, elem) => {
|
||||
// Convert element to integer.
|
||||
let temp = parseInt(elem, 10);
|
||||
|
||||
// If element is not an integer.
|
||||
if (isNaN(temp))
|
||||
throw new OperationError("Character: " + elem + " is not a digit.");
|
||||
|
||||
// If element is in an even position
|
||||
if (even) {
|
||||
// Double the element and add the quotient and remainder together.
|
||||
temp = 2 * elem;
|
||||
temp = Math.floor(temp/10) + (temp % 10);
|
||||
}
|
||||
|
||||
even = !even;
|
||||
return acc + temp;
|
||||
}, 0) % 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!input) return "";
|
||||
|
||||
const checkSum = this.checksum(input);
|
||||
let checkDigit = this.checksum(input + "0");
|
||||
checkDigit = checkDigit === 0 ? 0 : (10-checkDigit);
|
||||
|
||||
return `Checksum: ${checkSum}
|
||||
Checkdigit: ${checkDigit}
|
||||
Luhn Validated String: ${input + "" + checkDigit}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default LuhnChecksum;
|
@ -144,7 +144,7 @@ class MultipleBombe extends Operation {
|
||||
* @param {number} progress - Progress (as a float in the range 0..1)
|
||||
*/
|
||||
updateStatus(nLoops, nStops, progress, start) {
|
||||
const elapsed = new Date().getTime() - start;
|
||||
const elapsed = Date.now() - start;
|
||||
const remaining = (elapsed / progress) * (1 - progress) / 1000;
|
||||
const hours = Math.floor(remaining / 3600);
|
||||
const minutes = `0${Math.floor((remaining % 3600) / 60)}`.slice(-2);
|
||||
@ -237,7 +237,7 @@ class MultipleBombe extends Operation {
|
||||
const totalRuns = choose(rotors.length, 3) * 6 * fourthRotors.length * reflectors.length;
|
||||
let nRuns = 0;
|
||||
let nStops = 0;
|
||||
const start = new Date().getTime();
|
||||
const start = Date.now();
|
||||
for (const rotor1 of rotors) {
|
||||
for (const rotor2 of rotors) {
|
||||
if (rotor2 === rotor1) {
|
||||
|
47
src/core/operations/ParseObjectIDTimestamp.mjs
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @author dmfj [dominic@dmfj.io]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import BSON from "bson";
|
||||
|
||||
/**
|
||||
* Parse ObjectID timestamp operation
|
||||
*/
|
||||
class ParseObjectIDTimestamp extends Operation {
|
||||
|
||||
/**
|
||||
* ParseObjectIDTimestamp constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Parse ObjectID timestamp";
|
||||
this.module = "Serialise";
|
||||
this.description = "Parse timestamp from MongoDB/BSON ObjectID hex string.";
|
||||
this.infoURL = "https://docs.mongodb.com/manual/reference/method/ObjectId.getTimestamp/";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
const objectId = new BSON.ObjectID(input);
|
||||
return objectId.getTimestamp().toISOString();
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseObjectIDTimestamp;
|
@ -33,9 +33,9 @@ class ParseQRCode extends Operation {
|
||||
"value": false
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
|
||||
"pattern": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
|
||||
"flags": "",
|
||||
"args": [false],
|
||||
"useful": true
|
||||
|
@ -38,6 +38,13 @@ class ParseSSHHostKey extends Operation {
|
||||
]
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*([A-F\\d]{2}[,;:]){15,}[A-F\\d]{2}\\s*$",
|
||||
flags: "i",
|
||||
args: ["Hex"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,13 @@ class ParseUNIXFilePermissions extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*d[rxw-]{9}\\s*$",
|
||||
flags: "",
|
||||
args: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,13 @@ class ParseUserAgent extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^(User-Agent:|Mozilla\\/)[^\\n\\r]+\\s*$",
|
||||
flags: "i",
|
||||
args: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,13 +35,11 @@ class ParseX509Certificate extends Operation {
|
||||
"value": ["PEM", "DER Hex", "Base64", "Raw"]
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
"match": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$",
|
||||
"pattern": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$",
|
||||
"flags": "i",
|
||||
"args": [
|
||||
"PEM"
|
||||
]
|
||||
"args": ["PEM"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
88
src/core/operations/RailFenceCipherDecode.mjs
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @author Flavio Diez [flaviofdiez+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Rail Fence Cipher Decode operation
|
||||
*/
|
||||
class RailFenceCipherDecode extends Operation {
|
||||
|
||||
/**
|
||||
* RailFenceCipherDecode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Rail Fence Cipher Decode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Decodes Strings that were created using the Rail fence Cipher provided a key and an offset";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Rail_fence_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "number",
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: "Offset",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key, offset] = args;
|
||||
|
||||
let cipher = input;
|
||||
|
||||
if (key < 2) {
|
||||
throw new OperationError("Key has to be bigger than 2");
|
||||
} else if (key > cipher.length) {
|
||||
throw new OperationError("Key should be smaller than the cipher's length");
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
throw new OperationError("Offset has to be a positive integer");
|
||||
}
|
||||
|
||||
const cycle = (key - 1) * 2;
|
||||
|
||||
const rest = cipher.length % key;
|
||||
|
||||
if (rest !== 0) {
|
||||
cipher = cipher + (" ".repeat(key - rest));
|
||||
}
|
||||
|
||||
const plaintext = new Array(cipher.length);
|
||||
|
||||
let j = 0;
|
||||
let x, y;
|
||||
|
||||
for (y = 0; y < key; y++) {
|
||||
for (x = 0; x < cipher.length; x++) {
|
||||
if ((y + x + offset) % cycle === 0 || (y - x - offset) % cycle === 0) {
|
||||
plaintext[x] = cipher[j++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext.join("").trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default RailFenceCipherDecode;
|
74
src/core/operations/RailFenceCipherEncode.mjs
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @author Flavio Diez [flaviofdiez+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Rail Fence Cipher Encode operation
|
||||
*/
|
||||
class RailFenceCipherEncode extends Operation {
|
||||
|
||||
/**
|
||||
* RailFenceCipherEncode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Rail Fence Cipher Encode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Encodes Strings using the Rail fence Cipher provided a key and an offset";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Rail_fence_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "number",
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: "Offset",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key, offset] = args;
|
||||
|
||||
const plaintext = input;
|
||||
if (key < 2) {
|
||||
throw new OperationError("Key has to be bigger than 2");
|
||||
} else if (key > plaintext.length) {
|
||||
throw new OperationError("Key should be smaller than the plain text's length");
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
throw new OperationError("Offset has to be a positive integer");
|
||||
}
|
||||
|
||||
const cycle = (key - 1) * 2;
|
||||
const rows = new Array(key).fill("");
|
||||
|
||||
for (let pos = 0; pos < plaintext.length; pos++) {
|
||||
const rowIdx = key - 1 - Math.abs(cycle / 2 - (pos + offset) % cycle);
|
||||
|
||||
rows[rowIdx] += plaintext[pos];
|
||||
}
|
||||
|
||||
return rows.join("").trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RailFenceCipherEncode;
|
@ -60,6 +60,12 @@ class RawInflate extends Operation {
|
||||
value: false
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
entropyRange: [7.5, 8],
|
||||
args: [0, 0, INFLATE_BUFFER_TYPE, false, false]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ class RegularExpression extends Operation {
|
||||
},
|
||||
{
|
||||
name: "Email address",
|
||||
value: "\\b(\\w[-.\\w]*)@([-\\w]+(?:\\.[-\\w]+)*)\\.([A-Za-z]{2,4})\\b"
|
||||
value: "(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])"
|
||||
},
|
||||
{
|
||||
name: "URL",
|
||||
@ -163,7 +163,7 @@ class RegularExpression extends Operation {
|
||||
case "List matches with capture groups":
|
||||
return Utils.escapeHtml(regexList(input, regex, displayTotal, true, true));
|
||||
default:
|
||||
return "Error: Invalid output format";
|
||||
throw new OperationError("Error: Invalid output format");
|
||||
}
|
||||
} catch (err) {
|
||||
throw new OperationError("Invalid regex. Details: " + err.message);
|
||||
|
@ -35,12 +35,15 @@ class RenderImage extends Operation {
|
||||
"value": ["Raw", "Base64", "Hex"]
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
"match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
|
||||
"flags": "",
|
||||
"args": ["Raw"],
|
||||
"useful": true
|
||||
pattern: "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
|
||||
flags: "",
|
||||
args: ["Raw"],
|
||||
useful: true,
|
||||
output: {
|
||||
mime: "image"
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -35,6 +35,13 @@ class StripHTMLTags extends Operation {
|
||||
"value": true
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "(</html>|</div>|</body>)",
|
||||
flags: "i",
|
||||
args: [true, true]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,13 @@ class StripHTTPHeaders extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^HTTP(.|\\s)+?(\\r?\\n){2}",
|
||||
flags: "",
|
||||
args: []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,11 @@ class ToHex extends Operation {
|
||||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: TO_HEX_DELIM_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Bytes per line",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
@ -40,8 +45,16 @@ class ToHex extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space");
|
||||
return toHex(new Uint8Array(input), delim, 2);
|
||||
let delim, comma;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
comma = ",";
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
const lineSize = args[1];
|
||||
|
||||
return toHex(new Uint8Array(input), delim, 2, comma, lineSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,17 +67,31 @@ class ToHex extends Operation {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlight(pos, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
len = delim === "\r\n" ? 1 : delim.length;
|
||||
|
||||
pos[0].start = pos[0].start * (2 + len);
|
||||
pos[0].end = pos[0].end * (2 + len) - len;
|
||||
|
||||
// 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
|
||||
if (delim === "0x" || delim === "\\x") {
|
||||
pos[0].start += 2;
|
||||
pos[0].end += 2;
|
||||
let delim, commaLen;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
commaLen = 1;
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
|
||||
const lineSize = args[1],
|
||||
len = (delim === "\r\n" ? 1 : delim.length) + commaLen;
|
||||
|
||||
const countLF = function(p) {
|
||||
// Count the number of LFs from 0 upto p
|
||||
return (p / lineSize | 0) - (p >= lineSize && p % lineSize === 0);
|
||||
};
|
||||
|
||||
pos[0].start = pos[0].start * (2 + len) + countLF(pos[0].start);
|
||||
pos[0].end = pos[0].end * (2 + len) + countLF(pos[0].end);
|
||||
|
||||
// if the deliminators are not prepended, trim the trailing deliminator
|
||||
if (!(delim === "0x" || delim === "\\x")) {
|
||||
pos[0].end -= delim.length;
|
||||
}
|
||||
// if there is comma, trim the trailing comma
|
||||
pos[0].end -= commaLen;
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -78,20 +105,26 @@ class ToHex extends Operation {
|
||||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightReverse(pos, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
len = delim === "\r\n" ? 1 : delim.length,
|
||||
width = len + 2;
|
||||
|
||||
// 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
|
||||
if (delim === "0x" || delim === "\\x") {
|
||||
if (pos[0].start > 1) pos[0].start -= 2;
|
||||
else pos[0].start = 0;
|
||||
if (pos[0].end > 1) pos[0].end -= 2;
|
||||
else pos[0].end = 0;
|
||||
let delim, commaLen;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
commaLen = 1;
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
|
||||
pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
|
||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
|
||||
const lineSize = args[1],
|
||||
len = (delim === "\r\n" ? 1 : delim.length) + commaLen,
|
||||
width = len + 2;
|
||||
|
||||
const countLF = function(p) {
|
||||
// Count the number of LFs from 0 up to p
|
||||
const lineLength = width * lineSize;
|
||||
return (p / lineLength | 0) - (p >= lineLength && p % lineLength === 0);
|
||||
};
|
||||
|
||||
pos[0].start = pos[0].start === 0 ? 0 : Math.round((pos[0].start - countLF(pos[0].start)) / width);
|
||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil((pos[0].end - countLF(pos[0].end)) / width);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ class URLDecode extends Operation {
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: ".*(?:%[\\da-f]{2}.*){4}",
|
||||
pattern: ".*(?:%[\\da-f]{2}.*){4}",
|
||||
flags: "i",
|
||||
args: []
|
||||
},
|
||||
|
@ -27,9 +27,9 @@ class Untar extends Operation {
|
||||
this.outputType = "List<File>";
|
||||
this.presentType = "html";
|
||||
this.args = [];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
"match": "^.{257}\\x75\\x73\\x74\\x61\\x72",
|
||||
"pattern": "^.{257}\\x75\\x73\\x74\\x61\\x72",
|
||||
"flags": "",
|
||||
"args": []
|
||||
}
|
||||
|
@ -40,12 +40,12 @@ class Unzip extends Operation {
|
||||
value: false
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)",
|
||||
pattern: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)",
|
||||
flags: "",
|
||||
args: ["", false]
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -59,9 +59,9 @@ class ZlibInflate extends Operation {
|
||||
value: false
|
||||
}
|
||||
];
|
||||
this.patterns = [
|
||||
this.checks = [
|
||||
{
|
||||
match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)",
|
||||
pattern: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)",
|
||||
flags: "",
|
||||
args: [0, 0, "Adaptive", false, false]
|
||||
},
|
||||
|
2
src/core/vendor/gost/gostEngine.mjs
vendored
@ -383,7 +383,7 @@ if (root.importScripts) {
|
||||
* method with data parameter: algorithm, method and arg.<br>
|
||||
* Call method execute and postMessage() results to onmessage event handler
|
||||
* in the main process.<br>
|
||||
* If error occured onerror event handler executed in main process.
|
||||
* If error occurred onerror event handler executed in main process.
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @name onmessage
|
||||
|
4
src/core/vendor/gost/gostRandom.mjs
vendored
@ -70,7 +70,7 @@ if (typeof document !== 'undefined') {
|
||||
try {
|
||||
// Mouse move event to fill random array
|
||||
document.addEventListener('mousemove', function (e) {
|
||||
randomRing.set((new Date().getTime() & 255) ^
|
||||
randomRing.set((Date.now() & 255) ^
|
||||
((e.clientX || e.pageX) & 255) ^
|
||||
((e.clientY || e.pageY) & 255));
|
||||
}, false);
|
||||
@ -80,7 +80,7 @@ if (typeof document !== 'undefined') {
|
||||
try {
|
||||
// Keypress event to fill random array
|
||||
document.addEventListener('keydown', function (e) {
|
||||
randomRing.set((new Date().getTime() & 255) ^
|
||||
randomRing.set((Date.now() & 255) ^
|
||||
(e.keyCode & 255));
|
||||
}, false);
|
||||
} catch (e) {
|
||||
|
@ -282,11 +282,11 @@ export function help(input) {
|
||||
.map(result => result.hydrated);
|
||||
|
||||
if (matches && matches.length) {
|
||||
console.log(`${matches.length} result${matches.length > 1 ? "s" : ""} found.`);
|
||||
// console.log(`${matches.length} result${matches.length > 1 ? "s" : ""} found.`);
|
||||
return matches;
|
||||
}
|
||||
|
||||
console.log("No results found.");
|
||||
// console.log("No results found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -293,6 +293,16 @@ class HTMLIngredient {
|
||||
|
||||
this.manager.addDynamicListener(".arg-selector", "change", this.argSelectorChange, this);
|
||||
break;
|
||||
case "label":
|
||||
html += `<div class="form-group">
|
||||
<label>${this.name}</label>
|
||||
<input type="hidden"
|
||||
class="form-control arg"
|
||||
id="${this.id}"
|
||||
arg-name="${this.name}"
|
||||
value="">
|
||||
</div>`;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
728
src/web/static/images/logo/cyberchef.svg
Executable file
@ -0,0 +1,728 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 511.99999 511.99999"
|
||||
id="svg4819"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cyberchef.svg"
|
||||
inkscape:export-filename="H:\My Documents\CyberChef\images\logo\os\cyberchef_logo.png"
|
||||
inkscape:export-xdpi="263.67001"
|
||||
inkscape:export-ydpi="263.67001">
|
||||
<defs
|
||||
id="defs4821">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4392">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4394" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4396" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4398" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-2.47025e-015"
|
||||
result="offset"
|
||||
id="feOffset4400" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4402" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4576">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4578" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4580" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4582" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4584" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4586" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4588">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4590" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4592" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4594" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4596" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4598" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4608">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4610" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4612" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4614" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4616" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4618" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4620">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4622" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4624" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4626" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4628" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4630" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4736">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4738" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4740" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4742" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4744" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4746" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4784">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4786" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4788" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4790" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="2"
|
||||
result="offset"
|
||||
id="feOffset4792" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4794" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4830">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4832" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4834" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4836" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4838" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4840" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4842">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4844" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4846" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4848" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4850" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4852" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4637">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4639" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4641" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4643" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset4645" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4647" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4649">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4651" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4653" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4655" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4657" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4659" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4661">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4663" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4665" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4667" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4669" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4671" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4682">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4684" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4686" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4688" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4690" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4692" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4694">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4696" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4698" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4700" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4702" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4704" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4879">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4881" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4883" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="2"
|
||||
result="blur"
|
||||
id="feGaussianBlur4885" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4887" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4889" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5095">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5097" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5099" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur5101" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5103" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5105" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.70000001"
|
||||
inkscape:cx="269.91137"
|
||||
inkscape:cy="253.12655"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g4673"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1138"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4824">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-540.36219)">
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-0"
|
||||
cx="203.00006"
|
||||
cy="871.01947"
|
||||
r="14.964106" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#a05a2c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;filter:url(#filter4661)"
|
||||
d="m 147.26218,836.04571 c -25.20823,-0.10755 -39.52686,29.07087 -38.48314,49.6054 -50.615937,46.28423 -16.205613,107.16245 37.64298,108.72598 32.0833,-1.5e-4 42.68786,-30.52742 42.68801,-63.04845 -0.0198,-17.82216 -8.00167,-34.67629 -21.70832,-45.83854 1.05039,-3.56483 1.5874,-7.26473 1.59442,-10.98515 0,-21.34208 -0.67913,-38.45924 -21.73395,-38.45924 z"
|
||||
id="path5533"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#666666;stroke:none;filter:url(#filter4649)"
|
||||
d="m 329.75057,848.9372 -0.99384,5.44742 c -0.54665,2.99618 -1.51544,9.1802 -2.15123,13.74049 -0.96309,6.90853 -2.0091,8.79753 -6.28134,11.3267 -4.99839,2.95911 -5.3259,2.94503 -13.05113,-0.51884 -17.00524,-7.62485 -16.50462,-7.73628 -24.18511,5.36828 -0.83958,1.43242 -1.5755,2.69215 -2.21413,3.80274 -4.47081,7.77361 -4.19222,8.34457 -1.54404,11.31067 1.69375,1.89713 6.44342,5.94635 10.55236,9.00298 6.60433,4.91288 7.45215,6.27116 7.30351,11.70885 -0.14851,5.43242 -1.3543,7.12566 -10.33319,14.48994 -5.59176,4.58626 -10.1684,8.74733 -10.16843,9.24712 -2e-5,1.6752 11.82228,22.36426 13.3138,23.29861 0.81025,0.50761 6.89179,-1.29426 13.51104,-4.00793 11.69561,-4.79479 12.17517,-4.8546 16.98848,-2.07698 4.0965,2.36394 5.15278,4.28857 6.10882,11.14635 0.6358,4.56033 1.60491,10.74732 2.1515,13.74346 l 0.99533,5.44345 13.89887,-1.1e-4 13.90372,0 1.72092,-6.28433 c 0.94717,-3.45714 1.73487,-8.17143 1.75242,-10.47619 0.0565,-7.42942 1.72011,-10.87992 6.61533,-13.72769 4.61835,-2.68631 5.20277,-2.61426 16.03306,2.06875 6.18176,2.67299 12.00889,4.88209 12.94949,4.90711 0.94061,0.025 4.43989,-4.67108 7.77519,-10.43288 3.33531,-5.76188 6.078,-11.60524 6.09452,-12.98806 0.0166,-1.38282 -4.3658,-5.90842 -9.74023,-10.05691 -8.71341,-6.72592 -9.78365,-8.20675 -9.87259,-13.6679 -0.0899,-5.51114 0.89302,-6.93673 9.81558,-14.24623 5.45348,-4.46763 9.91683,-9.15506 9.92014,-10.41728 0.006,-1.70693 -8.94144,-18.4331 -12.49772,-23.36766 -0.2065,-0.2861 -6.15615,1.75011 -13.22574,4.53279 -12.27748,4.83246 -13.0599,4.94274 -17.42196,2.33088 -4.67438,-2.79905 -6.3909,-6.49185 -6.44709,-13.88872 -0.0176,-2.30473 -0.80397,-7.0164 -1.75108,-10.47347 l -1.72259,-6.28557 -13.90368,-0.002 -13.89894,1.7e-4 z m 8.33566,50.05554 a 21.565918,21.860154 0 0 1 26.41031,15.4593 21.565918,21.860154 0 0 1 -15.24637,26.77349 21.565918,21.860154 0 0 1 -26.41413,-15.4583 21.565918,21.860154 0 0 1 15.25019,-26.77449 z"
|
||||
id="path5680-4" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect4178"
|
||||
width="80.357857"
|
||||
height="21.07921"
|
||||
x="182.31805"
|
||||
y="965.93365" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#de8787;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 248.10536,1013.0243 0.0735,6e-4 0.27913,-33.12148 -0.0735,-6.2e-4 -0.0549,6.51764 -66.53394,-0.61382 c 18.2854,10.09362 31.55974,25.45918 66.38614,18.15098 z"
|
||||
id="path6299"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 247.7409,975.65034 58.09206,-0.65817 c 0.3574,12.17742 -35.60705,22.20893 -58.09206,23.00293 z"
|
||||
id="rect5437-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<g
|
||||
id="g4814"
|
||||
transform="matrix(1.0166163,0,0,1.0304866,-12.543356,-24.305675)"
|
||||
style="stroke:none;filter:url(#filter4694)">
|
||||
<path
|
||||
id="path5473"
|
||||
transform="translate(0,540.36219)"
|
||||
d="m 256,294.35938 0,136.21289 0.0293,0 0,-0.5625 57.14258,-0.63868 c 0.35133,11.80977 -34.97938,21.53912 -57.09961,22.32032 l 0,11.02343 -0.0723,0 0,32.51368 c 35.99476,0.4041 68.91204,-13.70201 99.9375,-36.72461 l 0,-164.14453 -99.9375,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5437"
|
||||
d="m 256,834.72124 0,135.93276 -57.14285,0.17857 c 4.80435,15.52459 35.24626,22.13924 57.14285,21.25 l 0,43.50783 c -30.78963,-0.3457 -63.82206,-11.2715 -99.9375,-36.72463 l 0,-164.14453 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffe1e1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-1"
|
||||
cx="196.15344"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path6225-7"
|
||||
cx="204.14046"
|
||||
cy="882.65778"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1fdf1f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5"
|
||||
cx="294.18433"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path6225"
|
||||
cx="300.96732"
|
||||
cy="882.12958"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<g
|
||||
id="g4743"
|
||||
style="filter:url(#filter4879)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5538"
|
||||
d="m 149.12011,835.91605 c -9.75347,0 -23.64321,12.16601 -23.43637,26.91145 26.77544,0.89277 12.23382,16.59426 54.45054,16.59426 23.57775,-8.2e-4 52.36301,-19.37569 52.36241,-43.27513 -0.001,-0.0393 -0.004,-0.0786 -0.005,-0.11789 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d38d5f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5538-5"
|
||||
d="m 349.49606,836.33762 c 9.75346,0 23.64321,12.16602 23.43637,26.91145 -26.77544,0.89278 -12.23382,16.59426 -54.45054,16.59426 -23.57775,-8.1e-4 -52.36301,-19.37568 -52.36241,-43.27513 10e-4,-0.0393 0.004,-0.0786 0.005,-0.11789 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g4404"
|
||||
transform="matrix(1.0166163,0,0,1.0304866,-12.543356,-24.305675)"
|
||||
style="stroke:none;filter:url(#filter5095)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect4160"
|
||||
d="m 255.89286,880.36219 5.82421,-0.13837 18.004,70.01981 -23.64731,0.11856 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect4160-0"
|
||||
d="m 255.94643,880.36219 c -4.61559,1.13878 -6.93068,3.5072 -8.38698,6.84881 -9.11992,20.92646 -30.50667,62.87939 8.38498,63.15119 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffcfcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g4673"
|
||||
style="filter:url(#filter4682)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5513"
|
||||
d="m 247.71042,792.74395 0,32.00949 97.94463,0 0,-32.00949 -97.94463,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5516"
|
||||
d="m 247.71042,792.74395 -97.94463,0 0,32.00949 97.94463,0 0,-32.00949 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
id="path5432"
|
||||
d="m 256.47476,549.80506 c -2.93079,0.0237 -5.85751,0.22598 -8.76434,0.60581 -0.0277,65.61462 0,171.31359 0,246.9062 l 102.82518,0 0,-51.59276 c 0.34138,-2.19919 0.64564,-4.39387 0.82997,-6.13864 l 0.74658,-7.06246 6.41143,-2.55609 6.41143,-2.5581 9.34811,7.55758 c 5.14171,4.15711 10.34711,7.56009 11.56798,7.56361 3.05362,0.0103 24.90114,-22.4949 24.90114,-25.64946 0,-1.33375 -3.32577,-6.68709 -7.38833,-11.89487 l -7.38636,-9.4676 2.32909,-5.44225 c 1.28072,-2.99325 2.66205,-5.81504 3.06771,-6.26947 0.40565,-0.45443 6.4466,-1.77039 13.4245,-2.92441 l 12.68785,-2.09721 0.31968,-17.45587 c 0.19141,-10.42474 -0.1393,-17.92314 -0.82203,-18.61518 -0.62875,-0.63732 -6.64398,-1.99532 -13.36493,-3.01699 l -12.21726,-1.85568 -2.69443,-6.71426 -2.69047,-6.71226 7.36849,-9.55615 c 4.05209,-5.256 7.36649,-10.33897 7.36649,-11.2951 0,-2.04511 -22.89779,-25.96343 -24.85547,-25.96343 -0.73476,0 -5.85983,3.4567 -11.38928,7.68437 l -10.05298,7.6884 -6.15927,-2.5883 -5.96467,-2.50376 c -0.0655,-0.0303 -0.13101,-0.0605 -0.19658,-0.0906 l -1.89623,-12.34168 c -1.04342,-6.79095 -2.4584,-13.03053 -3.14516,-13.86931 -0.96141,-1.17423 -9.08067,-1.71556 -17.20305,-1.66447 -8.12235,0.0511 -16.24958,0.69142 -17.22093,1.87782 -0.69477,0.84854 -1.89525,5.90378 -2.8493,11.68555 -13.78021,-15.03842 -33.09617,-23.61037 -53.34456,-23.67301 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccscccscccscccccsscccccssscccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5490"
|
||||
d="m 247.71042,819.17836 0,16.911 102.82518,0 0,-16.911 -102.82518,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5488"
|
||||
d="m 247.71042,550.41054 a 73.110297,74.107784 0 0 0 -50.24705,29.88411 73.110297,74.107784 0 0 0 -24.78797,-4.48825 73.110297,74.107784 0 0 0 -73.109015,74.10849 73.110297,74.107784 0 0 0 44.891955,68.35225 l 0,79.0496 103.25208,0 0,-246.9062 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5492"
|
||||
d="m 247.71042,819.17836 -103.25208,0 0,16.911 103.25208,0 0,-16.911 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4473-2"
|
||||
d="m 145.97025,816.61919 204.28572,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 35 KiB |
BIN
src/web/static/images/logo/cyberchef_512.png
Executable file
After Width: | Height: | Size: 38 KiB |
754
src/web/static/images/logo/cyberchef_banner.svg
Executable file
@ -0,0 +1,754 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1692.6885"
|
||||
height="582.38904"
|
||||
viewBox="0 0 1692.6884 582.38903"
|
||||
id="svg4819"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cyberchef_banner.svg"
|
||||
inkscape:export-xdpi="79.75"
|
||||
inkscape:export-ydpi="79.75">
|
||||
<defs
|
||||
id="defs4821">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4392">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4394" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4396" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4398" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-2.47025e-015"
|
||||
result="offset"
|
||||
id="feOffset4400" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4402" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4576">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4578" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4580" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4582" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4584" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4586" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4588">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4590" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4592" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4594" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4596" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4598" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4608">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4610" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4612" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4614" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4616" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4618" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4620">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4622" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4624" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4626" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4628" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4630" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4736">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4738" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4740" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4742" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4744" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4746" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4784">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4786" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4788" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4790" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="2"
|
||||
result="offset"
|
||||
id="feOffset4792" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4794" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4830">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4832" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4834" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4836" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4838" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4840" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4842">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4844" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4846" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4848" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4850" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4852" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4637">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4639" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4641" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4643" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset4645" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4647" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4649">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4651" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4653" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4655" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4657" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4659" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4661">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4663" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4665" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4667" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4669" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4671" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4682">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4684" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4686" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4688" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4690" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4692" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4694">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4696" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4698" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4700" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4702" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4704" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4879">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4881" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4883" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="2"
|
||||
result="blur"
|
||||
id="feGaussianBlur4885" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4887" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4889" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5095">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5097" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5099" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur5101" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5103" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5105" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="501.53482"
|
||||
inkscape:cy="239.41965"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1138"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="40"
|
||||
fit-margin-bottom="40" />
|
||||
<metadata
|
||||
id="metadata4824">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-56.737013,-521.1766)">
|
||||
<circle
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-0"
|
||||
cx="203.00006"
|
||||
cy="871.01947"
|
||||
r="0" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#a05a2c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4661);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 147.26218,836.04571 c -25.20823,-0.10755 -39.52686,29.07087 -38.48314,49.6054 -50.615937,46.28423 -16.205613,107.16245 37.64298,108.72598 32.0833,-1.5e-4 42.68786,-30.52742 42.68801,-63.04845 -0.0198,-17.82216 -8.00167,-34.67629 -21.70832,-45.83854 1.05039,-3.56483 1.5874,-7.26473 1.59442,-10.98515 0,-21.34208 -0.67913,-38.45924 -21.73395,-38.45924 z"
|
||||
id="path5533"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#666666;stroke:none;filter:url(#filter4649)"
|
||||
d="m 329.75057,848.9372 -0.99384,5.44742 c -0.54665,2.99618 -1.51544,9.1802 -2.15123,13.74049 -0.96309,6.90853 -2.0091,8.79753 -6.28134,11.3267 -4.99839,2.95911 -5.3259,2.94503 -13.05113,-0.51884 -17.00524,-7.62485 -16.50462,-7.73628 -24.18511,5.36828 -0.83958,1.43242 -1.5755,2.69215 -2.21413,3.80274 -4.47081,7.77361 -4.19222,8.34457 -1.54404,11.31067 1.69375,1.89713 6.44342,5.94635 10.55236,9.00298 6.60433,4.91288 7.45215,6.27116 7.30351,11.70885 -0.14851,5.43242 -1.3543,7.12566 -10.33319,14.48994 -5.59176,4.58626 -10.1684,8.74733 -10.16843,9.24712 -2e-5,1.6752 11.82228,22.36426 13.3138,23.29861 0.81025,0.50761 6.89179,-1.29426 13.51104,-4.00793 11.69561,-4.79479 12.17517,-4.8546 16.98848,-2.07698 4.0965,2.36394 5.15278,4.28857 6.10882,11.14635 0.6358,4.56033 1.60491,10.74732 2.1515,13.74346 l 0.99533,5.44345 13.89887,-1.1e-4 13.90372,0 1.72092,-6.28433 c 0.94717,-3.45714 1.73487,-8.17143 1.75242,-10.47619 0.0565,-7.42942 1.72011,-10.87992 6.61533,-13.72769 4.61835,-2.68631 5.20277,-2.61426 16.03306,2.06875 6.18176,2.67299 12.00889,4.88209 12.94949,4.90711 0.94061,0.025 4.43989,-4.67108 7.77519,-10.43288 3.33531,-5.76188 6.078,-11.60524 6.09452,-12.98806 0.0166,-1.38282 -4.3658,-5.90842 -9.74023,-10.05691 -8.71341,-6.72592 -9.78365,-8.20675 -9.87259,-13.6679 -0.0899,-5.51114 0.89302,-6.93673 9.81558,-14.24623 5.45348,-4.46763 9.91683,-9.15506 9.92014,-10.41728 0.006,-1.70693 -8.94144,-18.4331 -12.49772,-23.36766 -0.2065,-0.2861 -6.15615,1.75011 -13.22574,4.53279 -12.27748,4.83246 -13.0599,4.94274 -17.42196,2.33088 -4.67438,-2.79905 -6.3909,-6.49185 -6.44709,-13.88872 -0.0176,-2.30473 -0.80397,-7.0164 -1.75108,-10.47347 l -1.72259,-6.28557 -13.90368,-0.002 -13.89894,1.7e-4 z m 8.33566,50.05554 a 21.565918,21.860154 0 0 1 26.41031,15.4593 21.565918,21.860154 0 0 1 -15.24637,26.77349 21.565918,21.860154 0 0 1 -26.41413,-15.4583 21.565918,21.860154 0 0 1 15.25019,-26.77449 z"
|
||||
id="path5680-4" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect4178"
|
||||
width="80.357857"
|
||||
height="21.07921"
|
||||
x="182.31805"
|
||||
y="965.93365" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#de8787;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 248.10536,1013.0243 0.0735,6e-4 0.27913,-33.12148 -0.0735,-6.2e-4 -0.0549,6.51764 -66.53394,-0.61382 c 18.2854,10.09362 31.55974,25.45918 66.38614,18.15098 z"
|
||||
id="path6299"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 247.7409,975.65034 58.09206,-0.65817 c 0.3574,12.17742 -35.60705,22.20893 -58.09206,23.00293 z"
|
||||
id="rect5437-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<g
|
||||
id="g4814"
|
||||
transform="matrix(1.0166163,0,0,1.0304866,-12.543356,-24.305675)"
|
||||
style="stroke:none;filter:url(#filter4694)">
|
||||
<path
|
||||
id="path5473"
|
||||
transform="translate(0,540.36219)"
|
||||
d="m 256,294.35938 0,136.21289 0.0293,0 0,-0.5625 57.14258,-0.63868 c 0.35133,11.80977 -34.97938,21.53912 -57.09961,22.32032 l 0,11.02343 -0.0723,0 0,32.51368 c 35.99476,0.4041 68.91204,-13.70201 99.9375,-36.72461 l 0,-164.14453 -99.9375,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5437"
|
||||
d="m 256,834.72124 0,135.93276 -57.14285,0.17857 c 4.80435,15.52459 35.24626,22.13924 57.14285,21.25 l 0,43.50783 c -30.78963,-0.3457 -63.82206,-11.2715 -99.9375,-36.72463 l 0,-164.14453 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffe1e1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-1"
|
||||
cx="196.15344"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path6225-7"
|
||||
cx="204.14046"
|
||||
cy="882.65778"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1fdf1f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5"
|
||||
cx="294.18433"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path6225"
|
||||
cx="300.96732"
|
||||
cy="882.12958"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<g
|
||||
id="g4743"
|
||||
style="filter:url(#filter4879)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5538"
|
||||
d="m 149.12011,835.91605 c -9.75347,0 -23.64321,12.16601 -23.43637,26.91145 26.77544,0.89277 12.23382,16.59426 54.45054,16.59426 23.57775,-8.2e-4 52.36301,-19.37569 52.36241,-43.27513 -0.001,-0.0393 -0.004,-0.0786 -0.005,-0.11789 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d38d5f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5538-5"
|
||||
d="m 349.49606,836.33762 c 9.75346,0 23.64321,12.16602 23.43637,26.91145 -26.77544,0.89278 -12.23382,16.59426 -54.45054,16.59426 -23.57775,-8.1e-4 -52.36301,-19.37568 -52.36241,-43.27513 10e-4,-0.0393 0.004,-0.0786 0.005,-0.11789 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g4404"
|
||||
transform="matrix(1.0166163,0,0,1.0304866,-12.543356,-24.305675)"
|
||||
style="stroke:none;filter:url(#filter5095)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect4160"
|
||||
d="m 255.89286,880.36219 5.82421,-0.13837 18.004,70.01981 -23.64731,0.11856 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect4160-0"
|
||||
d="m 255.94643,880.36219 c -4.61559,1.13878 -6.93068,3.5072 -8.38698,6.84881 -9.11992,20.92646 -30.50667,62.87939 8.38498,63.15119 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffcfcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g4673"
|
||||
style="filter:url(#filter4682)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5513"
|
||||
d="m 247.71042,792.74395 0,32.00949 97.94463,0 0,-32.00949 -97.94463,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5516"
|
||||
d="m 247.71042,792.74395 -97.94463,0 0,32.00949 97.94463,0 0,-32.00949 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
id="path5432"
|
||||
d="m 256.47476,549.80506 c -2.93079,0.0237 -5.85751,0.22598 -8.76434,0.60581 -0.0277,65.61462 0,171.31359 0,246.9062 l 102.82518,0 0,-51.59276 c 0.34138,-2.19919 0.64564,-4.39387 0.82997,-6.13864 l 0.74658,-7.06246 6.41143,-2.55609 6.41143,-2.5581 9.34811,7.55758 c 5.14171,4.15711 10.34711,7.56009 11.56798,7.56361 3.05362,0.0103 24.90114,-22.4949 24.90114,-25.64946 0,-1.33375 -3.32577,-6.68709 -7.38833,-11.89487 l -7.38636,-9.4676 2.32909,-5.44225 c 1.28072,-2.99325 2.66205,-5.81504 3.06771,-6.26947 0.40565,-0.45443 6.4466,-1.77039 13.4245,-2.92441 l 12.68785,-2.09721 0.31968,-17.45587 c 0.19141,-10.42474 -0.1393,-17.92314 -0.82203,-18.61518 -0.62875,-0.63732 -6.64398,-1.99532 -13.36493,-3.01699 l -12.21726,-1.85568 -2.69443,-6.71426 -2.69047,-6.71226 7.36849,-9.55615 c 4.05209,-5.256 7.36649,-10.33897 7.36649,-11.2951 0,-2.04511 -22.89779,-25.96343 -24.85547,-25.96343 -0.73476,0 -5.85983,3.4567 -11.38928,7.68437 l -10.05298,7.6884 -6.15927,-2.5883 -5.96467,-2.50376 c -0.0655,-0.0303 -0.13101,-0.0605 -0.19658,-0.0906 l -1.89623,-12.34168 c -1.04342,-6.79095 -2.4584,-13.03053 -3.14516,-13.86931 -0.96141,-1.17423 -9.08067,-1.71556 -17.20305,-1.66447 -8.12235,0.0511 -16.24958,0.69142 -17.22093,1.87782 -0.69477,0.84854 -1.89525,5.90378 -2.8493,11.68555 -13.78021,-15.03842 -33.09617,-23.61037 -53.34456,-23.67301 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccscccscccscccccsscccccssscccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5490"
|
||||
d="m 247.71042,819.17836 0,16.911 102.82518,0 0,-16.911 -102.82518,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5488"
|
||||
d="m 247.71042,550.41054 a 73.110297,74.107784 0 0 0 -50.24705,29.88411 73.110297,74.107784 0 0 0 -24.78797,-4.48825 73.110297,74.107784 0 0 0 -73.109015,74.10849 73.110297,74.107784 0 0 0 44.891955,68.35225 l 0,79.0496 103.25208,0 0,-246.9062 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5492"
|
||||
d="m 247.71042,819.17836 -103.25208,0 0,16.911 103.25208,0 0,-16.911 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4473-2"
|
||||
d="m 145.97025,816.61919 204.28572,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:166.50489807px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#666666;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="1079.7885"
|
||||
y="1003.4395"
|
||||
id="text4733"
|
||||
sodipodi:linespacing="125%"
|
||||
inkscape:export-xdpi="79.75"
|
||||
inkscape:export-ydpi="79.75"><tspan
|
||||
sodipodi:role="line"
|
||||
x="1079.7885"
|
||||
y="1003.4395"
|
||||
id="tspan4735"
|
||||
style="font-weight:bold"><tspan
|
||||
x="1079.7885"
|
||||
y="1003.4395"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:249.75732422px;line-height:125%;font-family:Consolas;-inkscape-font-specification:'Consolas, Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#666666"
|
||||
id="tspan4737">CyberChef</tspan></tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 36 KiB |
BIN
src/web/static/images/logo/cyberchef_banner_1500.png
Executable file
After Width: | Height: | Size: 60 KiB |
146
src/web/static/images/logo/cyberchef_hat.svg
Executable file
@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="400"
|
||||
height="400"
|
||||
viewBox="0 0 400 399.99999"
|
||||
id="svg4819"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cyberchef_hat.svg"
|
||||
inkscape:export-xdpi="337.5"
|
||||
inkscape:export-ydpi="337.5">
|
||||
<defs
|
||||
id="defs4821">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4682">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4684" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4686" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4688" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4690" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4692" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="40.62369"
|
||||
inkscape:cy="206.8588"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1138"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-page="false"
|
||||
showguides="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata4824">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-61.812519,-579.37011)">
|
||||
<circle
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-0"
|
||||
cx="209.06097"
|
||||
cy="843.2403"
|
||||
r="0" />
|
||||
<g
|
||||
id="g4673"
|
||||
style="filter:url(#filter4682)"
|
||||
transform="translate(5.1770318,2.0203049)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5513"
|
||||
d="m 243.66981,877.59676 0,32.00949 97.94463,0 0,-32.00949 -97.94463,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5516"
|
||||
d="m 243.66981,877.59676 -97.94463,0 0,32.00949 97.94463,0 0,-32.00949 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
id="path5432"
|
||||
d="m 252.43415,634.65787 c -2.93079,0.0237 -5.85751,0.22598 -8.76434,0.60581 2.9e-4,92.54556 0,151.78177 0,246.9062 l 102.82518,0 0,-51.59276 c 0.34138,-2.19919 0.64564,-4.39387 0.82997,-6.13864 l 0.74658,-7.06246 6.41143,-2.55609 6.41143,-2.5581 9.34811,7.55758 c 5.14171,4.15711 10.34711,7.56009 11.56798,7.56361 3.05362,0.0103 24.90114,-22.4949 24.90114,-25.64946 0,-1.33375 -3.32577,-6.68709 -7.38833,-11.89487 l -7.38636,-9.4676 2.32909,-5.44225 c 1.28072,-2.99325 2.66205,-5.81504 3.06771,-6.26947 0.40565,-0.45443 6.4466,-1.77039 13.4245,-2.92441 l 12.68785,-2.09721 0.31968,-17.45587 c 0.19141,-10.42474 -0.1393,-17.92314 -0.82203,-18.61518 -0.62875,-0.63732 -6.64398,-1.99532 -13.36493,-3.01699 l -12.21726,-1.85568 -2.69443,-6.71426 -2.69047,-6.71226 7.36849,-9.55615 c 4.05209,-5.256 7.36649,-10.33897 7.36649,-11.2951 0,-2.04511 -22.89779,-25.96343 -24.85547,-25.96343 -0.73476,0 -5.85983,3.4567 -11.38928,7.68437 l -10.05298,7.6884 -6.15927,-2.5883 -5.96467,-2.50376 c -0.0655,-0.0303 -0.13101,-0.0605 -0.19658,-0.0906 l -1.89623,-12.34168 c -1.04342,-6.79095 -2.4584,-13.03053 -3.14516,-13.86931 -0.96141,-1.17423 -9.08067,-1.71556 -17.20305,-1.66447 -8.12235,0.0511 -16.24958,0.69142 -17.22093,1.87782 -0.69477,0.84854 -1.89525,5.90378 -2.8493,11.68555 -13.78021,-15.03842 -33.09617,-23.61037 -53.34456,-23.67301 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccscccscccscccccsscccccssscccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5490"
|
||||
d="m 243.66981,904.03117 0,16.911 102.82518,0 0,-16.911 -102.82518,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5488"
|
||||
d="m 243.66981,635.26335 a 73.110297,74.107784 0 0 0 -50.24705,29.88411 73.110297,74.107784 0 0 0 -24.78797,-4.48825 73.110297,74.107784 0 0 0 -73.109015,74.10849 73.110297,74.107784 0 0 0 44.891955,68.35225 l 0,79.0496 103.25208,0 0,-246.9062 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5492"
|
||||
d="m 243.66981,904.03117 -103.25208,0 0,16.911 103.25208,0 0,-16.911 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4473-2"
|
||||
d="m 141.92964,901.472 204.28572,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.4 KiB |
BIN
src/web/static/images/logo/cyberchef_hat_512.png
Executable file
After Width: | Height: | Size: 20 KiB |
BIN
src/web/static/images/logo/cyberchef_hat_text_512.png
Executable file
After Width: | Height: | Size: 29 KiB |
1157
src/web/static/images/logo/cyberchef_human.svg
Executable file
After Width: | Height: | Size: 44 KiB |
833
src/web/static/images/logo/cyberchef_robot.svg
Executable file
@ -0,0 +1,833 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 511.99999 511.99999"
|
||||
id="svg4819"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cyberchef_robot.svg"
|
||||
inkscape:export-xdpi="263.67001"
|
||||
inkscape:export-ydpi="263.67001">
|
||||
<defs
|
||||
id="defs4821">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4392">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4394" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4396" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4398" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-2.47025e-015"
|
||||
result="offset"
|
||||
id="feOffset4400" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4402" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4576">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4578" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4580" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4582" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4584" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4586" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4588">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4590" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4592" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4594" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4596" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4598" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4608">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4610" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4612" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4614" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4616" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4618" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4620">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4622" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4624" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4626" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4628" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4630" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4736">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4738" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4740" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4742" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4744" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4746" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4784">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4786" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4788" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur4790" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="2"
|
||||
result="offset"
|
||||
id="feOffset4792" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4794" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4830">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4832" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4834" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4836" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4838" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4840" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4842">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4844" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4846" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4848" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="-6.38378e-016"
|
||||
result="offset"
|
||||
id="feOffset4850" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4852" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4637">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4639" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4641" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4643" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset4645" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4647" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4649">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4651" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4653" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4655" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4657" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4659" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4661">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4663" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4665" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4667" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4669" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4671" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4682">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4684" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4686" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4688" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4690" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4692" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4694">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4696" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4698" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur4700" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4702" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4704" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4879">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4881" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4883" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="2"
|
||||
result="blur"
|
||||
id="feGaussianBlur4885" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="0.7"
|
||||
result="offset"
|
||||
id="feOffset4887" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4889" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5095">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5097" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5099" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur5101" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5103" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5105" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5936">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5938" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5940" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur5942" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5944" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5946" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5948">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5950" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5952" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur5954" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5956" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5958" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5960">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5962" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5964" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur5966" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5968" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5970" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5972">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5974" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5976" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="5"
|
||||
result="blur"
|
||||
id="feGaussianBlur5978" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5980" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5982" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter5984">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood5986" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite5988" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="3"
|
||||
result="blur"
|
||||
id="feGaussianBlur5990" />
|
||||
<feOffset
|
||||
dx="1.34615e-014"
|
||||
dy="1"
|
||||
result="offset"
|
||||
id="feOffset5992" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite5994" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="254.96332"
|
||||
inkscape:cy="312.82202"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1138"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4824">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-540.36219)">
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 171.63281,974.99305 c -0.47362,12.46697 44.5914,22.83842 76.10742,24.64037 l 0,0.23658 c 0.70013,-0.0267 1.44907,-0.0914 2.17383,-0.1373 1.01469,0.0459 2.06277,0.11056 3.04297,0.1373 l 0,-0.36965 c 22.41538,-2.12681 53.20592,-12.31299 52.875,-24.5073 l -55.91797,0.68439 -78.28125,-0.68439 z"
|
||||
id="rect5437-2-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#666666;stroke:none;filter:url(#filter5948)"
|
||||
d="m 329.75057,848.9372 -0.99384,5.44742 c -0.54665,2.99618 -1.51544,9.1802 -2.15123,13.74049 -0.96309,6.90853 -2.0091,8.79753 -6.28134,11.3267 -4.99839,2.95911 -5.3259,2.94503 -13.05113,-0.51884 -17.00524,-7.62485 -16.50462,-7.73628 -24.18511,5.36828 -0.83958,1.43242 -1.5755,2.69215 -2.21413,3.80274 -4.47081,7.77361 -4.19222,8.34457 -1.54404,11.31067 1.69375,1.89713 6.44342,5.94635 10.55236,9.00298 6.60433,4.91288 7.45215,6.27116 7.30351,11.70885 -0.14851,5.43242 -1.3543,7.12566 -10.33319,14.48994 -5.59176,4.58626 -10.1684,8.74733 -10.16843,9.24712 -2e-5,1.6752 11.82228,22.36426 13.3138,23.29861 0.81025,0.50761 6.89179,-1.29426 13.51104,-4.00793 11.69561,-4.79479 12.17517,-4.8546 16.98848,-2.07698 4.0965,2.36394 5.15278,4.28857 6.10882,11.14635 0.6358,4.56033 1.60491,10.74732 2.1515,13.74346 l 0.99533,5.44345 13.89887,-1.1e-4 13.90372,0 1.72092,-6.28433 c 0.94717,-3.45714 1.73487,-8.17143 1.75242,-10.47619 0.0565,-7.42942 1.72011,-10.87992 6.61533,-13.72769 4.61835,-2.68631 5.20277,-2.61426 16.03306,2.06875 6.18176,2.67299 12.00889,4.88209 12.94949,4.90711 0.94061,0.025 4.43989,-4.67108 7.77519,-10.43288 3.33531,-5.76188 6.078,-11.60524 6.09452,-12.98806 0.0166,-1.38282 -4.3658,-5.90842 -9.74023,-10.05691 -8.71341,-6.72592 -9.78365,-8.20675 -9.87259,-13.6679 -0.0899,-5.51114 0.89302,-6.93673 9.81558,-14.24623 5.45348,-4.46763 9.91683,-9.15506 9.92014,-10.41728 0.006,-1.70693 -8.94144,-18.4331 -12.49772,-23.36766 -0.2065,-0.2861 -6.15615,1.75011 -13.22574,4.53279 -12.27748,4.83246 -13.0599,4.94274 -17.42196,2.33088 -4.67438,-2.79905 -6.3909,-6.49185 -6.44709,-13.88872 -0.0176,-2.30473 -0.80397,-7.0164 -1.75108,-10.47347 l -1.72259,-6.28557 -13.90368,-0.002 -13.89894,1.7e-4 z m 8.33566,50.05554 a 21.565918,21.860154 0 0 1 26.41031,15.4593 21.565918,21.860154 0 0 1 -15.24637,26.77349 21.565918,21.860154 0 0 1 -26.41413,-15.4583 21.565918,21.860154 0 0 1 15.25019,-26.77449 z"
|
||||
id="path5680-4" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#666666;stroke:none;filter:url(#filter5972)"
|
||||
d="m 165.89597,848.9372 0.99384,5.44742 c 0.54665,2.99618 1.51544,9.1802 2.15123,13.74049 0.96309,6.90853 2.0091,8.79753 6.28134,11.3267 4.99839,2.95911 5.3259,2.94503 13.05113,-0.51884 17.00524,-7.62485 16.50462,-7.73628 24.18511,5.36828 0.83958,1.43242 1.5755,2.69215 2.21413,3.80274 4.47081,7.77361 4.19222,8.34457 1.54404,11.31067 -1.69375,1.89713 -6.44342,5.94635 -10.55236,9.00298 -6.60433,4.91288 -7.45215,6.27116 -7.30351,11.70885 0.14851,5.43242 1.3543,7.12566 10.33319,14.48994 5.59176,4.58626 10.1684,8.74733 10.16843,9.24712 2e-5,1.6752 -11.82228,22.36426 -13.3138,23.29861 -0.81025,0.50761 -6.89179,-1.29426 -13.51104,-4.00793 -11.69561,-4.79479 -12.17517,-4.8546 -16.98848,-2.07698 -4.0965,2.36394 -5.15278,4.28857 -6.10882,11.14635 -0.6358,4.56033 -1.60491,10.74732 -2.1515,13.74346 l -0.99533,5.44345 -13.89887,-1.1e-4 -13.90372,0 -1.72092,-6.28433 c -0.94717,-3.45714 -1.73487,-8.17143 -1.75242,-10.47619 -0.0565,-7.42942 -1.72011,-10.87992 -6.61533,-13.72769 -4.61835,-2.68631 -5.20277,-2.61426 -16.03306,2.06875 -6.18176,2.67299 -12.00889,4.88209 -12.94949,4.90711 -0.94061,0.025 -4.43989,-4.67108 -7.77519,-10.43288 -3.33531,-5.76188 -6.078,-11.60524 -6.09452,-12.98806 -0.0166,-1.38282 4.3658,-5.90842 9.74023,-10.05691 8.71341,-6.72592 9.78365,-8.20675 9.87259,-13.6679 0.0899,-5.51114 -0.89302,-6.93673 -9.81558,-14.24623 -5.45348,-4.46763 -9.91683,-9.15506 -9.92014,-10.41728 -0.006,-1.70693 8.94144,-18.4331 12.49772,-23.36766 0.2065,-0.2861 6.15615,1.75011 13.22574,4.53279 12.27748,4.83246 13.0599,4.94274 17.42196,2.33088 4.67438,-2.79905 6.3909,-6.49185 6.44709,-13.88872 0.0176,-2.30473 0.80397,-7.0164 1.75108,-10.47347 l 1.72259,-6.28557 13.90368,-0.002 13.89894,1.7e-4 z m -8.33566,50.05554 a 21.565918,21.860154 0 0 0 -26.41031,15.4593 21.565918,21.860154 0 0 0 15.24637,26.77349 21.565918,21.860154 0 0 0 26.41413,-15.4583 21.565918,21.860154 0 0 0 -15.25019,-26.77449 z"
|
||||
id="path5680-4-6" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;filter:url(#filter5960)"
|
||||
d="M 146.33789 295.50195 L 146.33789 464.65039 C 177.81414 488.3261 211.20599 502.84856 247.71094 502.49414 C 247.78601 502.49341 247.86044 502.495 247.93555 502.49414 C 284.44054 502.84851 317.8323 488.32621 349.30859 464.65039 L 349.30859 295.50195 L 247.93555 295.50195 L 247.71094 295.50195 L 146.33789 295.50195 z M 189.81445 434.62891 L 247.71094 435.28516 L 247.71094 435.86719 L 247.74023 435.86719 L 247.74023 435.28711 L 247.82422 435.28711 L 247.90625 435.28711 L 247.90625 435.86719 L 247.93555 435.86719 L 247.93555 435.28516 L 305.83203 434.62891 C 306.18899 446.79157 270.31455 456.81354 247.82422 457.62891 C 225.33401 456.81403 189.45749 446.79191 189.81445 434.62891 z "
|
||||
transform="translate(0,540.36219)"
|
||||
id="path5473-7" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-0"
|
||||
cx="203.00006"
|
||||
cy="871.01947"
|
||||
r="14.964106" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1fdf1f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;"
|
||||
id="path5494-5"
|
||||
cx="294.18433"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;"
|
||||
id="path6225"
|
||||
cx="300.96732"
|
||||
cy="882.12958"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 349.49606,836.33762 c 9.75346,0 23.64321,12.16602 23.43637,26.91145 -26.77544,0.89278 -12.23382,16.59426 -54.45054,16.59426 -23.57775,-8.1e-4 -52.36301,-19.37568 -52.36241,-43.27513 10e-4,-0.0393 0.004,-0.0786 0.005,-0.11789 z"
|
||||
id="path5538-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;filter:url(#filter5984)"
|
||||
d="M 242.125 342.39062 L 223.82031 414.54492 L 247.78516 414.66797 L 247.86133 414.66797 L 271.82617 414.54492 L 253.52344 342.39062 L 247.82422 342.52734 L 242.125 342.39062 z "
|
||||
transform="translate(0,540.36219)"
|
||||
id="rect4160" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1fdf1f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path5494-5-8"
|
||||
cx="201.46222"
|
||||
cy="887.901"
|
||||
rx="18.238831"
|
||||
ry="18.487673" />
|
||||
<ellipse
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.60587597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="path6225-3"
|
||||
cx="208.24521"
|
||||
cy="882.12958"
|
||||
rx="5.7431631"
|
||||
ry="5.8215208" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.9000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 146.15048,836.33762 c -9.75346,0 -23.64321,12.16602 -23.43637,26.91145 26.77544,0.89278 12.23382,16.59426 54.45054,16.59426 23.57775,-8.1e-4 52.36301,-19.37568 52.36241,-43.27513 -0.001,-0.0393 -0.004,-0.0786 -0.005,-0.11789 z"
|
||||
id="path5538-5-0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<g
|
||||
id="g5929"
|
||||
style="filter:url(#filter5936)">
|
||||
<path
|
||||
id="rect5513"
|
||||
transform="translate(0,540.36219)"
|
||||
d="M 149.99219 252.38086 L 149.99219 284.39062 L 247.71094 284.39062 L 247.93555 284.39062 L 345.6543 284.39062 L 345.6543 252.38086 L 247.93555 252.38086 L 247.71094 252.38086 L 149.99219 252.38086 z "
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
id="path5432"
|
||||
transform="translate(0,540.36219)"
|
||||
d="M 239.17188 9.4433594 A 73.110297 74.107784 0 0 0 185.82812 33.115234 C 184.87407 27.333464 183.67329 22.278227 182.97852 21.429688 C 182.00717 20.243287 173.88016 19.603834 165.75781 19.552734 C 157.63543 19.501644 149.5161 20.042567 148.55469 21.216797 C 147.86793 22.055577 146.45162 28.294988 145.4082 35.085938 L 143.51172 47.427734 A 73.110297 74.107784 0 0 0 143.31641 47.517578 L 137.35156 50.021484 L 131.19141 52.611328 L 121.13867 44.921875 C 115.60922 40.694205 110.48476 37.238281 109.75 37.238281 C 107.79232 37.238281 84.894531 61.156062 84.894531 63.201172 C 84.894531 64.157302 88.209629 69.240094 92.261719 74.496094 L 99.628906 84.052734 L 96.939453 90.765625 L 94.244141 97.478516 L 82.027344 99.333984 C 75.306394 100.35565 69.290859 101.71424 68.662109 102.35156 C 67.979379 103.0436 67.648434 110.54206 67.839844 120.9668 L 68.160156 138.42188 L 80.847656 140.51953 C 87.825556 141.67355 93.865834 142.99088 94.271484 143.44531 C 94.677144 143.89974 96.059124 146.71964 97.339844 149.71289 L 99.669922 155.15625 L 92.283203 164.62305 C 88.220643 169.83083 84.894531 175.18578 84.894531 176.51953 C 84.894531 179.67409 106.7413 202.17827 109.79492 202.16797 C 111.01579 202.16445 116.22157 198.76063 121.36328 194.60352 L 130.71094 187.04688 L 137.12305 189.60547 L 143.53516 192.16016 L 144.28125 199.22266 C 144.46558 200.96743 144.76995 203.16214 145.11133 205.36133 L 145.11133 256.95508 L 247.71094 256.95508 L 247.93555 256.95508 L 350.53516 256.95508 L 350.53516 205.36133 C 350.87654 203.16214 351.1809 200.96743 351.36523 199.22266 L 352.11133 192.16016 L 358.52344 189.60547 L 364.93555 187.04688 L 374.2832 194.60352 C 379.42491 198.76063 384.63069 202.16445 385.85156 202.16797 C 388.90518 202.17827 410.75195 179.67409 410.75195 176.51953 C 410.75195 175.18578 407.42584 169.83083 403.36328 164.62305 L 395.97852 155.15625 L 398.30664 149.71289 C 399.58736 146.71964 400.96934 143.89974 401.375 143.44531 C 401.78065 142.99088 407.82093 141.67355 414.79883 140.51953 L 427.48633 138.42188 L 427.80664 120.9668 C 427.99805 110.54206 427.66711 103.0436 426.98438 102.35156 C 426.35562 101.71424 420.34009 100.35565 413.61914 99.333984 L 401.40234 97.478516 L 398.70703 90.765625 L 396.01758 84.052734 L 403.38672 74.496094 C 407.43881 69.240094 410.75195 64.157302 410.75195 63.201172 C 410.75195 61.156062 387.85416 37.238281 385.89648 37.238281 C 385.16172 37.238281 380.03726 40.694205 374.50781 44.921875 L 364.45508 52.611328 L 358.29492 50.021484 L 352.33008 47.517578 A 73.110297 74.107784 0 0 0 352.13477 47.427734 L 350.23828 35.085938 C 349.19486 28.294988 347.77856 22.055577 347.0918 21.216797 C 346.13039 20.042567 338.01105 19.501644 329.88867 19.552734 C 321.76632 19.603834 313.63932 20.243287 312.66797 21.429688 C 311.9732 22.278227 310.77241 27.333464 309.81836 33.115234 A 73.110297 74.107784 0 0 0 256.47461 9.4433594 A 73.110297 74.107784 0 0 0 247.82422 10.035156 A 73.110297 74.107784 0 0 0 239.17188 9.4433594 z "
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5490"
|
||||
d="m 247.71042,819.17836 0,16.911 102.82518,0 0,-16.911 -102.82518,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4473-2"
|
||||
d="m 145.97025,816.61919 204.28572,0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4682)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5490-5"
|
||||
d="m 247.93612,819.17836 0,16.911 -102.82518,0 0,-16.911 102.82518,0 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 37 KiB |
@ -1,4 +1,4 @@
|
||||
import Sitemap from "sitemap";
|
||||
import sm from "sitemap";
|
||||
import OperationConfig from "../../core/config/OperationConfig.json";
|
||||
|
||||
|
||||
@ -10,24 +10,25 @@ import OperationConfig from "../../core/config/OperationConfig.json";
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
const sitemap = Sitemap.createSitemap({
|
||||
const smStream = new sm.SitemapStream({
|
||||
hostname: "https://gchq.github.io/CyberChef",
|
||||
});
|
||||
|
||||
sitemap.add({
|
||||
smStream.write({
|
||||
url: "/",
|
||||
changefreq: "weekly",
|
||||
priority: 1.0
|
||||
});
|
||||
|
||||
for (const op in OperationConfig) {
|
||||
sitemap.add({
|
||||
smStream.write({
|
||||
url: `/?op=${encodeURIComponent(op)}`,
|
||||
changeFreq: "yearly",
|
||||
priority: 0.5
|
||||
});
|
||||
}
|
||||
smStream.end();
|
||||
|
||||
const xml = sitemap.toString();
|
||||
|
||||
console.log(xml); // eslint-disable-line no-console
|
||||
sm.streamToPromise(smStream).then(
|
||||
buffer => console.log(buffer.toString()) // eslint-disable-line no-console
|
||||
);
|
||||
|
@ -51,7 +51,6 @@ class RecipeWaiter {
|
||||
}
|
||||
}.bind(this),
|
||||
onSort: function(evt) {
|
||||
this.updateZIndices();
|
||||
if (evt.from.id === "rec-list") {
|
||||
document.dispatchEvent(this.manager.statechange);
|
||||
}
|
||||
@ -150,19 +149,6 @@ class RecipeWaiter {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the z-index property on each operation to make sure that operations higher in the list
|
||||
* have a higher index, meaning dropdowns are not hidden underneath subsequent operations.
|
||||
*/
|
||||
updateZIndices() {
|
||||
const operations = document.getElementById("rec-list").children;
|
||||
for (let i = 0; i < operations.length; i++) {
|
||||
const operation = operations[i];
|
||||
operation.style.zIndex = 100 + operations.length - i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for favourite dragover events.
|
||||
* If the element being dragged is an operation, displays a visual cue so that the user knows it can
|
||||
@ -480,7 +466,6 @@ class RecipeWaiter {
|
||||
log.debug(`'${e.target.querySelector(".op-title").textContent}' added to recipe`);
|
||||
|
||||
this.triggerArgEvents(e.target);
|
||||
this.updateZIndices();
|
||||
window.dispatchEvent(this.manager.statechange);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,10 @@ class SeasonalWaiter {
|
||||
// Konami code
|
||||
this.kkeys = [];
|
||||
window.addEventListener("keydown", this.konamiCodeListener.bind(this));
|
||||
|
||||
// CyberChef Challenge
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("43 6f 6e 67 72 61 74 75 6c 61 74 69 6f 6e 73 2c 20 79 6f 75 20 68 61 76 65 20 63 6f 6d 70 6c 65 74 65 64 20 43 79 62 65 72 43 68 65 66 20 63 68 61 6c 6c 65 6e 67 65 20 23 31 21 0a 0a 54 68 69 73 20 63 68 61 6c 6c 65 6e 67 65 20 65 78 70 6c 6f 72 65 64 20 68 65 78 61 64 65 63 69 6d 61 6c 20 65 6e 63 6f 64 69 6e 67 2e 20 54 6f 20 6c 65 61 72 6e 20 6d 6f 72 65 2c 20 76 69 73 69 74 20 77 69 6b 69 70 65 64 69 61 2e 6f 72 67 2f 77 69 6b 69 2f 48 65 78 61 64 65 63 69 6d 61 6c 2e 0a 0a 54 68 65 20 63 6f 64 65 20 66 6f 72 20 74 68 69 73 20 63 68 61 6c 6c 65 6e 67 65 20 69 73 20 39 64 34 63 62 63 65 66 2d 62 65 35 32 2d 34 37 35 31 2d 61 32 62 32 2d 38 33 33 38 65 36 34 30 39 34 31 36 20 28 6b 65 65 70 20 74 68 69 73 20 70 72 69 76 61 74 65 29 2e 0a 0a 54 68 65 20 6e 65 78 74 20 63 68 61 6c 6c 65 6e 67 65 20 63 61 6e 20 62 65 20 66 6f 75 6e 64 20 61 74 20 68 74 74 70 73 3a 2f 2f 70 61 73 74 65 62 69 6e 2e 63 6f 6d 2f 47 53 6e 54 41 6d 6b 56 2e");
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ class WindowWaiter {
|
||||
* focus is returned.
|
||||
*/
|
||||
windowBlur() {
|
||||
this.windowBlurTime = new Date().getTime();
|
||||
this.windowBlurTime = Date.now();
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ class WindowWaiter {
|
||||
* a long time and the browser has swapped out all its memory.
|
||||
*/
|
||||
windowFocus() {
|
||||
const unfocusedTime = new Date().getTime() - this.windowBlurTime;
|
||||
const unfocusedTime = Date.now() - this.windowBlurTime;
|
||||
if (unfocusedTime > 60000) {
|
||||
this.app.silentBake();
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ class WorkerWaiter {
|
||||
*/
|
||||
bakingComplete() {
|
||||
this.setBakingStatus(false);
|
||||
let duration = new Date().getTime() - this.bakeStartTime;
|
||||
let duration = Date.now() - this.bakeStartTime;
|
||||
duration = duration.toLocaleString() + "ms";
|
||||
const progress = this.getBakeProgress();
|
||||
|
||||
@ -489,7 +489,7 @@ class WorkerWaiter {
|
||||
bake(recipeConfig, options, progress, step) {
|
||||
this.setBakingStatus(true);
|
||||
this.manager.recipe.updateBreakpointIndicator(false);
|
||||
this.bakeStartTime = new Date().getTime();
|
||||
this.bakeStartTime = Date.now();
|
||||
this.bakeId++;
|
||||
this.recipeConfig = recipeConfig;
|
||||
this.options = options;
|
||||
|
@ -10,6 +10,8 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import Chef from "../../src/core/Chef.mjs";
|
||||
import Utils from "../../src/core/Utils.mjs";
|
||||
import cliProgress from "cli-progress";
|
||||
|
||||
/**
|
||||
* Object to store and run the list of tests.
|
||||
@ -47,68 +49,103 @@ class TestRegister {
|
||||
/**
|
||||
* Runs all the tests in the register.
|
||||
*/
|
||||
runTests () {
|
||||
console.log("Running tests...");
|
||||
return Promise.all(
|
||||
this.tests.map(function(test, i) {
|
||||
const chef = new Chef();
|
||||
async runTests () {
|
||||
const progBar = new cliProgress.SingleBar({
|
||||
format: formatter,
|
||||
stopOnComplete: true
|
||||
}, cliProgress.Presets.shades_classic);
|
||||
const testResults = [];
|
||||
|
||||
return chef.bake(
|
||||
test.input,
|
||||
test.recipeConfig,
|
||||
{},
|
||||
0,
|
||||
false
|
||||
).then(function(result) {
|
||||
const ret = {
|
||||
test: test,
|
||||
status: null,
|
||||
output: null,
|
||||
};
|
||||
console.log("Running operation tests...");
|
||||
progBar.start(this.tests.length, 0, {
|
||||
msg: "Setting up"
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
if (test.expectedError) {
|
||||
ret.status = "passing";
|
||||
} else {
|
||||
ret.status = "erroring";
|
||||
ret.output = result.error.displayStr;
|
||||
}
|
||||
} else {
|
||||
if (test.expectedError) {
|
||||
ret.status = "failing";
|
||||
ret.output = "Expected an error but did not receive one.";
|
||||
} else if (result.result === test.expectedOutput) {
|
||||
ret.status = "passing";
|
||||
} else if ("expectedMatch" in test && test.expectedMatch.test(result.result)) {
|
||||
ret.status = "passing";
|
||||
} else {
|
||||
ret.status = "failing";
|
||||
const expected = test.expectedOutput ? test.expectedOutput :
|
||||
test.expectedMatch ? test.expectedMatch.toString() : "unknown";
|
||||
ret.output = [
|
||||
"Expected",
|
||||
"\t" + expected.replace(/\n/g, "\n\t"),
|
||||
"Received",
|
||||
"\t" + result.result.replace(/\n/g, "\n\t"),
|
||||
].join("\n");
|
||||
}
|
||||
}
|
||||
for (const test of this.tests) {
|
||||
progBar.update(testResults.length, {
|
||||
msg: test.name
|
||||
});
|
||||
|
||||
return ret;
|
||||
});
|
||||
})
|
||||
);
|
||||
const chef = new Chef();
|
||||
const result = await chef.bake(
|
||||
test.input,
|
||||
test.recipeConfig,
|
||||
{},
|
||||
0,
|
||||
false
|
||||
);
|
||||
|
||||
const ret = {
|
||||
test: test,
|
||||
status: null,
|
||||
output: null,
|
||||
duration: result.duration
|
||||
};
|
||||
|
||||
if (result.error) {
|
||||
if (test.expectedError) {
|
||||
ret.status = "passing";
|
||||
} else {
|
||||
ret.status = "erroring";
|
||||
ret.output = result.error.displayStr;
|
||||
}
|
||||
} else {
|
||||
if (test.expectedError) {
|
||||
ret.status = "failing";
|
||||
ret.output = "Expected an error but did not receive one.";
|
||||
} else if (result.result === test.expectedOutput) {
|
||||
ret.status = "passing";
|
||||
} else if ("expectedMatch" in test && test.expectedMatch.test(result.result)) {
|
||||
ret.status = "passing";
|
||||
} else if ("unexpectedMatch" in test && !test.unexpectedMatch.test(result.result)) {
|
||||
ret.status = "passing";
|
||||
} else {
|
||||
ret.status = "failing";
|
||||
const expected = test.expectedOutput ? test.expectedOutput :
|
||||
test.expectedMatch ? test.expectedMatch.toString() :
|
||||
test.unexpectedMatch ? "to not find " + test.unexpectedMatch.toString() :
|
||||
"unknown";
|
||||
ret.output = [
|
||||
"Expected",
|
||||
"\t" + expected.replace(/\n/g, "\n\t"),
|
||||
"Received",
|
||||
"\t" + result.result.replace(/\n/g, "\n\t"),
|
||||
].join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
testResults.push(ret);
|
||||
progBar.increment();
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all api related tests and wrap results in report format
|
||||
*/
|
||||
runApiTests() {
|
||||
return Promise.all(this.apiTests.map(async function(test, i) {
|
||||
async runApiTests() {
|
||||
const progBar = new cliProgress.SingleBar({
|
||||
format: formatter,
|
||||
stopOnComplete: true
|
||||
}, cliProgress.Presets.shades_classic);
|
||||
const testResults = [];
|
||||
|
||||
console.log("Running Node API tests...");
|
||||
progBar.start(this.apiTests.length, 0, {
|
||||
msg: "Setting up"
|
||||
});
|
||||
|
||||
global.TESTING = true;
|
||||
for (const test of this.apiTests) {
|
||||
progBar.update(testResults.length, {
|
||||
msg: test.name
|
||||
});
|
||||
|
||||
const result = {
|
||||
test: test,
|
||||
status: null,
|
||||
output: null,
|
||||
output: null
|
||||
};
|
||||
try {
|
||||
await test.run();
|
||||
@ -117,10 +154,37 @@ class TestRegister {
|
||||
result.status = "erroring";
|
||||
result.output = e.message;
|
||||
}
|
||||
return result;
|
||||
}));
|
||||
|
||||
testResults.push(result);
|
||||
progBar.increment();
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formatter for the progress bar
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Object} params
|
||||
* @param {Object} payload
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatter(options, params, payload) {
|
||||
const bar = options.barCompleteString.substr(0, Math.round(params.progress * options.barsize)) +
|
||||
options.barIncompleteString.substr(0, Math.round((1-params.progress) * options.barsize));
|
||||
|
||||
const percentage = Math.floor(params.progress * 100),
|
||||
duration = Math.floor((Date.now() - params.startTime) / 1000);
|
||||
|
||||
let testName = payload.msg ? payload.msg : "";
|
||||
if (params.value >= params.total) testName = "Tests completed";
|
||||
testName = Utils.truncate(testName, 25).padEnd(25, " ");
|
||||
|
||||
return `${testName} ${bar} ${params.value}/${params.total} | ${percentage}% | Duration: ${duration}s`;
|
||||
}
|
||||
|
||||
// Export an instance to make a singleton
|
||||
export default new TestRegister();
|
||||
|
@ -33,6 +33,10 @@ function handleTestResult(testStatus, testResult) {
|
||||
testStatus.allTestsPassing = testStatus.allTestsPassing && testResult.status === "passing";
|
||||
testStatus.counts[testResult.status] = (testStatus.counts[testResult.status] || 0) + 1;
|
||||
testStatus.counts.total += 1;
|
||||
|
||||
if (testResult.duration > 2000) {
|
||||
console.log(`'${testResult.test.name}' took ${(testResult.duration / 1000).toFixed(1)}s to complete`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,8 +46,6 @@ function handleTestResult(testStatus, testResult) {
|
||||
* @param {Object[]} results - results from TestRegister
|
||||
*/
|
||||
export function logTestReport(testStatus, results) {
|
||||
console.log("Tests completed.");
|
||||
|
||||
results.forEach(r => handleTestResult(testStatus, r));
|
||||
|
||||
console.log();
|
||||
@ -80,8 +82,9 @@ export function logTestReport(testStatus, results) {
|
||||
* Fail if the process takes longer than 60 seconds.
|
||||
*/
|
||||
export function setLongTestFailure() {
|
||||
const timeLimit = 120;
|
||||
setTimeout(function() {
|
||||
console.log("Tests took longer than 60 seconds to run, returning.");
|
||||
console.log(`Tests took longer than ${timeLimit} seconds to run, returning.`);
|
||||
process.exit(1);
|
||||
}, 60 * 1000);
|
||||
}, timeLimit * 1000);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ setLongTestFailure();
|
||||
|
||||
const logOpsTestReport = logTestReport.bind(null, testStatus);
|
||||
|
||||
TestRegister.runApiTests()
|
||||
.then(logOpsTestReport);
|
||||
|
||||
(async function() {
|
||||
const results = await TestRegister.runApiTests();
|
||||
logOpsTestReport(results);
|
||||
})();
|
||||
|
@ -588,7 +588,7 @@ Password: 034148`;
|
||||
const result = await chef.generatePGPKeyPair("Back To the Drawing Board", {
|
||||
keyType: "ECC-256",
|
||||
});
|
||||
assert.strictEqual(result.toString().length, 2005);
|
||||
assert.strictEqual(result.toString().length, 2007);
|
||||
}),
|
||||
|
||||
it("Generate UUID", () => {
|
||||
|
@ -45,6 +45,7 @@ import "./tests/Gzip.mjs";
|
||||
import "./tests/Gunzip.mjs";
|
||||
import "./tests/Hash.mjs";
|
||||
import "./tests/HaversineDistance.mjs";
|
||||
import "./tests/Hex.mjs";
|
||||
import "./tests/Hexdump.mjs";
|
||||
import "./tests/Image.mjs";
|
||||
import "./tests/IndexOfCoincidence.mjs";
|
||||
@ -96,6 +97,10 @@ import "./tests/DefangIP.mjs";
|
||||
import "./tests/ParseUDP.mjs";
|
||||
import "./tests/AvroToJSON.mjs";
|
||||
import "./tests/Lorenz.mjs";
|
||||
import "./tests/LuhnChecksum.mjs";
|
||||
import "./tests/CipherSaber2.mjs";
|
||||
import "./tests/Colossus.mjs";
|
||||
import "./tests/ParseObjectIDTimestamp.mjs";
|
||||
|
||||
|
||||
// Cannot test operations that use the File type yet
|
||||
@ -112,5 +117,7 @@ setLongTestFailure();
|
||||
|
||||
const logOpsTestReport = logTestReport.bind(null, testStatus);
|
||||
|
||||
TestRegister.runTests()
|
||||
.then(logOpsTestReport);
|
||||
(async function() {
|
||||
const results = await TestRegister.runTests();
|
||||
logOpsTestReport(results);
|
||||
})();
|
||||
|
43
tests/operations/samples/Images.mjs
Normal file
45
tests/operations/tests/CipherSaber2.mjs
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Ciphersaber2 tests.
|
||||
*
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "CipherSaber2 Encrypt",
|
||||
input: "Hello World",
|
||||
expectedMatch: /.{21}/s,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "CipherSaber2 Encrypt",
|
||||
args: [{ "option": "Latin1", "string": "test" }, 20],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "CipherSaber2 Decrypt",
|
||||
input: "\x5d\xd9\x7f\xeb\x77\x3c\x42\x9d\xfe\x9c\x3b\x21\x63\xbd\x53\x38\x18\x7c\x36\x37",
|
||||
expectedOutput: "helloworld",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "CipherSaber2 Decrypt",
|
||||
args: [{ "option": "Latin1", "string": "test" }, 20],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "CipherSaber2 Encrypt",
|
||||
input: "",
|
||||
expectedMatch: /.{10}/s,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "CipherSaber2 Encrypt",
|
||||
args: [{ "option": "Latin1", "string": "" }, 20],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
@ -418,4 +418,114 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: normal",
|
||||
input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
expectedOutput: "Cryptography is THE Art of Writing or solving codes",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [2, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: key has to be bigger than 2",
|
||||
input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
expectedOutput: "Key has to be bigger than 2",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [1, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: key has to be smaller than input's length",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Key should be smaller than the cipher's length",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [22, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: offset should be positive",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Offset has to be a positive integer",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [2, -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: Normal with Offset non-null",
|
||||
input: "51746026813793592840",
|
||||
expectedOutput: "12345678901234567890",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [4, 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: normal",
|
||||
input: "Cryptography is THE Art of Writing or solving codes",
|
||||
expectedOutput: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [2, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: key has to be bigger than 2",
|
||||
input: "Cryptography is THE Art of Writing or solving codes",
|
||||
expectedOutput: "Key has to be bigger than 2",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [1, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: key has to be smaller than input's length",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Key should be smaller than the plain text's length",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [22, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: offset should be positive",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Offset has to be a positive integer",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [2, -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: Normal with Offset non-null",
|
||||
input: "12345678901234567890",
|
||||
expectedOutput: "51746026813793592840",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [4, 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
91
tests/operations/tests/Colossus.mjs
Normal file
32
tests/operations/tests/ConvertToNATOAlphabet.mjs
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @author MarvinJWendt [git@marvinjwendt.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Convert to NATO alphabet: nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Convert to NATO alphabet",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Convert to NATO alphabet: full alphabet with numbers",
|
||||
input: "abcdefghijklmnopqrstuvwxyz0123456789,/.",
|
||||
expectedOutput: "Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whiskey X-ray Yankee Zulu Zero One Two Three Four Five Six Seven Eight Nine Comma Fraction bar Full stop ",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Convert to NATO alphabet",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
110
tests/operations/tests/Hex.mjs
Normal file
@ -0,0 +1,110 @@
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "ASCII to Hex stream",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "6162657279737477797468",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"None",
|
||||
0
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to Hex with colon deliminator ",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "61:62:65:72:79:73:74:77:79:74:68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"Colon",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to 0x Hex with comma",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "0x61,0x62,0x65,0x72,0x79,0x73,0x74,0x77,0x79,0x74,0x68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"0x with comma",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to 0x Hex with comma and line breaks",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "0x61,0x62,0x65,0x72,\n0x79,0x73,0x74,0x77,\n0x79,0x74,0x68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"0x with comma",
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Hex stream to UTF-8",
|
||||
input: "e69591e69591e5ada9e5ad90",
|
||||
expectedOutput: "救救孩子",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": [
|
||||
"Auto"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
name: "Multiline 0x hex to ASCII",
|
||||
input: "0x49,0x20,0x73,0x61,0x77,0x20,0x6d,0x79,0x73,0x65,0x6c,0x66,0x20,0x73,0x69,\
|
||||
0x74,0x74,0x69,0x6e,0x67,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x63,0x72,\
|
||||
0x6f,0x74,0x63,0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x69,\
|
||||
0x73,0x20,0x66,0x69,0x67,0x20,0x74,0x72,0x65,0x65,0x2c,0x20,0x73,0x74,0x61,\
|
||||
0x72,0x76,0x69,0x6e,0x67,0x20,0x74,0x6f,0x20,0x64,0x65,0x61,0x74,0x68,0x2c,\
|
||||
0x20,0x6a,0x75,0x73,0x74,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x49,\
|
||||
0x20,0x63,0x6f,0x75,0x6c,0x64,0x6e,0x27,0x74,0x20,0x6d,0x61,0x6b,0x65,0x20,\
|
||||
0x75,0x70,0x20,0x6d,0x79,0x20,0x6d,0x69,0x6e,0x64,0x20,0x77,0x68,0x69,0x63,\
|
||||
0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x66,0x69,0x67,0x73,0x20,0x49,\
|
||||
0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x63,0x68,0x6f,0x6f,0x73,0x65,0x2e",
|
||||
expectedOutput: "I saw myself sitting in the crotch of the this fig tree, starving to death, just because I couldn't make up my mind which of the figs I would choose.",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": [
|
||||
"Auto"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "0x with Comma to Ascii",
|
||||
input: "0x74,0x65,0x73,0x74,0x20,0x73,0x74,0x72,0x69,0x6e,0x67",
|
||||
expectedOutput: "test string",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": [
|
||||
"0x with comma"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
]);
|
66
tests/operations/tests/LuhnChecksum.mjs
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* From Decimal tests
|
||||
*
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @licence Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Luhn Checksum on standard data",
|
||||
input: "35641709012469",
|
||||
expectedOutput: "Checksum: 7\nCheckdigit: 0\nLuhn Validated String: 356417090124690",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Luhn Checksum",
|
||||
args: []
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Luhn Checksum on standard data 2",
|
||||
input: "896101950123440000",
|
||||
expectedOutput: "Checksum: 5\nCheckdigit: 1\nLuhn Validated String: 8961019501234400001",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Luhn Checksum",
|
||||
args: []
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Luhn Checksum on standard data 3",
|
||||
input: "35726908971331",
|
||||
expectedOutput: "Checksum: 6\nCheckdigit: 7\nLuhn Validated String: 357269089713317",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Luhn Checksum",
|
||||
args: []
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Luhn Checksum on invalid data",
|
||||
input: "35641709b012469",
|
||||
expectedOutput: "Character: b is not a digit.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Luhn Checksum",
|
||||
args: []
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Luhn Checksum on empty data",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Luhn Checksum",
|
||||
args: []
|
||||
},
|
||||
],
|
||||
}
|
||||
]);
|
24
tests/operations/tests/ParseObjectIDTimestamp.mjs
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Parse ObjectID timestamp tests
|
||||
*
|
||||
* @author dmfj [dominic@dmfj.io]
|
||||
*
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Parse ISO timestamp from ObjectId",
|
||||
input: "000000000000000000000000",
|
||||
expectedOutput: "1970-01-01T00:00:00.000Z",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Parse ObjectID timestamp",
|
||||
args: [],
|
||||
}
|
||||
],
|
||||
}
|
||||
]);
|