Merge branch 'master' into bigint-utils

This commit is contained in:
GCHQDeveloper581 2026-02-26 09:52:13 +00:00 committed by GitHub
commit 5ddba1ac6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1860 additions and 2311 deletions

3876
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -39,57 +39,57 @@
"node >= 16"
],
"devDependencies": {
"@babel/core": "^7.24.7",
"@babel/eslint-parser": "^7.24.7",
"@babel/plugin-syntax-import-assertions": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@babel/runtime": "^7.24.7",
"@codemirror/commands": "^6.6.0",
"@codemirror/language": "^6.10.2",
"@codemirror/search": "^6.5.6",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.28.0",
"autoprefixer": "^10.4.19",
"babel-loader": "^9.1.3",
"@babel/core": "^7.29.0",
"@babel/eslint-parser": "^7.28.6",
"@babel/plugin-syntax-import-assertions": "^7.28.6",
"@babel/plugin-transform-runtime": "^7.29.0",
"@babel/preset-env": "^7.29.0",
"@babel/runtime": "^7.28.6",
"@codemirror/commands": "^6.10.2",
"@codemirror/language": "^6.12.1",
"@codemirror/search": "^6.6.0",
"@codemirror/state": "^6.5.4",
"@codemirror/view": "^6.39.15",
"autoprefixer": "^10.4.24",
"babel-loader": "^10.0.0",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-transform-builtin-extend": "1.1.2",
"base64-loader": "^1.0.0",
"chromedriver": "^130.0.0",
"chromedriver": "^130.0.4",
"cli-progress": "^3.12.0",
"colors": "^1.4.0",
"compression-webpack-plugin": "^11.1.0",
"copy-webpack-plugin": "^12.0.2",
"core-js": "^3.37.1",
"cspell": "^8.17.3",
"css-loader": "7.1.2",
"eslint": "^9.4.0",
"eslint-plugin-jsdoc": "^48.2.9",
"globals": "^15.4.0",
"copy-webpack-plugin": "^13.0.1",
"core-js": "^3.48.0",
"cspell": "^8.19.4",
"css-loader": "7.1.4",
"eslint": "^9.39.3",
"eslint-plugin-jsdoc": "^48.11.0",
"globals": "^15.15.0",
"grunt": "^1.6.1",
"grunt-chmod": "~1.1.1",
"grunt-concurrent": "^3.0.0",
"grunt-contrib-clean": "~2.0.1",
"grunt-contrib-connect": "^4.0.0",
"grunt-contrib-connect": "^5.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^25.0.0",
"grunt-exec": "~3.0.0",
"grunt-webpack": "^6.0.0",
"grunt-zip": "^1.0.0",
"html-webpack-plugin": "^5.6.0",
"html-webpack-plugin": "^5.6.6",
"imports-loader": "^5.0.0",
"mini-css-extract-plugin": "2.9.0",
"mini-css-extract-plugin": "2.10.0",
"modify-source-webpack-plugin": "^4.1.0",
"nightwatch": "^3.6.3",
"postcss": "^8.4.38",
"nightwatch": "^3.15.0",
"postcss": "^8.5.6",
"postcss-css-variables": "^0.19.0",
"postcss-import": "^16.1.0",
"postcss-loader": "^8.1.1",
"postcss-import": "^16.1.1",
"postcss-loader": "^8.2.1",
"prompt": "^1.3.0",
"sitemap": "^8.0.0",
"terser": "^5.31.1",
"webpack": "^5.91.0",
"sitemap": "^8.0.2",
"terser": "^5.46.0",
"webpack": "^5.105.2",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-dev-server": "5.0.4",
"webpack-node-externals": "^3.0.0",
@ -100,12 +100,13 @@
"@babel/polyfill": "^7.12.1",
"@blu3r4y/lzma": "^2.3.3",
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
"@xmldom/xmldom": "^0.8.10",
"@xmldom/xmldom": "^0.8.11",
"argon2-browser": "^1.18.0",
"arrive": "^2.4.1",
"avsc": "^5.7.7",
"arrive": "^2.5.2",
"assert": "^2.1.0",
"avsc": "^5.7.9",
"bcryptjs": "^2.4.3",
"bignumber.js": "^9.1.2",
"bignumber.js": "^9.3.1",
"blakejs": "^1.2.1",
"bootstrap": "4.6.2",
"bootstrap-colorpicker": "^3.4.0",
@ -122,44 +123,45 @@
"ctph.js": "0.0.5",
"d3": "7.9.0",
"d3-hexbin": "^0.2.2",
"diff": "^5.2.0",
"dompurify": "^3.2.5",
"diff": "^5.2.2",
"dompurify": "^3.3.1",
"es6-promisify": "^7.0.0",
"escodegen": "^2.1.0",
"esprima": "^4.0.1",
"events": "^3.3.0",
"exif-parser": "^0.1.12",
"fernet": "^0.4.0",
"fernet": "^0.3.3",
"file-saver": "^2.0.5",
"flat": "^6.0.1",
"geodesy": "1.1.3",
"handlebars": "^4.7.8",
"hash-wasm": "^4.12.0",
"highlight.js": "^11.9.0",
"highlight.js": "^11.11.1",
"ieee754": "^1.2.1",
"jimp": "^1.6.0",
"jq-web": "^0.5.1",
"jq-web": "^0.6.2",
"jquery": "3.7.1",
"js-sha3": "^0.9.3",
"jsesc": "^3.0.2",
"jsesc": "^3.1.0",
"json5": "^2.2.3",
"jsonata": "^2.0.3",
"jsonpath-plus": "^10.3.0",
"jsonata": "^2.1.0",
"jsonpath-plus": "^10.4.0",
"jsonwebtoken": "8.5.1",
"jsqr": "^1.4.0",
"jsrsasign": "^11.1.0",
"jsrsasign": "^11.1.1",
"kbpgp": "^2.1.17",
"libbzip2-wasm": "0.0.4",
"libyara-wasm": "^1.2.1",
"lodash": "^4.17.21",
"loglevel": "^1.9.1",
"lodash": "^4.17.23",
"loglevel": "^1.9.2",
"loglevel-message-prefix": "^3.0.0",
"lz-string": "^1.5.0",
"lz4js": "^0.2.0",
"markdown-it": "^14.1.0",
"markdown-it": "^14.1.1",
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"moment-timezone": "^0.6.0",
"ngeohash": "^0.6.3",
"node-forge": "^1.3.1",
"node-forge": "^1.3.3",
"node-md6": "^0.1.0",
"nodom": "^2.4.0",
"notepack.io": "^3.0.1",
@ -169,24 +171,25 @@
"path": "^0.12.7",
"popper.js": "^1.16.1",
"process": "^0.11.10",
"protobufjs": "^7.3.1",
"protobufjs": "^7.5.4",
"qr-image": "^3.2.0",
"reflect-metadata": "^0.2.2",
"rison": "^0.1.1",
"scryptsy": "^2.1.0",
"snackbarjs": "^1.1.0",
"sortablejs": "^1.15.2",
"sortablejs": "^1.15.7",
"split.js": "^1.6.5",
"ssdeep.js": "0.0.3",
"stream-browserify": "^3.0.0",
"tesseract.js": "5.1.0",
"ua-parser-js": "^1.0.38",
"tesseract.js": "5.1.1",
"ua-parser-js": "^1.0.41",
"unorm": "^1.6.0",
"url": "^0.11.4",
"utf8": "^3.0.0",
"uuid": "^11.1.0",
"uuid": "^13.0.0",
"vkbeautify": "^0.99.3",
"xpath": "0.0.34",
"xregexp": "^5.1.1",
"xregexp": "^5.1.2",
"zlibjs": "^0.3.1"
},
"scripts": {

View File

@ -106,7 +106,7 @@ export function generateQrCode(
case "PDF":
return Utils.strToArrayBuffer(qrImage);
case "PNG":
return qrImage.buffer;
return qrImage.buffer.slice(qrImage.byteOffset, qrImage.byteLength + qrImage.byteOffset);
default:
throw new OperationError("Unsupported QR code format.");
}

View File

@ -133,11 +133,12 @@ class AddTextToImage extends Operation {
} catch (err) {
throw new OperationError(`Error loading image. (${err})`);
}
try {
if (isWorkerEnvironment())
self.sendStatusMessage("Adding text to image...");
const fontsMap = {};
if (isWorkerEnvironment())
self.sendStatusMessage("Adding text to image...");
const fontsMap = {};
try {
const fonts = [
import(
/* webpackMode: "eager" */ "../../web/static/fonts/bmfonts/Roboto72White.fnt"
@ -159,7 +160,6 @@ class AddTextToImage extends Operation {
fontsMap["Roboto Mono"] = fonts[2];
fontsMap["Roboto Slab"] = fonts[3];
});
// Make Webpack load the png font images
await Promise.all([
import(
@ -175,11 +175,16 @@ class AddTextToImage extends Operation {
/* webpackMode: "eager" */ "../../web/static/fonts/bmfonts/RobotoBlack72White.png"
),
]);
} catch (err) {
throw new OperationError(`Error preparing fonts. (${err})`);
}
let jimpFont;
try {
const font = fontsMap[fontFace];
// LoadFont needs an absolute url, so append the font name to self.docURL
const jimpFont = await loadFont(self.docURL + "/" + font.default);
jimpFont = await loadFont(self.docURL + "/" + font.default);
jimpFont.pages.forEach(function (page) {
if (page.bitmap) {
@ -210,7 +215,11 @@ class AddTextToImage extends Operation {
}
}
});
} catch (err) {
throw new OperationError(`Error loading font. (${err})`);
}
try {
// Create a temporary image to hold the rendered text
const textImage = new Jimp({
width: measureText(jimpFont, text),
@ -271,7 +280,11 @@ class AddTextToImage extends Operation {
x: xPos,
y: yPos,
});
} catch (err) {
throw new OperationError(`Error adding text to image. (${err})`);
}
try {
let imageBuffer;
if (image.mime === "image/gif") {
imageBuffer = await image.getBuffer(JimpMime.png);
@ -280,7 +293,7 @@ class AddTextToImage extends Operation {
}
return imageBuffer.buffer;
} catch (err) {
throw new OperationError(`Error adding text to image. (${err})`);
throw new OperationError(`Error exporting image. (${err})`);
}
}

View File

@ -44,23 +44,6 @@ class EscapeUnicodeCharacters extends Operation {
"value": true
}
];
this.checks = [
{
pattern: "\\\\u(?:[\\da-f]{4,6})",
flags: "i",
args: ["\\u"]
},
{
pattern: "%u(?:[\\da-f]{4,6})",
flags: "i",
args: ["%u"]
},
{
pattern: "U\\+(?:[\\da-f]{4,6})",
flags: "i",
args: ["U+"]
}
];
}
/**

View File

@ -30,6 +30,23 @@ class UnescapeUnicodeCharacters extends Operation {
"value": ["\\u", "%u", "U+"]
}
];
this.checks = [
{
pattern: "\\\\u(?:[\\da-f]{4,6})",
flags: "i",
args: ["\\u"]
},
{
pattern: "%u(?:[\\da-f]{4,6})",
flags: "i",
args: ["%u"]
},
{
pattern: "U\\+(?:[\\da-f]{4,6})",
flags: "i",
args: ["U+"]
}
];
}
/**

View File

@ -104,6 +104,7 @@
<char id="126" x="454" y="319" width="42" height="16" xoffset="1" yoffset="47" xadvance="44" page="0" chnl="0" />
<char id="127" x="0" y="0" width="45" height="99" xoffset="-1" yoffset="-2" xadvance="43" page="0" chnl="0" />
</chars>
<kernings count="0">
<kernings count="1">
<kerning first="0" second="0" amount="0" />
</kernings>
</font>

View File

@ -153,16 +153,22 @@ class InputWaiter {
paste(event, view) {
const clipboardData = event.clipboardData;
const items = clipboardData.items;
const files = [];
let files = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.kind === "file") {
const file = item.getAsFile();
files.push(file);
event.preventDefault(); // Prevent the default paste behavior
if (item.kind === "string") {
// If there are any string items they should be preferred over
// files.
files = [];
break;
} else if (item.kind === "file") {
files.push(item.getAsFile());
}
}
if (files.length > 0) {
// Prevent the default paste behavior, afterPaste will load the files instead
event.preventDefault();
}
setTimeout(() => {
self.afterPaste(files);
});

View File

@ -34,7 +34,10 @@ module.exports = {
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]);
testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]);
testOp(browser, "Add line numbers", "test input", "1 test input");
testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, [[], ["Chef", "Center", "Middle", 0, 0, 16], []]);
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "50cdf8ea483c55564a091650c2bccb4586f919b721e5fe9d6a61660505b4346d6ebdb2ef0cf075a7728cd84cb26ea3e477b5bd86a94a49a27d79423994afb60a", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto"], []]);
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "78b3055463d9167dd039e47f451acaf06c593d209f8e405b4e18011cdcf190dc0af5952be887d93c0ebd38738e978120c1294c71104e6b00d3f9de8d6320ec1c", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Black"], []]);
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "4ab4d4b6cb22ad700f6cd144c2c8ecad2a094f21a1d1d5d48eb6c8f97417192f89b4512f6a78276d49668ebef5e89c3a4d14860cb79399a0dafce98c92209e07", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Mono"], []]);
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "11490db4907516b4d9e256da1ac0b02b561fa7547971e6316a8a0b90c9c66585a11f3145672c6d972b1a221d3bfad9c8a97de7ff77fd9442ebc40f39c1ef9ef7", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Slab"], []]);
testOp(browser, ["From Hex", "Dither Image", "SHA2"], Images.PNG_HEX, "cbf587a78915cfb14546ba83080b13e5054800802488dd0cb786b8951e7dc0b48f055260917bd0ccfc075e422b9d6aff112948562653995d74e70f0b66367ac3", [[], [], []]);
testOp(browser, ["From Hex", "Generate Image", "SHA2"], Images.PNG_HEX, "2c451762a6c9192fd31dc80765eab3f447be70ea51f6fdb6911ade4d89d4a98bd0a1ff00b08d76aac472faeceb54b66092e3f3be7bbf899bf3e55ca9c96a56aa", [[], [], []]);
testOp(browser, ["From Hex", "Image Hue/Saturation/Lightness", "SHA2"], Images.PNG_HEX, "522dfc0bbef00e05c5d6861a002039fa2952e4bbb7fe8d21d0d538ef6f9d65da82065929b4150dc5b8b49460ee6c9bef7f660b86f8d4e7442a07c61c0a152a4b", [[], [50, 50, 50], []]);

View File

@ -76,6 +76,7 @@ import "./tests/FromDecimal.mjs";
import "./tests/GenerateAllChecksums.mjs";
import "./tests/GenerateAllHashes.mjs";
import "./tests/GenerateDeBruijnSequence.mjs";
import "./tests/GenerateQRCode.mjs";
import "./tests/GetAllCasings.mjs";
import "./tests/GOST.mjs";
import "./tests/Gunzip.mjs";

View File

@ -0,0 +1,67 @@
/**
* Generate QR Code tests
*
* @author GCHQDeveloper581
* @copyright Crown Copyright 2025
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "Generate QR Code : PNG",
input: "Hello world!",
expectedOutput: "89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 91 00 00 00 91 08 00 00 00 00 e6 b3 05 ff 00 00 01 1a 49 44 41 54 78 da ed da 41 12 83 20 0c 05 50 ef 7f e9 76 dd 05 f4 47 6c c4 ce 63 e5 8c 0c be 4d 24 24 1c af dd c6 41 44 44 44 44 44 44 44 44 44 f4 9f a2 e3 fb 98 cf 2b ad 42 44 d4 2a 1a 07 c3 e7 37 83 a7 d2 37 88 88 1a 44 c3 18 1a 46 e7 ca 2a 44 44 7b 88 4a f3 88 88 1e 23 9a ef 09 44 44 fb 8a 82 b7 c3 3c fe 8e 8c 8d 88 e8 b2 33 6d ba b3 f4 9d b2 89 88 16 eb 90 f3 a5 ef a8 8c 12 11 55 f3 a3 61 a2 93 e6 4c c3 45 89 88 ba 44 a5 e4 e7 64 5d 9d 88 a8 5f 14 74 82 d2 8a 64 5a b4 24 22 6a 10 a5 2d cf 79 3f e9 6c 53 89 88 e8 a7 a2 79 4f a8 b4 b3 ac 57 6b 88 88 ae 15 a5 de b9 bc 14 70 44 44 3f 13 ad d4 21 03 ea d9 6a 0d 11 d1 15 a2 e0 ff 5f 47 07 36 22 a2 06 d1 4a d2 1f 1c 94 89 88 b6 14 95 ee d5 12 11 3d 50 14 74 8c 82 70 24 22 ea 12 05 6f d3 4b 2c 4b d5 1a 22 a2 cb 44 2b 69 7d e9 5e 00 11 51 97 e8 d6 41 44 44 44 44 44 44 44 44 44 f4 7c d1 1b 1c 52 72 cb 26 c8 c7 0b 00 00 00 00 49 45 4e 44 ae 42 60 82",
recipeConfig: [
{
"op": "Generate QR Code",
"args": ["PNG", 5, 4, "Medium"]
},
{
"op": "To Hex",
"args": ["Space", 0]
}
],
},
{
name: "Generate QR Code : SVG",
input: "Hello world!",
expectedOutput: '<svg xmlns="http://www.w3.org/2000/svg" width="145" height="145" viewBox="0 0 29 29"><path d="M4 4h7v7h-7zM12 4h5v2h-1v-1h-1v1h1v1h1v1h-2v3h-1v-1h-1v-1h1v-4h-1v1h-1zM18 4h7v7h-7zM5 5v5h5v-5zM19 5v5h5v-5zM6 6h3v3h-3zM20 6h3v3h-3zM12 7h1v1h-1zM12 10h1v1h1v1h-2zM16 10h1v1h-1zM4 12h1v1h-1zM6 12h2v2h-1v1h1v-1h3v1h-1v1h-2v1h-2v-1h-1v-1h-1v-1h2zM9 12h3v2h-1v-1h-2zM14 12h1v2h-2v-1h1zM18 12h1v1h2v-1h1v1h1v1h-3v2h-1v-2h-1v1h-1v1h-1v-3h2zM23 12h2v3h-1v1h-1v-2h1v-1h-1zM12 14h1v1h-1zM11 15h1v2h-2v-1h1zM14 15h1v1h-1zM21 15h1v1h-1zM15 16h1v2h-1v1h2v-1h1v-1h-1v-1h2v1h2v2h-1v1h-1v-1h-1v1h-2v1h-1v-1h-1v1h-1v-1h-1v-3h3zM24 16h1v2h-1zM22 17h1v1h-1zM4 18h7v7h-7zM13 18v1h1v-1zM5 19v5h5v-5zM21 19h2v1h1v2h-1v1h-1v-1h-1zM6 20h3v3h-3zM12 21h1v2h-1zM14 21h1v1h-1zM16 21h1v2h-1zM18 21h1v1h-1zM19 22h1v1h1v1h-1v1h-3v-2h2zM13 23h1v1h-1zM15 23h1v2h-2v-1h1zM24 23h1v1h-1zM12 24h1v1h-1zM22 24h1v1h-1z"/></svg>',
recipeConfig: [
{
"op": "Generate QR Code",
"args": ["SVG", 5, 4, "Medium"]
},
],
},
{
name: "Generate QR Code : EPS",
input: "Hello world!",
expectedOutput: "%!PS-Adobe-3.0 EPSF-3.0%%BoundingBox: 0 0 315 315/h { 0 rlineto } bind def/v { 0 exch neg rlineto } bind def/M { neg 30 add moveto } bind def/z { closepath } bind def9 9 scale5 0 M 7 h 7 v -7 h z13 0 M 1 h 1 v -1 h z16 0 M 2 h 1 v -1 h 1 v 1 h 1 v -2 h -1 v -1 h 2 v -1 h -3 v 2 h z20 0 M 2 h 1 v -2 h z23 0 M 7 h 7 v -7 h z6 1 M 5 v 5 h -5 v z24 1 M 5 v 5 h -5 v z7 2 M 3 h 3 v -3 h z19 2 M 1 h 1 v -1 h z21 2 M 1 h 2 v -1 h z25 2 M 3 h 3 v -3 h z13 4 M 1 h 3 v -1 h z17 4 M 4 h 1 v 1 h 2 v -1 h -1 v -1 h 1 v -1 h -1 v -1 h -1 v -1 h z15 6 M 1 h 1 v -1 h z17 6 M 1 h 1 v -1 h z16 7 M 1 h 1 v -1 h z18 7 M 1 h 1 v -1 h z20 7 M 1 h 2 v 1 h 1 v -2 h -1 v -1 h -1 v 1 h z6 8 M 7 h 1 v 2 h 1 v -2 h 1 v -2 h -1 v 1 h -1 v -4 h 1 v -1 h -1 v -1 h z17 8 M 1 h 1 v -1 h z24 8 M 2 h 1 v -1 h 1 v -1 h z29 8 M 1 h 1 v -1 h z27 9 M 1 h 1 v -1 h z6 10 M 1 h 1 v 1 h 1 v -1 h 1 v -1 h z8 10 M 2 h 5 v 1 h 1 v -3 h 1 v -1 h -4 v 1 h 1 v 1 h -1 v -1 h -1 v 1 h -1 v -1 h z16 10 M 2 h 4 v 1 h -1 v 2 h 1 v 3 h -1 v -3 h -2 v 1 h 1 v 1 h -1 v 1 h 1 v 4 h -2 v 2 h 3 v -2 h 1 v -1 h -1 v -2 h 1 v 2 h 1 v -1 h 1 v 2 h 2 v 1 h -1 v 1 h 3 v -1 h -1 v -2 h -2 v -1 h 2 v 1 h 1 v 2 h 1 v -2 h 2 v -1 h -1 v -1 h -1 v -1 h 1 v -1 h -1 v -1 h 2 v -1 h -1 v -1 h -1 v 1 h -2 v -1 h -1 v -1 h 1 v 1 h 2 v -1 h -1 v -1 h 1 v -1 h -3 v 1 h -1 v -1 h 1 v -1 h -1 v -1 h -1 v 4 h 1 v 1 h -2 v -3 h -1 v -1 h 1 v -1 h -1 v -1 h 2 v -1 h 1 v -2 h -1 v 1 h -1 v -1 h -1 v 1 h -1 v 1 h -1 v 1 h 1 v 1 h -1 v 1 h 1 v 1 h -1 v -1 h z22 10 M 1 h 1 v -1 h z25 10 M 2 h 1 v -2 h z19 11 M 1 h 1 v -1 h z11 12 M 1 h 1 v -1 h z5 13 M 1 h 4 v -1 h z28 14 M 2 h 2 v -1 h -1 v -1 h z21 15 M 1 v 2 h -1 v z13 17 M 1 h 1 v 2 h 1 v -2 h 1 v 1 h 1 v 1 h 1 v -2 h 1 v 2 h 2 v -1 h -1 v -2 h z22 17 M 3 v 3 h -3 v z5 18 M 7 h 7 v -7 h z23 18 M 1 h 1 v -1 h z6 19 M 5 v 5 h -5 v z7 20 M 3 h 3 v -3 h z29 21 M 1 h 4 v -3 h -1 v 2 h z17 22 M 2 h 3 v -2 h -1 v 1 h -1 v -1 h z24 22 M 1 h 1 v 1 h 1 v -1 h 1 v -3 h -1 v 1 h -1 v 1 h z20 23 M 1 h 2 v -1 h zfill%%EOF",
recipeConfig: [
{
"op": "Generate QR Code",
"args": ["EPS", 6, 5, "Quartile"]
},
{
"op": "Remove whitespace",
"args": [false, true, true, false, false, false]
},
],
},
{
name: "Generate QR Code : PDF",
input: "Hello world!",
expectedOutput: "%PDF-1.01 0 obj << /Type /Catalog /Pages 2 0 R >> endobj2 0 obj << /Type /Pages /Count 1 /Kids [ 3 0 R ] >> endobj3 0 obj << /Type /Page /Parent 2 0 R /Resources <<>> /Contents 4 0 R /MediaBox [ 0 0 261 261 ] >> endobj4 0 obj << /Length 1837 >> stream9 0 0 9 0 0 cm4 25 m 11 25 l 11 18 l 4 18 l h12 25 m 14 25 l 14 23 l 13 23 l 13 24 l 12 24 l h16 25 m 17 25 l 17 22 l 16 22 l h18 25 m 25 25 l 25 18 l 18 18 l h5 24 m 5 19 l 10 19 l 10 24 l h19 24 m 19 19 l 24 19 l 24 24 l h6 23 m 9 23 l 9 20 l 6 20 l h12 23 m 13 23 l 13 21 l 15 21 l 15 20 l 12 20 l h14 23 m 15 23 l 15 22 l 14 22 l h20 23 m 23 23 l 23 20 l 20 20 l h15 22 m 16 22 l 16 21 l 15 21 l h12 19 m 13 19 l 13 18 l 12 18 l h14 19 m 15 19 l 15 13 l 13 13 l 13 11 l 12 11 l 12 14 l 14 14 l 14 15 l 11 15 l 11 16 l 12 16 l 12 17 l 13 17 l 13 16 l 14 16 l 14 17 l 13 17 l 13 18 l 14 18 l h16 19 m 17 19 l 17 18 l 16 18 l h4 17 m 8 17 l 8 16 l 10 16 l 10 15 l 11 15 l 11 14 l 10 14 l 10 13 l 11 13 l 11 12 l 9 12 l 9 15 l 8 15 l 8 13 l 6 13 l 6 15 l 7 15 l 7 16 l 4 16 l h10 17 m 11 17 l 11 16 l 10 16 l h17 17 m 18 17 l 18 16 l 20 16 l 20 17 l 23 17 l 23 15 l 20 15 l 20 13 l 19 13 l 19 15 l 18 15 l 18 14 l 17 14 l 17 13 l 16 13 l 16 16 l 17 16 l h24 17 m 25 17 l 25 14 l 24 14 l 24 13 l 23 13 l 23 15 l 24 15 l h21 14 m 22 14 l 22 13 l 21 13 l h15 13 m 16 13 l 16 11 l 15 11 l h17 13 m 19 13 l 19 12 l 21 12 l 21 10 l 20 10 l 20 9 l 19 9 l 19 10 l 18 10 l 18 9 l 16 9 l 16 8 l 15 8 l 15 10 l 17 10 l 17 11 l 18 11 l 18 12 l 17 12 l h24 13 m 25 13 l 25 11 l 24 11 l h22 12 m 23 12 l 23 11 l 22 11 l h4 11 m 11 11 l 11 4 l 4 4 l h14 11 m 15 11 l 15 10 l 14 10 l h5 10 m 5 5 l 10 5 l 10 10 l h13 10 m 14 10 l 14 9 l 13 9 l h21 10 m 23 10 l 23 9 l 24 9 l 24 7 l 23 7 l 23 6 l 22 6 l 22 7 l 21 7 l h6 9 m 9 9 l 9 6 l 6 6 l h12 8 m 15 8 l 15 7 l 13 7 l 13 6 l 16 6 l 16 4 l 15 4 l 15 5 l 14 5 l 14 4 l 12 4 l h16 8 m 17 8 l 17 6 l 16 6 l h18 8 m 19 8 l 19 7 l 18 7 l h19 7 m 20 7 l 20 6 l 21 6 l 21 5 l 20 5 l 20 4 l 17 4 l 17 6 l 19 6 l h24 6 m 25 6 l 25 5 l 24 5 l h22 5 m 23 5 l 23 4 l 22 4 l hfendstreamendobjxref0 50000000000 65535 f 0000000010 00000 n 0000000059 00000 n 0000000118 00000 n 0000000223 00000 n trailer << /Root 1 0 R /Size 5 >>startxref2111%%EOF",
recipeConfig: [
{
"op": "Generate QR Code",
"args": ["PDF", 5, 4, "Low"]
},
{
"op": "Remove whitespace",
"args": [false, true, true, false, false, false]
},
],
},
]);

View File

@ -18,12 +18,6 @@ export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffc
*/
export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082";
/**
* The CyberChef logo with 'chef'
* 32x32
*/
export const PNG_CHEF_B64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAHqElEQVR4AcXBfUyU9wEH8O/v9zz3PHfPvXLewXHnxYKgYCFW6ktHmXUySIdKcVlFs2ZkrRB1m6kx00XTbGJjFrvVTSexZusGviQqwsxImM5laOZclG3EisEXWK2cvBwcuYN7456XPawQb+fx4l/7fAji5Obmvrlx48ZKjUZjlyTpaXNz89nOzs42TDp37lzLwMCAcefOnWtPnz6d53A4CsPhMNPb2/v37du3/wuADIACUADImIZer3e3tLS0rVy50k2gIqo9e/b8et++fd8+ceLEqXA47Jk3b97SmpqaDTU1NT+ur68/BICeOXPmEsuyzry8vAcWi+XtQCCAYDBIASiBQOAPIyMjd+x2+7poNPpZSUnJuwAkJLFr165j1dXVlQUFBa+yUBUXF79TW1tbtWTJkrXd3d3XMam9vb325MmTH27durXc4XAwBoPh1Z6eHqSkpCzDl2R8iZhMpnKj0biBqHiez+I47v2GhoavabVaa0VFxacAZEwqLy/Pa2xsbI9EIk8YqA4ePPhJa2tre2Nj40d4hnz88cerMzMz1/T29rrS0tKcLMvC7/eDUooJg4ODBCpCCAghICqoxsfH+aqqqr2CIFTabLbykpIS74ULF24zDKPbvXv3nuLi4rUmk0mfmppqoQzDGMvKyl55+PDhdcRpampavnjx4v3d3d1wOByY4nQ6IQgCIpEIrFYrVq1aBVEUMcXv9yMjIwNOpxPp6emw2WzIz8//lUajMQNg9Xp9oSiKxvT0dLsgCF+hPM/rLRaL9tGjRwN4hmRnZ2+nlGoMBgMEQcAUk8mEkZERmM1mqORbt24hJSUFExRFgcVigc/ng9frxejoKHp6eiRRFCPl5eU7JEkaPXDgwPq+vr67p06d+lttbe0GCoBAJUmSjGcoz/N5SKKrqws2mw0TiMrv98PlcmFCIBBAQUEBBgYGEI1GEQqFwLIsA0C7Y8eOQwAIJlFKCVSsLMsSVHa73YRnFFUEsyOKooAQggmiKGJCcXExEoVCIagoAAlx2Gg0OtzR0dHndruz8YwcDAavGQyGr46NjSEQCMDlciEJBQBBgpaWFpjNZkyJRqOxYDB4DoCMBFRRFOnixYstmzdvrmQYRodJra2tx30+HxYtWgRZlpGMokIcnuchiiIcDgcEQYAgCGAYZrCysvKlioqKKgAKElCo6urqDmZnZxuOHDlyRhCEBZRSXV1dXaYgCLh//z7S09MxFwaDAbdv30ZWVhZ8Ph+i0SiCwWBqZ2enp6ys7H0kwULl8/me5OXlrTl+/PinwWDwc6gikYh49OjR39fX139w5cqVfwLQMAwDQgjiEUJAKcUUhmHQ1dWF1atXg+d5yLKMtrY2XL169beIwzAMhYogDiGE8jyfrtVqrcFgsDcWi40AMPT29g5TSrlwOAxFUSAIAib4/X55ZGSEiqIIQRAwRZKkUFFRUf6xY8c2m81mecuWLYcByJjEsqxJUUmSNMoijqIociQS8UQiEQ+S0Ol0SMRxHDiOQzxZliOxWKxv27Zth5CEKIoBTKL4P6OYnYIXRAhRAMiYAxazC9+4cePPRqPxG0jw9OlT9Pf3I1E4HL4GIIY5YDE7TVZWVjbDMEjEcRwsFgsSybK8EAADQMYsWMxgSZpeu6Uo53vMF//IIJQins46XzHrjIrH41E8Hg/iiaKYvWbNmq+3tbW1YhYE06OH38o5sfa1gmqe0+B/EWSseRdfxDi5/cED2tTUBEmSEE9RlJgq//Lly/cxA4ppvLM83WXXs9992N0DkfKYEohISF/+TehtCzAhJSUFK8pWIJoSxRSGYcBx3F99qtLS0ixGhWkwmMa3ljrWW3Ts28FwBK9t/gBpOYU4cPYKvNZcGMxpSLNa8dm9exA1GrKf7IdmqQbLVi7DG+43kJOTg6GhIafNZiuzWq0HMzMzuzs7O+8gCYoktr/uznCZ+aOYRCkDncmOFSuK8KDzHjKcToQDAYT8fjI2Nob33O/hSegJMvlM2O12aLVanyiK/+Y4bilRsSybimmwSCI3Vb+LoWQeElRv2oTqTZsgyTKC/f2YMDQ0hEJjIQoNhUAY/8Xz/LDX693rcrkuBYPB35w9e/YXmAbF86iGJQWYQTQahZZlMWF4eBiJZFmmBoOhCCqe518vLS3NwDQonqfIMgYwA57nMQ4VIUogEICiKIgXiUQyTSbTD6FiWTbX4XB8H9Ng8TzFOzb+icDp3iIEDJJgKIXebkd2fj6owwFCCBKQ8fHxjkAg8KHRaCz3eDxHMA0WSfzkcveffro+e0eqgfsIgAmTZFmGJxCAXqcDw7K409VF/tjWpoiiCL1eL61bt45REahisdhfmpubLwK4iBmwSE75UcvDk5tecVzKmKd7k+V0vwRgppTCodNh8NEjhIeHIQ0MKG63W3E6nXC73QxRQcVx3BOPx/NzzAGLGZzv6B8A0PCdQW80S9D/jNNoXBqeh+vllzEh1tenWLxeijiSJD0NhUI/uHbtmgdzwGAO6hoa7sqy/LuchQtHeY57iWWYFKiGxsaUkVCIQCVJUm8oFDpy8+bNqr1793ZgjgheEKWUu37+/JIF8+cv/dznM/d4vWOqu4cPH+54/PjxOF7QfwCiFwbr9BCaBwAAAABJRU5ErkJggg==";
/**
* Sunglasses smiley
* 32x32

View File

@ -120,17 +120,20 @@ module.exports = {
jquery: "jquery/src/jquery",
},
fallback: {
"fs": false,
"child_process": false,
"net": false,
"tls": false,
"path": require.resolve("path/"),
"assert": require.resolve("assert/"),
"buffer": require.resolve("buffer/"),
"child_process": false,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"zlib": require.resolve("browserify-zlib"),
"events": require.resolve("events/"),
"fs": false,
"net": false,
"path": require.resolve("path/"),
"process": false,
"vm": false
"stream": require.resolve("stream-browserify"),
"tls": false,
"url": require.resolve("url/"),
"vm": false,
"zlib": require.resolve("browserify-zlib")
}
},
module: {