cyberchef 10.22.0 → 10.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/CONTRIBUTING.md +37 -0
  3. package/Dockerfile +2 -0
  4. package/Gruntfile.js +0 -12
  5. package/README.md +1 -1
  6. package/babel.config.js +0 -6
  7. package/package.json +63 -62
  8. package/src/core/Chef.mjs +8 -1
  9. package/src/core/Ingredient.mjs +5 -2
  10. package/src/core/Operation.mjs +6 -1
  11. package/src/core/Recipe.mjs +10 -5
  12. package/src/core/config/Categories.json +18 -3
  13. package/src/core/config/OperationConfig.json +22310 -0
  14. package/src/core/config/modules/Bletchley.mjs +28 -0
  15. package/src/core/config/modules/Charts.mjs +24 -0
  16. package/src/core/config/modules/Ciphers.mjs +128 -0
  17. package/src/core/config/modules/Code.mjs +60 -0
  18. package/src/core/config/modules/Compression.mjs +52 -0
  19. package/src/core/config/modules/Crypto.mjs +134 -0
  20. package/src/core/config/modules/Default.mjs +424 -0
  21. package/src/core/config/modules/Diff.mjs +16 -0
  22. package/src/core/config/modules/Encodings.mjs +42 -0
  23. package/src/core/config/modules/Handlebars.mjs +16 -0
  24. package/src/core/config/modules/Hashing.mjs +30 -0
  25. package/src/core/config/modules/Image.mjs +70 -0
  26. package/src/core/config/modules/Jq.mjs +16 -0
  27. package/src/core/config/modules/OCR.mjs +16 -0
  28. package/src/core/config/modules/OpModules.mjs +63 -0
  29. package/src/core/config/modules/PGP.mjs +26 -0
  30. package/src/core/config/modules/Protobuf.mjs +18 -0
  31. package/src/core/config/modules/PublicKey.mjs +36 -0
  32. package/src/core/config/modules/Regex.mjs +40 -0
  33. package/src/core/config/modules/Serialise.mjs +26 -0
  34. package/src/core/config/modules/Shellcode.mjs +18 -0
  35. package/src/core/config/modules/URL.mjs +20 -0
  36. package/src/core/config/modules/UserAgent.mjs +16 -0
  37. package/src/core/config/modules/Yara.mjs +16 -0
  38. package/src/core/lib/AudioBytes.mjs +103 -0
  39. package/src/core/lib/AudioMetaSchema.mjs +82 -0
  40. package/src/core/lib/AudioParsers.mjs +630 -0
  41. package/src/core/lib/BigIntUtils.mjs +73 -0
  42. package/src/core/lib/Modhex.mjs +2 -0
  43. package/src/core/lib/QRCode.mjs +30 -10
  44. package/src/core/lib/RC6.mjs +625 -0
  45. package/src/core/operations/A1Z26CipherDecode.mjs +1 -1
  46. package/src/core/operations/AddTextToImage.mjs +116 -64
  47. package/src/core/operations/BlurImage.mjs +10 -12
  48. package/src/core/operations/ContainImage.mjs +50 -40
  49. package/src/core/operations/ConvertImageFormat.mjs +33 -39
  50. package/src/core/operations/CoverImage.mjs +39 -37
  51. package/src/core/operations/CropImage.mjs +35 -21
  52. package/src/core/operations/DisassembleARM.mjs +193 -0
  53. package/src/core/operations/DitherImage.mjs +8 -8
  54. package/src/core/operations/EscapeUnicodeCharacters.mjs +0 -17
  55. package/src/core/operations/ExtractAudioMetadata.mjs +175 -0
  56. package/src/core/operations/ExtractLSB.mjs +17 -11
  57. package/src/core/operations/ExtractRGBA.mjs +12 -10
  58. package/src/core/operations/FlaskSessionDecode.mjs +80 -0
  59. package/src/core/operations/FlaskSessionSign.mjs +89 -0
  60. package/src/core/operations/FlaskSessionVerify.mjs +136 -0
  61. package/src/core/operations/FlipImage.mjs +14 -10
  62. package/src/core/operations/GenerateImage.mjs +39 -32
  63. package/src/core/operations/ImageBrightnessContrast.mjs +10 -10
  64. package/src/core/operations/ImageFilter.mjs +14 -13
  65. package/src/core/operations/ImageHueSaturationLightness.mjs +22 -20
  66. package/src/core/operations/ImageOpacity.mjs +6 -8
  67. package/src/core/operations/InvertImage.mjs +4 -6
  68. package/src/core/operations/Jq.mjs +12 -4
  69. package/src/core/operations/NormaliseImage.mjs +5 -7
  70. package/src/core/operations/OffsetChecker.mjs +1 -1
  71. package/src/core/operations/ParseEthernetFrame.mjs +112 -0
  72. package/src/core/operations/ParseIPv4Header.mjs +23 -6
  73. package/src/core/operations/ParseQRCode.mjs +13 -13
  74. package/src/core/operations/PseudoRandomIntegerGenerator.mjs +164 -0
  75. package/src/core/operations/RC6Decrypt.mjs +119 -0
  76. package/src/core/operations/RC6Encrypt.mjs +119 -0
  77. package/src/core/operations/RandomizeColourPalette.mjs +11 -11
  78. package/src/core/operations/ResizeImage.mjs +30 -23
  79. package/src/core/operations/RotateImage.mjs +8 -9
  80. package/src/core/operations/SQLBeautify.mjs +21 -3
  81. package/src/core/operations/SharpenImage.mjs +94 -62
  82. package/src/core/operations/SplitColourChannels.mjs +47 -21
  83. package/src/core/operations/TextIntegerConverter.mjs +123 -0
  84. package/src/core/operations/UnescapeUnicodeCharacters.mjs +17 -0
  85. package/src/core/operations/ViewBitPlane.mjs +16 -20
  86. package/src/core/operations/index.mjs +960 -0
  87. package/src/node/index.mjs +2423 -0
  88. package/src/web/HTMLIngredient.mjs +24 -43
  89. package/src/web/Manager.mjs +1 -0
  90. package/src/web/html/index.html +6 -6
  91. package/src/web/static/fonts/bmfonts/Roboto72White.fnt +491 -485
  92. package/src/web/static/fonts/bmfonts/RobotoBlack72White.fnt +494 -488
  93. package/src/web/static/fonts/bmfonts/RobotoMono72White.fnt +110 -103
  94. package/src/web/static/fonts/bmfonts/RobotoSlab72White.fnt +498 -492
  95. package/src/web/stylesheets/layout/_banner.css +30 -0
  96. package/src/web/stylesheets/layout/_modals.css +5 -0
  97. package/src/web/stylesheets/utils/_overrides.css +7 -0
  98. package/src/web/waiters/ControlsWaiter.mjs +82 -0
  99. package/src/web/waiters/InputWaiter.mjs +12 -6
  100. package/src/web/waiters/RecipeWaiter.mjs +2 -2
  101. package/tests/browser/02_ops.js +23 -3
  102. package/tests/node/index.mjs +1 -0
  103. package/tests/node/tests/lib/BigIntUtils.mjs +150 -0
  104. package/tests/node/tests/operations.mjs +9 -7
  105. package/tests/operations/index.mjs +8 -0
  106. package/tests/operations/tests/A1Z26CipherDecode.mjs +33 -0
  107. package/tests/operations/tests/DisassembleARM.mjs +377 -0
  108. package/tests/operations/tests/ExtractAudioMetadata.mjs +287 -0
  109. package/tests/operations/tests/FlaskSession.mjs +246 -0
  110. package/tests/operations/tests/GenerateQRCode.mjs +67 -0
  111. package/tests/operations/tests/JWTSign.mjs +83 -8
  112. package/tests/operations/tests/Jq.mjs +32 -0
  113. package/tests/operations/tests/Modhex.mjs +20 -0
  114. package/tests/operations/tests/ParseEthernetFrame.mjs +45 -0
  115. package/tests/operations/tests/RC6.mjs +487 -0
  116. package/tests/operations/tests/SQLBeautify.mjs +54 -0
  117. package/tests/operations/tests/TextIntegerConverter.mjs +199 -0
  118. package/tests/samples/Audio.mjs +73 -0
  119. package/tests/samples/Images.mjs +0 -12
  120. package/webpack.config.js +10 -7
  121. package/src/core/lib/ImageManipulation.mjs +0 -251
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Text-Integer Conversion tests.
3
+ *
4
+ * @author p-leriche [philip.leriche@cantab.net]
5
+ *
6
+ * @copyright Crown Copyright 2025
7
+ * @license Apache-2.0
8
+ */
9
+ import TestRegister from "../../lib/TestRegister.mjs";
10
+
11
+ TestRegister.addTests([
12
+ {
13
+ name: "Text-Integer Conversion quoted string to decimal",
14
+ input: "\"ABC\"",
15
+ expectedOutput: "4276803",
16
+ recipeConfig: [
17
+ {
18
+ op: "Text-Integer Conversion",
19
+ args: ["Decimal"],
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ name: "Text-Integer Conversion quoted string to hexadecimal",
25
+ input: "\"ABC\"",
26
+ expectedOutput: "0x414243",
27
+ recipeConfig: [
28
+ {
29
+ op: "Text-Integer Conversion",
30
+ args: ["Hexadecimal"],
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ name: "Text-Integer Conversion single quoted string to decimal",
36
+ input: "'Hello'",
37
+ expectedOutput: "310939249775",
38
+ recipeConfig: [
39
+ {
40
+ op: "Text-Integer Conversion",
41
+ args: ["Decimal"],
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ name: "Text-Integer Conversion decimal to string",
47
+ input: "4276803",
48
+ expectedOutput: "ABC",
49
+ recipeConfig: [
50
+ {
51
+ op: "Text-Integer Conversion",
52
+ args: ["String"],
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ name: "Text-Integer Conversion hexadecimal to string",
58
+ input: "0x48656C6C6F",
59
+ expectedOutput: "Hello",
60
+ recipeConfig: [
61
+ {
62
+ op: "Text-Integer Conversion",
63
+ args: ["String"],
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ name: "Text-Integer Conversion round-trip string.decimal.string",
69
+ input: "\"Test\"",
70
+ expectedOutput: "Test",
71
+ recipeConfig: [
72
+ {
73
+ op: "Text-Integer Conversion",
74
+ args: ["Decimal"],
75
+ },
76
+ {
77
+ op: "Text-Integer Conversion",
78
+ args: ["String"],
79
+ },
80
+ ],
81
+ },
82
+ {
83
+ name: "Text-Integer Conversion round-trip string.hex.string",
84
+ input: "\"CyberChef\"",
85
+ expectedOutput: "CyberChef",
86
+ recipeConfig: [
87
+ {
88
+ op: "Text-Integer Conversion",
89
+ args: ["Hexadecimal"],
90
+ },
91
+ {
92
+ op: "Text-Integer Conversion",
93
+ args: ["String"],
94
+ },
95
+ ],
96
+ },
97
+ {
98
+ name: "Text-Integer Conversion implicit round trip string-string Latin-1",
99
+ input: "U+00FF",
100
+ expectedOutput: "U+00FF", // U+00FF (Latin small letter y with diaeresis)
101
+ recipeConfig: [
102
+ {
103
+ op: "Unescape Unicode Characters",
104
+ args: ["U+"],
105
+ },
106
+ {
107
+ op: "Text-Integer Conversion",
108
+ args: ["String"],
109
+ },
110
+ {
111
+ op: "Escape Unicode Characters",
112
+ args: ["U+", false, 4, true],
113
+ },
114
+ ],
115
+ },
116
+ {
117
+ name: "Text-Integer Conversion unquoted text to decimal",
118
+ input: "Hi",
119
+ expectedOutput: "18537",
120
+ recipeConfig: [
121
+ {
122
+ op: "Text-Integer Conversion",
123
+ args: ["Decimal"],
124
+ },
125
+ ],
126
+ },
127
+ {
128
+ name: "Text-Integer Conversion single character",
129
+ input: "\"A\"",
130
+ expectedOutput: "65",
131
+ recipeConfig: [
132
+ {
133
+ op: "Text-Integer Conversion",
134
+ args: ["Decimal"],
135
+ },
136
+ ],
137
+ },
138
+ {
139
+ name: "Text-Integer Conversion hex to decimal conversion",
140
+ input: "0xFF",
141
+ expectedOutput: "255",
142
+ recipeConfig: [
143
+ {
144
+ op: "Text-Integer Conversion",
145
+ args: ["Decimal"],
146
+ },
147
+ ],
148
+ },
149
+ {
150
+ name: "Text-Integer Conversion decimal to hex conversion",
151
+ input: "255",
152
+ expectedOutput: "0xff",
153
+ recipeConfig: [
154
+ {
155
+ op: "Text-Integer Conversion",
156
+ args: ["Hexadecimal"],
157
+ },
158
+ ],
159
+ },
160
+ {
161
+ name: "Text-Integer Conversion large number to string",
162
+ input: "113091951015816448506195587157728348242683688608116",
163
+ expectedOutput: "Mary had a little cat",
164
+ recipeConfig: [
165
+ {
166
+ op: "Text-Integer Conversion",
167
+ args: ["String"],
168
+ },
169
+ ],
170
+ },
171
+ {
172
+ name: "Text-Integer Conversion whitespace handling (quoted)",
173
+ input: "\" test \"",
174
+ expectedOutput: "2314978187545944096",
175
+ recipeConfig: [
176
+ {
177
+ op: "Text-Integer Conversion",
178
+ args: ["Decimal"],
179
+ },
180
+ ],
181
+ },
182
+ {
183
+ name: "Text-Integer Conversion non-Latin1 character in input",
184
+ input: "61 ce 93 61",
185
+ expectedOutput:
186
+ `Character at position 1 exceeds Latin-1 range (0-255).
187
+ Only ASCII and Latin-1 characters are supported.`,
188
+ recipeConfig: [
189
+ {
190
+ "op": "From Hex",
191
+ "args": ["Auto"]
192
+ },
193
+ {
194
+ op: "Text-Integer Conversion",
195
+ args: ["Decimal"],
196
+ },
197
+ ],
198
+ },
199
+ ]);
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Audio file headers in various formats for use in tests.
3
+ *
4
+ * Each constant contains the minimal bytes needed for container
5
+ * detection and metadata extraction (trimmed from real audio files).
6
+ *
7
+ * @author d0s1nt [d0s1nt@cyberchefaudio]
8
+ * @copyright Crown Copyright 2025
9
+ * @license Apache-2.0
10
+ */
11
+
12
+ /**
13
+ * MP3 with ID3v2.4 header — title: Galway, artist: Kevin MacLeod
14
+ * 78 bytes: ID3v2 header + TIT2 + TPE1 + TSSE frames
15
+ */
16
+ export const MP3_HEX = "4944330400000000004e544954320000000800000347616c77617900545045310000000f0000034b6576696e204d61634c656f6400545353450000000f0000034c61766635362e34302e3130310000000000000000000000";
17
+
18
+ /**
19
+ * WAV (RIFF/WAVE) header — 2 channels, 16-bit, 44100 Hz
20
+ * 48 bytes: RIFF header + fmt chunk + data chunk start
21
+ */
22
+ export const WAV_HEX = "52494646e69d2a0057415645666d7420100000000100020044ac000010b102000400100064617461489d2a0000000100";
23
+
24
+ /**
25
+ * FLAC with streaminfo + Vorbis comment block — title: Galway, artist: Kevin MacLeod
26
+ * 174 bytes: fLaC magic + STREAMINFO (34 bytes) + VORBIS_COMMENT block (86 bytes)
27
+ */
28
+ export const FLAC_HEX = "664c6143000000221200120000052e00319f0ac442f0000aa752c925754a50e5f02e117eeb46467e7053040000560d0000004c61766635362e34302e313031030000000c0000007469746c653d47616c776179140000006172746973743d4b6576696e204d61634c656f6415000000656e636f6465723d4c61766635362e34302e313031";
29
+
30
+ /**
31
+ * AAC ADTS frame header — MPEG-4, LC profile, 44100 Hz, stereo
32
+ * 32 bytes: ADTS sync + frame header fields
33
+ */
34
+ export const AAC_HEX = "fff150800bbffcde02004c61766335382e33342e31303000423590002000001e";
35
+
36
+ /**
37
+ * AC3 (Dolby Digital) sync frame header — 44100 Hz, 192 kbps, 2.0 stereo
38
+ * 32 bytes: AC3 sync word + BSI fields
39
+ */
40
+ export const AC3_HEX = "0b773968544043e106f575f0d4da1c1ac159850953e549a125736e8d37359d3f";
41
+
42
+ /**
43
+ * OGG Vorbis — two OGG pages with identification + comment headers
44
+ * title: Galway, artist: Kevin MacLeod, vendor: Lavf56.40.101
45
+ * 281 bytes
46
+ */
47
+ export const OGG_HEX = "4f6767530002000000000000000027a7032a000000002acbc833011e01766f72626973000000000244ac00000000000080b5010000000000b8014f6767530000000000000000000027a7032a010000007e1abea41168ffffffffffffffffffffffffffffff0703766f726269730d0000004c61766635362e34302e313031030000001f000000656e636f6465723d4c61766335362e36302e313030206c6962766f726269730c0000007469746c653d47616c776179140000006172746973743d4b6576696e204d61634c656f64";
48
+
49
+ /**
50
+ * Opus — two OGG pages with OpusHead + OpusTags headers
51
+ * title: Galway, artist: Kevin MacLeod, vendor: Lavf58.19.102
52
+ * 233 bytes
53
+ */
54
+ export const OPUS_HEX = "4f67675300020000000000000000919a59f200000000f6117eb601134f707573486561640102380180bb00000000004f67675300000000000000000000919a59f201000000b047e56601664f707573546167730d0000004c61766635382e31392e313032030000001d000000656e636f6465723d4c61766335382e33342e313030206c69626f7075730c0000007469746c653d47616c776179140000006172746973743d4b6576696e204d61634c656f64";
55
+
56
+ /**
57
+ * WMA/ASF — ASF header with Content Description + Extended Content
58
+ * title: Galway, author: Kevin MacLeod, encoder: Lavf56.40.101
59
+ * 700 bytes: ASF Header Object + all sub-objects
60
+ */
61
+ export const WMA_HEX = "3026b2758e66cf11a6d900aa0062ce6c8a02000000000000060000000102a1dcab8c47a9cf118ee400c00c205365680000000000000000000000000000000000000000000000bc3504000000000000803ed5deb19d0156000000000000007040490b00000000b03a7009000000001c0c00000000000002000000800c0000800c000000f40100b503bf5f2ea9cf118ee300c00c2053652e0000000000000011d2d3abbaa9cf118ee600c00c2053650600000000003326b2758e66cf11a6d900aa0062ce6c4c000000000000000e001c00000000000000470061006c0077006100790000004b006500760069006e0020004d00610063004c0065006f006400000040a4d0d207e3d21197f000a0c95ea850b40000000000000003000c007400690074006c006500000000000e00470061006c0077006100790000000e0041007500740068006f007200000000001c004b006500760069006e0020004d00610063004c0065006f0064000000280057004d002f0045006e0063006f00640069006e006700530065007400740069006e0067007300000000001c004c00610076006600350036002e00340030002e0031003000310000009107dcb7b7a9cf118ee600c00c2053657200000000000000409e69f84d5bcf11a8fd00805f5c442b50cdc3bf8f61cf118bb200aa00b4e22000000000000000001c000000080000000100000000006101020044ac0000803e0000e70210000a000000000001000000000001e702e7020100004052d1861d31d011a3a400a0c90348f664000000000000004152d1861d31d011a3a400a0c90348f60100000002001700570069006e0064006f007700730020004d006500640069006100200041007500640069006f0020005600380000000000020061013626b2758e66cf11a6d900aa0062ce6c32330400000000000000000000000000000000000000000056000000000000000101";
62
+
63
+ /**
64
+ * M4A (MPEG-4 Audio) — ftyp atom with brand "M4A ", plus mdat
65
+ * 512 bytes: ftyp + free + mdat start (moov not included in slice)
66
+ */
67
+ export const M4A_HEX = "0000001c667479704d344120000002004d34412069736f6d69736f3200000008667265650003e2236d6461742111450014500146fff10a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5de98214b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4b4bc211a93a09c3e310803595989841e21e02814c4d2f28f925da49e5fe61d4521f0088400d65662610788780a0563ab2a671af1d0cd2fd9997d18be037ff8852d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d";
68
+
69
+ /**
70
+ * AIFF (FORM/AIFF) header with NAME chunk = "Galway", COMM and SSND chunks
71
+ * 36 bytes: FORM header + NAME chunk + COMM chunk start
72
+ */
73
+ export const AIFF_HEX = "464f524d002a9d84414946464e414d450000000647616c776179434f4d4d00000012000200";
@@ -18,18 +18,6 @@ export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffc
18
18
  */
19
19
  export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082";
20
20
 
21
- /**
22
- * The CyberChef logo with 'chef'
23
- * 32x32
24
- */
25
- export const PNG_CHEF_B64 = "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";
26
-
27
- /**
28
- * The CyberChef logo with blur
29
- * 32x32
30
- */
31
- export const PNG_BLUR_B64 = "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";
32
-
33
21
  /**
34
22
  * Sunglasses smiley
35
23
  * 32x32
package/webpack.config.js CHANGED
@@ -120,17 +120,20 @@ module.exports = {
120
120
  jquery: "jquery/src/jquery",
121
121
  },
122
122
  fallback: {
123
- "fs": false,
123
+ "assert": require.resolve("assert/"),
124
+ "buffer": require.resolve("buffer/"),
124
125
  "child_process": false,
126
+ "crypto": require.resolve("crypto-browserify"),
127
+ "events": require.resolve("events/"),
128
+ "fs": false,
125
129
  "net": false,
126
- "tls": false,
127
130
  "path": require.resolve("path/"),
128
- "buffer": require.resolve("buffer/"),
129
- "crypto": require.resolve("crypto-browserify"),
130
- "stream": require.resolve("stream-browserify"),
131
- "zlib": require.resolve("browserify-zlib"),
132
131
  "process": false,
133
- "vm": false
132
+ "stream": require.resolve("stream-browserify"),
133
+ "tls": false,
134
+ "url": require.resolve("url/"),
135
+ "vm": false,
136
+ "zlib": require.resolve("browserify-zlib")
134
137
  }
135
138
  },
136
139
  module: {
@@ -1,251 +0,0 @@
1
- /**
2
- * Image manipulation resources
3
- *
4
- * @author j433866 [j433866@gmail.com]
5
- * @copyright Crown Copyright 2019
6
- * @license Apache-2.0
7
- */
8
-
9
- import OperationError from "../errors/OperationError.mjs";
10
-
11
- /**
12
- * Gaussian blurs an image.
13
- *
14
- * @param {jimp} input
15
- * @param {number} radius
16
- * @param {boolean} fast
17
- * @returns {jimp}
18
- */
19
- export function gaussianBlur (input, radius) {
20
- try {
21
- // From http://blog.ivank.net/fastest-gaussian-blur.html
22
- const boxes = boxesForGauss(radius, 3);
23
- for (let i = 0; i < 3; i++) {
24
- input = boxBlur(input, (boxes[i] - 1) / 2);
25
- }
26
- } catch (err) {
27
- throw new OperationError(`Error blurring image. (${err})`);
28
- }
29
-
30
- return input;
31
- }
32
-
33
- /**
34
- *
35
- * @param {number} radius
36
- * @param {number} numBoxes
37
- * @returns {Array}
38
- */
39
- function boxesForGauss(radius, numBoxes) {
40
- const idealWidth = Math.sqrt((12 * radius * radius / numBoxes) + 1);
41
-
42
- let wl = Math.floor(idealWidth);
43
-
44
- if (wl % 2 === 0) {
45
- wl--;
46
- }
47
-
48
- const wu = wl + 2;
49
-
50
- const mIdeal = (12 * radius * radius - numBoxes * wl * wl - 4 * numBoxes * wl - 3 * numBoxes) / (-4 * wl - 4);
51
- const m = Math.round(mIdeal);
52
-
53
- const sizes = [];
54
- for (let i = 0; i < numBoxes; i++) {
55
- sizes.push(i < m ? wl : wu);
56
- }
57
- return sizes;
58
- }
59
-
60
- /**
61
- * Applies a box blur effect to the image
62
- *
63
- * @param {jimp} source
64
- * @param {number} radius
65
- * @returns {jimp}
66
- */
67
- function boxBlur (source, radius) {
68
- const width = source.bitmap.width;
69
- const height = source.bitmap.height;
70
- let output = source.clone();
71
- output = boxBlurH(source, output, width, height, radius);
72
- source = boxBlurV(output, source, width, height, radius);
73
-
74
- return source;
75
- }
76
-
77
- /**
78
- * Applies the horizontal blur
79
- *
80
- * @param {jimp} source
81
- * @param {jimp} output
82
- * @param {number} width
83
- * @param {number} height
84
- * @param {number} radius
85
- * @returns {jimp}
86
- */
87
- function boxBlurH (source, output, width, height, radius) {
88
- const iarr = 1 / (radius + radius + 1);
89
- for (let i = 0; i < height; i++) {
90
- let ti = 0,
91
- li = ti,
92
- ri = ti + radius;
93
- const idx = source.getPixelIndex(ti, i);
94
- const firstValRed = source.bitmap.data[idx],
95
- firstValGreen = source.bitmap.data[idx + 1],
96
- firstValBlue = source.bitmap.data[idx + 2],
97
- firstValAlpha = source.bitmap.data[idx + 3];
98
-
99
- const lastIdx = source.getPixelIndex(width - 1, i),
100
- lastValRed = source.bitmap.data[lastIdx],
101
- lastValGreen = source.bitmap.data[lastIdx + 1],
102
- lastValBlue = source.bitmap.data[lastIdx + 2],
103
- lastValAlpha = source.bitmap.data[lastIdx + 3];
104
-
105
- let red = (radius + 1) * firstValRed;
106
- let green = (radius + 1) * firstValGreen;
107
- let blue = (radius + 1) * firstValBlue;
108
- let alpha = (radius + 1) * firstValAlpha;
109
-
110
- for (let j = 0; j < radius; j++) {
111
- const jIdx = source.getPixelIndex(ti + j, i);
112
- red += source.bitmap.data[jIdx];
113
- green += source.bitmap.data[jIdx + 1];
114
- blue += source.bitmap.data[jIdx + 2];
115
- alpha += source.bitmap.data[jIdx + 3];
116
- }
117
-
118
- for (let j = 0; j <= radius; j++) {
119
- const jIdx = source.getPixelIndex(ri++, i);
120
- red += source.bitmap.data[jIdx] - firstValRed;
121
- green += source.bitmap.data[jIdx + 1] - firstValGreen;
122
- blue += source.bitmap.data[jIdx + 2] - firstValBlue;
123
- alpha += source.bitmap.data[jIdx + 3] - firstValAlpha;
124
-
125
- const tiIdx = source.getPixelIndex(ti++, i);
126
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
127
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
128
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
129
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
130
- }
131
-
132
- for (let j = radius + 1; j < width - radius; j++) {
133
- const riIdx = source.getPixelIndex(ri++, i);
134
- const liIdx = source.getPixelIndex(li++, i);
135
- red += source.bitmap.data[riIdx] - source.bitmap.data[liIdx];
136
- green += source.bitmap.data[riIdx + 1] - source.bitmap.data[liIdx + 1];
137
- blue += source.bitmap.data[riIdx + 2] - source.bitmap.data[liIdx + 2];
138
- alpha += source.bitmap.data[riIdx + 3] - source.bitmap.data[liIdx + 3];
139
-
140
- const tiIdx = source.getPixelIndex(ti++, i);
141
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
142
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
143
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
144
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
145
- }
146
-
147
- for (let j = width - radius; j < width; j++) {
148
- const liIdx = source.getPixelIndex(li++, i);
149
- red += lastValRed - source.bitmap.data[liIdx];
150
- green += lastValGreen - source.bitmap.data[liIdx + 1];
151
- blue += lastValBlue - source.bitmap.data[liIdx + 2];
152
- alpha += lastValAlpha - source.bitmap.data[liIdx + 3];
153
-
154
- const tiIdx = source.getPixelIndex(ti++, i);
155
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
156
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
157
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
158
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
159
- }
160
- }
161
- return output;
162
- }
163
-
164
- /**
165
- * Applies the vertical blur
166
- *
167
- * @param {jimp} source
168
- * @param {jimp} output
169
- * @param {number} width
170
- * @param {number} height
171
- * @param {number} radius
172
- * @returns {jimp}
173
- */
174
- function boxBlurV (source, output, width, height, radius) {
175
- const iarr = 1 / (radius + radius + 1);
176
- for (let i = 0; i < width; i++) {
177
- let ti = 0,
178
- li = ti,
179
- ri = ti + radius;
180
-
181
- const idx = source.getPixelIndex(i, ti);
182
-
183
- const firstValRed = source.bitmap.data[idx],
184
- firstValGreen = source.bitmap.data[idx + 1],
185
- firstValBlue = source.bitmap.data[idx + 2],
186
- firstValAlpha = source.bitmap.data[idx + 3];
187
-
188
- const lastIdx = source.getPixelIndex(i, height - 1),
189
- lastValRed = source.bitmap.data[lastIdx],
190
- lastValGreen = source.bitmap.data[lastIdx + 1],
191
- lastValBlue = source.bitmap.data[lastIdx + 2],
192
- lastValAlpha = source.bitmap.data[lastIdx + 3];
193
-
194
- let red = (radius + 1) * firstValRed;
195
- let green = (radius + 1) * firstValGreen;
196
- let blue = (radius + 1) * firstValBlue;
197
- let alpha = (radius + 1) * firstValAlpha;
198
-
199
- for (let j = 0; j < radius; j++) {
200
- const jIdx = source.getPixelIndex(i, ti + j);
201
- red += source.bitmap.data[jIdx];
202
- green += source.bitmap.data[jIdx + 1];
203
- blue += source.bitmap.data[jIdx + 2];
204
- alpha += source.bitmap.data[jIdx + 3];
205
- }
206
-
207
- for (let j = 0; j <= radius; j++) {
208
- const riIdx = source.getPixelIndex(i, ri++);
209
- red += source.bitmap.data[riIdx] - firstValRed;
210
- green += source.bitmap.data[riIdx + 1] - firstValGreen;
211
- blue += source.bitmap.data[riIdx + 2] - firstValBlue;
212
- alpha += source.bitmap.data[riIdx + 3] - firstValAlpha;
213
-
214
- const tiIdx = source.getPixelIndex(i, ti++);
215
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
216
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
217
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
218
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
219
- }
220
-
221
- for (let j = radius + 1; j < height - radius; j++) {
222
- const riIdx = source.getPixelIndex(i, ri++);
223
- const liIdx = source.getPixelIndex(i, li++);
224
- red += source.bitmap.data[riIdx] - source.bitmap.data[liIdx];
225
- green += source.bitmap.data[riIdx + 1] - source.bitmap.data[liIdx + 1];
226
- blue += source.bitmap.data[riIdx + 2] - source.bitmap.data[liIdx + 2];
227
- alpha += source.bitmap.data[riIdx + 3] - source.bitmap.data[liIdx + 3];
228
-
229
- const tiIdx = source.getPixelIndex(i, ti++);
230
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
231
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
232
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
233
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
234
- }
235
-
236
- for (let j = height - radius; j < height; j++) {
237
- const liIdx = source.getPixelIndex(i, li++);
238
- red += lastValRed - source.bitmap.data[liIdx];
239
- green += lastValGreen - source.bitmap.data[liIdx + 1];
240
- blue += lastValBlue - source.bitmap.data[liIdx + 2];
241
- alpha += lastValAlpha - source.bitmap.data[liIdx + 3];
242
-
243
- const tiIdx = source.getPixelIndex(i, ti++);
244
- output.bitmap.data[tiIdx] = Math.round(red * iarr);
245
- output.bitmap.data[tiIdx + 1] = Math.round(green * iarr);
246
- output.bitmap.data[tiIdx + 2] = Math.round(blue * iarr);
247
- output.bitmap.data[tiIdx + 3] = Math.round(alpha * iarr);
248
- }
249
- }
250
- return output;
251
- }