From b765534b8b2a0454a5132a0a52d1d8844bcbdaaa Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 24 Mar 2020 11:06:37 +0000 Subject: [PATCH] Tidied up the Magic operation --- src/core/config/scripts/generateConfig.mjs | 24 +- src/core/lib/Magic.mjs | 231 ++++++++---------- src/core/lib/MagicCriteria.mjs | 12 - src/core/operations/A1Z26CipherDecode.mjs | 66 +++-- src/core/operations/BaconCipherDecode.mjs | 86 ++++--- src/core/operations/Bzip2Decompress.mjs | 16 +- src/core/operations/DechunkHTTPResponse.mjs | 16 +- src/core/operations/DecodeNetBIOSName.mjs | 16 +- src/core/operations/DefangIPAddresses.mjs | 30 +-- .../operations/EscapeUnicodeCharacters.mjs | 36 ++- src/core/operations/FromBCD.mjs | 18 +- src/core/operations/FromBase32.mjs | 15 +- src/core/operations/FromBase58.mjs | 27 +- src/core/operations/FromBase64.mjs | 138 +++++------ src/core/operations/FromBinary.mjs | 78 +++--- src/core/operations/FromDecimal.mjs | 66 +++-- src/core/operations/FromHTMLEntity.mjs | 16 +- src/core/operations/FromHex.mjs | 106 ++++---- src/core/operations/FromHexContent.mjs | 16 +- src/core/operations/FromHexdump.mjs | 18 +- src/core/operations/FromMorseCode.mjs | 16 +- src/core/operations/FromOctal.mjs | 66 +++-- src/core/operations/FromQuotedPrintable.mjs | 18 +- src/core/operations/FromUNIXTimestamp.mjs | 46 ++-- src/core/operations/Gunzip.mjs | 16 +- src/core/operations/ObjectIdentifierToHex.mjs | 11 - src/core/operations/ParseQRCode.mjs | 18 +- src/core/operations/ParseSSHHostKey.mjs | 16 +- .../operations/ParseUNIXFilePermissions.mjs | 16 +- src/core/operations/ParseUserAgent.mjs | 16 +- src/core/operations/ParseX509Certificate.mjs | 16 +- src/core/operations/RawInflate.mjs | 12 +- src/core/operations/RenderImage.mjs | 24 +- src/core/operations/StripHTMLTags.mjs | 16 +- src/core/operations/StripHTTPHeaders.mjs | 16 +- src/core/operations/URLDecode.mjs | 18 +- src/core/operations/Untar.mjs | 16 +- src/core/operations/Unzip.mjs | 16 +- src/core/operations/ZlibInflate.mjs | 18 +- tests/lib/TestRegister.mjs | 6 +- tests/operations/samples/Images.mjs | 43 ++++ tests/operations/tests/Image.mjs | 23 +- tests/operations/tests/Magic.mjs | 177 ++++++++------ 43 files changed, 771 insertions(+), 900 deletions(-) delete mode 100644 src/core/lib/MagicCriteria.mjs create mode 100644 tests/operations/samples/Images.mjs diff --git a/src/core/config/scripts/generateConfig.mjs b/src/core/config/scripts/generateConfig.mjs index 6e090652..64c7cb81 100644 --- a/src/core/config/scripts/generateConfig.mjs +++ b/src/core/config/scripts/generateConfig.mjs @@ -43,31 +43,9 @@ for (const opObj in Ops) { flowControl: op.flowControl, manualBake: op.manualBake, args: op.args, + checks: op.checks }; - if ("checks" in op) { - if ("input" in op.checks) { - operationConfig[op.name].input = {}; - if ("regex" in op.checks.input) { - operationConfig[op.name].input.regex = op.checks.input.regex; - } - if ("entropy" in op.checks.input) { - operationConfig[op.name].input.entropy = op.checks.input.entropy; - } - } - if ("output" in op.checks) { - operationConfig[op.name].output = {}; - if ("regex" in op.checks.output) { - operationConfig[op.name].output.regex = op.checks.output.regex; - } - if ("entropy" in op.checks.output) { - operationConfig[op.name].output.entropy = op.checks.output.entropy; - } - if ("mime" in op.checks.output) { - operationConfig[op.name].output.mime = op.checks.output.mime; - } - } - } if (!(op.module in modules)) modules[op.module] = {}; modules[op.module][op.name] = opObj; diff --git a/src/core/lib/Magic.mjs b/src/core/lib/Magic.mjs index b4decbe9..983b9aed 100644 --- a/src/core/lib/Magic.mjs +++ b/src/core/lib/Magic.mjs @@ -19,66 +19,40 @@ class Magic { * Magic constructor. * * @param {ArrayBuffer} buf - * @param {Object} prevOp + * @param {Object[]} [opCriteria] + * @param {Object} [prevOp] */ - constructor(buf, opPatterns, prevOp) { + constructor(buf, opCriteria=Magic._generateOpCriteria(), prevOp=null) { this.inputBuffer = new Uint8Array(buf); this.inputStr = Utils.arrayBufferToStr(buf); - this.opPatterns = opPatterns || Magic._generateOpCriteria(); + this.opCriteria = opCriteria; this.prevOp = prevOp; } /** - * Finds operations that claim to be able to decode the input based on - * regular expression matches. - * - * @param {[Object]} opPatterns - * @returns {Array} - */ - inputRegexMatch(opPatterns) { - const matches = []; - - for (let i = 0; i < opPatterns.length; i++) { - const pattern = opPatterns[i]; - - - if (pattern.match.test(this.inputStr)) { - matches.push(pattern); - } - } - - return matches; - } - - /** - * Finds operations that claim to be able to decode the input based on entropy - * matches. - * - * @param {[Object]} opPatterns - * @returns {Array} - */ - entropyInputMatch(opPatterns) { - const matches = []; - - const entropyOfInput = this.calcEntropy(); - - for (let i = 0; i < opPatterns.length; i++) { - const currOp = opPatterns[i]; - if ((entropyOfInput > currOp.entropy[0]) && (entropyOfInput < currOp.entropy[1])) - matches.push(currOp); - } - return matches; - } - - /** - * Finds operations that claim to be able to decode the input based on criteria. + * Finds operations that claim to be able to decode the input based on various criteria. * * @returns {Object[]} */ findMatchingInputOps() { - let matches = this.inputRegexMatch(this.opPatterns.regex); - matches = matches.concat(this.entropyInputMatch(this.opPatterns.entropy)); - return [...new Set(matches)]; + const matches = [], + inputEntropy = this.calcEntropy(); + + 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; + + matches.push(check); + }); + + return matches; } /** @@ -218,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; @@ -228,6 +204,8 @@ class Magic { if (p === 0) continue; entropy += p * Math.log(p) / Math.log(2); } + + if (!standalone) this.inputEntropy = -entropy; return -entropy; } @@ -298,32 +276,29 @@ class Magic { } /** + * Checks whether the data passes output criteria for an operation check * + * @param {ArrayBuffer} data + * @param {Object} criteria + * @returns {boolean} */ - checkRegexes(regexes) { - for (const elem of regexes) { - const regex = new RegExp(elem.match, elem.flags); - if (regex.test(this.inputStr)) - return true; + outputCheckPasses(data, criteria) { + if (criteria.pattern) { + const dataStr = Utils.arrayBufferToStr(data), + regex = new RegExp(criteria.pattern, criteria.flags); + if (!regex.test(dataStr)) + return false; } - return false; - } - /** - * - */ - checkOutputFromPrevious() { - let score = 0; - if ("regex" in this.prevOp.output) { - if (this.checkRegexes(this.prevOp.output.regex)) score++; + if (criteria.entropyRange) { + const dataEntropy = this.calcEntropy(data, true); + if (dataEntropy < criteria.entropyRange[0] || dataEntropy > criteria.entropyRange[1]) + return false; } - if ("entropy" in this.prevOp.output) { - const inputEntropy = this.calcEntropy(); - if ((inputEntropy > this.prevOp.output.entropy[0]) && (inputEntropy < this.prevOp.output.entropy[1])) score++; - } - if ("mime" in this.prevOp.output) { - if (isType(this.prevOp.output.mime, this.inputBuffer)) score++; - } - return score > 0; + if (criteria.mime && + !isType(criteria.mime, data)) + return false; + + return true; } /** @@ -331,26 +306,27 @@ class Magic { * * @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 - - if (this.prevOp) { - if ("output" in this.prevOp) { - if (!(this.checkOutputFromPrevious())) { - return []; - } - } - } const matchingOps = this.findMatchingInputOps(); let results = []; @@ -374,20 +350,24 @@ class Magic { const opConfig = { op: op.op, args: op.args - }, 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; - } + }, + output = await this._runRecipe([opConfig]); // If the recipe returned an empty buffer, do not continue if (_buffersEqual(output, new ArrayBuffer())) { return; } + // If the recipe is repeating and returning the same data, do not continue + if (prevOp && op.op === prevOp.op && _buffersEqual(output, this.inputBuffer)) { + return; + } - const magic = new Magic(output, this.opPatterns, OperationConfig[op.op]), + // 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); @@ -399,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, undefined), + const magic = new Magic(enc.data, this.opCriteria, undefined), bfResults = await magic.speculativeExecution( depth-1, extLang, false, [...recipeConfig, enc.conf], false, crib); @@ -414,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 ) ); @@ -445,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; }); @@ -486,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; @@ -501,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; } /** @@ -517,30 +503,25 @@ class Magic { * @returns {Object[]} */ static _generateOpCriteria() { - const opCriteria = { - regex: [], - entropy: [] - }; + const opCriteria = []; for (const op in OperationConfig) { - if ("input" in OperationConfig[op]) { - if ("regex" in OperationConfig[op].input) - OperationConfig[op].input.regex.forEach(pattern => { - opCriteria.regex.push({ - op: op, - match: new RegExp(pattern.match, pattern.flags), - args: pattern.args, - useful: pattern.useful || false - }); - }); - if ("entropy" in OperationConfig[op].input) { - opCriteria.entropy.push({ - op: op, - entropy: OperationConfig[op].input.entropy.input, - args: OperationConfig[op].input.entropy.args - }); - } - } + if (!("checks" in OperationConfig[op])) + continue; + + 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, + pattern: check.pattern ? new RegExp(check.pattern, check.flags) : null, + args: check.args, + useful: check.useful, + entropyRange: check.entropyRange, + output: check.output + }); + }); } return opCriteria; diff --git a/src/core/lib/MagicCriteria.mjs b/src/core/lib/MagicCriteria.mjs deleted file mode 100644 index 6cf889a1..00000000 --- a/src/core/lib/MagicCriteria.mjs +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Constants for the entropy of text. - * - * @author n1073645 [n1073645@gmail.com] - * @copyright Crown Copyright 2020 - * @license Apache-2.0 -*/ -export const compressedToDecompressed = [6.5, 8]; - -export const binary = [1, 1.5]; - -export const entropyOfText = [3.5, 6]; diff --git a/src/core/operations/A1Z26CipherDecode.mjs b/src/core/operations/A1Z26CipherDecode.mjs index 4f4022fa..0b097c2b 100644 --- a/src/core/operations/A1Z26CipherDecode.mjs +++ b/src/core/operations/A1Z26CipherDecode.mjs @@ -33,42 +33,38 @@ class A1Z26CipherDecode extends Operation { value: DELIM_OPTIONS } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\s*([12]?[0-9] )+[12]?[0-9]\\s*$", - flags: "", - args: ["Space"] - }, - { - match: "^\\s*([12]?[0-9],)+[12]?[0-9]\\s*$", - flags: "", - args: ["Comma"] - }, - { - match: "^\\s*([12]?[0-9];)+[12]?[0-9]\\s*$", - flags: "", - args: ["Semi-colon"] - }, - { - match: "^\\s*([12]?[0-9]:)+[12]?[0-9]\\s*$", - flags: "", - args: ["Colon"] - }, - { - match: "^\\s*([12]?[0-9]\\n)+[12]?[0-9]\\s*$", - flags: "", - args: ["Line feed"] - }, - { - match: "^\\s*([12]?[0-9]\\r\\n)+[12]?[0-9]\\s*$", - flags: "", - args: ["CRLF"] - } - ] + 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"] } - }; + ]; } /** diff --git a/src/core/operations/BaconCipherDecode.mjs b/src/core/operations/BaconCipherDecode.mjs index 81aa3846..40eba6bb 100644 --- a/src/core/operations/BaconCipherDecode.mjs +++ b/src/core/operations/BaconCipherDecode.mjs @@ -44,52 +44,48 @@ class BaconCipherDecode extends Operation { "value": false } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\s*([01]{5}\\s?)+$", - flags: "", - args: ["Standard (I=J and U=V)", "0/1", false] - }, - { - match: "^\\s*([01]{5}\\s?)+$", - flags: "", - args: ["Standard (I=J and U=V)", "0/1", true] - }, - { - match: "^\\s*([AB]{5}\\s?)+$", - flags: "", - args: ["Standard (I=J and U=V)", "A/B", false] - }, - { - match: "^\\s*([AB]{5}\\s?)+$", - flags: "", - args: ["Standard (I=J and U=V)", "A/B", true] - }, - { - match: "^\\s*([01]{5}\\s?)+$", - flags: "", - args: ["Complete", "0/1", false] - }, - { - match: "^\\s*([01]{5}\\s?)+$", - flags: "", - args: ["Complete", "0/1", true] - }, - { - match: "^\\s*([AB]{5}\\s?)+$", - flags: "", - args: ["Complete", "A/B", false] - }, - { - match: "^\\s*([AB]{5}\\s?)+$", - flags: "", - args: ["Complete", "A/B", true] - } - ] + 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] } - }; + ]; } /** diff --git a/src/core/operations/Bzip2Decompress.mjs b/src/core/operations/Bzip2Decompress.mjs index 7b110820..fe419265 100644 --- a/src/core/operations/Bzip2Decompress.mjs +++ b/src/core/operations/Bzip2Decompress.mjs @@ -33,17 +33,13 @@ class Bzip2Decompress extends Operation { value: false } ]; - this.checks = { - input: { - regex: [ - { - "match": "^\\x42\\x5a\\x68", - "flags": "", - "args": [] - } - ] + this.checks = [ + { + "pattern": "^\\x42\\x5a\\x68", + "flags": "", + "args": [] } - }; + ]; } /** diff --git a/src/core/operations/DechunkHTTPResponse.mjs b/src/core/operations/DechunkHTTPResponse.mjs index c8e008ea..da2eb437 100644 --- a/src/core/operations/DechunkHTTPResponse.mjs +++ b/src/core/operations/DechunkHTTPResponse.mjs @@ -24,17 +24,13 @@ class DechunkHTTPResponse extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*[0-9A-F]+\r\n", - flags: "i", - args: [] - } - ] + this.checks = [ + { + pattern: "^[0-9A-F]+\r\n", + flags: "i", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/DecodeNetBIOSName.mjs b/src/core/operations/DecodeNetBIOSName.mjs index 2430043d..c726f5d8 100644 --- a/src/core/operations/DecodeNetBIOSName.mjs +++ b/src/core/operations/DecodeNetBIOSName.mjs @@ -30,17 +30,13 @@ class DecodeNetBIOSName extends Operation { "value": 65 } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\s*\\S{32}$", - flags: "", - args: [65] - } - ] + this.checks = [ + { + pattern: "^\\s*\\S{32}$", + flags: "", + args: [65] } - }; + ]; } /** diff --git a/src/core/operations/DefangIPAddresses.mjs b/src/core/operations/DefangIPAddresses.mjs index cecfab9c..a869f114 100644 --- a/src/core/operations/DefangIPAddresses.mjs +++ b/src/core/operations/DefangIPAddresses.mjs @@ -25,27 +25,17 @@ class DefangIPAddresses extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*(([0-9]{1,3}\\.){3}[0-9]{1,3}|([0-9a-f]{4}:){7}[0-9a-f]{4})\\s*$", - flags: "i", - args: [], - } - ] - }, - output: { - regex: [ - { - match: "^\\s*(([0-9]{1,3}\\[\\.\\]){3}[0-9]{1,3}|([0-9a-f]{4}\\[\\:\\]){7}[0-9a-f]{4})\\s*$", - flags: "i", - shouldMatch: true, - 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" + } } - }; + ]; } /** diff --git a/src/core/operations/EscapeUnicodeCharacters.mjs b/src/core/operations/EscapeUnicodeCharacters.mjs index cbefd8c3..db2680c0 100644 --- a/src/core/operations/EscapeUnicodeCharacters.mjs +++ b/src/core/operations/EscapeUnicodeCharacters.mjs @@ -44,27 +44,23 @@ class EscapeUnicodeCharacters extends Operation { "value": true } ]; - this.checks = { - input: { - regex: [ - { - match: "\\\\u(?:[\\da-f]{4,6})", - flags: "i", - args: ["\\u"] - }, - { - match: "%u(?:[\\da-f]{4,6})", - flags: "i", - args: ["%u"] - }, - { - match: "U\\+(?:[\\da-f]{4,6})", - flags: "i", - args: ["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+"] } - }; + ]; } /** diff --git a/src/core/operations/FromBCD.mjs b/src/core/operations/FromBCD.mjs index 907d40c6..2fbc679f 100644 --- a/src/core/operations/FromBCD.mjs +++ b/src/core/operations/FromBCD.mjs @@ -49,17 +49,13 @@ class FromBCD extends Operation { "value": FORMAT } ]; - this.checks = { - input: { - regex: [ - { - match: "^(?:\\d{4} ){3,}\\d{4}$", - flags: "", - args: ["8 4 2 1", true, false, "Nibbles"] - }, - ] - } - }; + this.checks = [ + { + pattern: "^(?:\\d{4} ){3,}\\d{4}$", + flags: "", + args: ["8 4 2 1", true, false, "Nibbles"] + }, + ]; } /** diff --git a/src/core/operations/FromBase32.mjs b/src/core/operations/FromBase32.mjs index 5959a9e0..2715fdc1 100644 --- a/src/core/operations/FromBase32.mjs +++ b/src/core/operations/FromBase32.mjs @@ -36,18 +36,13 @@ class FromBase32 extends Operation { value: true } ]; - this.checks = { - input: + this.checks = [ { - regex: [ - { - 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})?$", - flags: "", - args: ["A-Z2-7=", false] - } - ] + 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] } - }; + ]; } /** diff --git a/src/core/operations/FromBase58.mjs b/src/core/operations/FromBase58.mjs index d14529e7..f5a9ac3d 100644 --- a/src/core/operations/FromBase58.mjs +++ b/src/core/operations/FromBase58.mjs @@ -38,23 +38,18 @@ class FromBase58 extends Operation { "value": true } ]; - this.checks = { - input: + this.checks = [ { - regex: [ - { - match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", - flags: "", - args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false] - }, - { - match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", - flags: "", - args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false] - }, - ] - } - }; + pattern: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false] + }, + { + pattern: "^[1-9A-HJ-NP-Za-km-z]{20,}$", + flags: "", + args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false] + }, + ]; } /** diff --git a/src/core/operations/FromBase64.mjs b/src/core/operations/FromBase64.mjs index 2a6c6cf4..4de2930f 100644 --- a/src/core/operations/FromBase64.mjs +++ b/src/core/operations/FromBase64.mjs @@ -36,77 +36,73 @@ class FromBase64 extends Operation { value: true } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\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*$", - flags: "i", - args: ["A-Za-z0-9-_", true] - }, - { - match: "^\\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*$", - flags: "i", - args: ["./0-9A-Za-z=", true] - }, - { - match: "^\\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*$", - flags: "i", - args: ["A-Za-z0-9._-", true] - }, - { - match: "^\\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*$", - flags: "i", - args: ["0-9A-Za-z+/=", true] - }, - { - match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$", - flags: "", - args: [" -_", false] - }, - { - match: "^\\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*$", - 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*$", - flags: "i", - args: ["N-ZA-Mn-za-m0-9+/=", true] - }, - { - match: "^\\s*[A-Z\\d./]{20,}\\s*$", - flags: "i", - args: ["./0-9A-Za-z", true] - }, - ], - } - }; + this.checks = [ + { + pattern: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$", + flags: "i", + args: ["A-Za-z0-9+/=", true] + }, + { + pattern: "^\\s*[A-Z\\d\\-_]{20,}\\s*$", + flags: "i", + args: ["A-Za-z0-9-_", true] + }, + { + pattern: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$", + flags: "i", + args: ["A-Za-z0-9+\\-=", true] + }, + { + pattern: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$", + flags: "i", + args: ["./0-9A-Za-z=", true] + }, + { + pattern: "^\\s*[A-Z\\d_.]{20,}\\s*$", + flags: "i", + args: ["A-Za-z0-9_.", true] + }, + { + pattern: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$", + flags: "i", + args: ["A-Za-z0-9._-", true] + }, + { + pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$", + flags: "i", + args: ["0-9a-zA-Z+/=", true] + }, + { + pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$", + flags: "i", + args: ["0-9A-Za-z+/=", true] + }, + { + pattern: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$", + flags: "", + args: [" -_", false] + }, + { + pattern: "^\\s*[A-Z\\d+\\-]{20,}\\s*$", + flags: "i", + args: ["+\\-0-9A-Za-z", true] + }, + { + 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] + }, + { + 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] + }, + { + pattern: "^\\s*[A-Z\\d./]{20,}\\s*$", + flags: "i", + args: ["./0-9A-Za-z", true] + }, + ]; } /** diff --git a/src/core/operations/FromBinary.mjs b/src/core/operations/FromBinary.mjs index b7f4cc2c..15e5d663 100644 --- a/src/core/operations/FromBinary.mjs +++ b/src/core/operations/FromBinary.mjs @@ -33,47 +33,43 @@ class FromBinary extends Operation { "value": BIN_DELIM_OPTIONS } ]; - this.checks = { - input: { - regex: [ - { - match: "^(?:[01]{8})+$", - flags: "", - args: ["None"] - }, - { - match: "^(?:[01]{8})(?: [01]{8})*$", - flags: "", - args: ["Space"] - }, - { - match: "^(?:[01]{8})(?:,[01]{8})*$", - flags: "", - args: ["Comma"] - }, - { - match: "^(?:[01]{8})(?:;[01]{8})*$", - flags: "", - args: ["Semi-colon"] - }, - { - match: "^(?:[01]{8})(?::[01]{8})*$", - flags: "", - args: ["Colon"] - }, - { - match: "^(?:[01]{8})(?:\\n[01]{8})*$", - flags: "", - args: ["Line feed"] - }, - { - match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$", - flags: "", - args: ["CRLF"] - }, - ] - } - }; + this.checks = [ + { + pattern: "^(?:[01]{8})+$", + flags: "", + args: ["None"] + }, + { + pattern: "^(?:[01]{8})(?: [01]{8})*$", + flags: "", + args: ["Space"] + }, + { + pattern: "^(?:[01]{8})(?:,[01]{8})*$", + flags: "", + args: ["Comma"] + }, + { + pattern: "^(?:[01]{8})(?:;[01]{8})*$", + flags: "", + args: ["Semi-colon"] + }, + { + pattern: "^(?:[01]{8})(?::[01]{8})*$", + flags: "", + args: ["Colon"] + }, + { + pattern: "^(?:[01]{8})(?:\\n[01]{8})*$", + flags: "", + args: ["Line feed"] + }, + { + pattern: "^(?:[01]{8})(?:\\r\\n[01]{8})*$", + flags: "", + args: ["CRLF"] + }, + ]; } /** diff --git a/src/core/operations/FromDecimal.mjs b/src/core/operations/FromDecimal.mjs index e1904a47..f98931d6 100644 --- a/src/core/operations/FromDecimal.mjs +++ b/src/core/operations/FromDecimal.mjs @@ -36,42 +36,38 @@ class FromDecimal extends Operation { "value": false } ]; - this.checks = { - input: { - regex: [ - { - 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]))*$", - 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]))*$", - 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]))*$", - 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]))*$", - 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]))*$", - 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]))*$", - flags: "", - args: ["CRLF", false] - } - ] + this.checks = [ + { + 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] + }, + { + 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] + }, + { + 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] + }, + { + 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] + }, + { + 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] + }, + { + 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] } - }; + ]; } /** diff --git a/src/core/operations/FromHTMLEntity.mjs b/src/core/operations/FromHTMLEntity.mjs index b4c94f8d..4d09876d 100644 --- a/src/core/operations/FromHTMLEntity.mjs +++ b/src/core/operations/FromHTMLEntity.mjs @@ -25,17 +25,13 @@ class FromHTMLEntity extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});", - flags: "i", - args: [] - } - ] + this.checks = [ + { + pattern: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});", + flags: "i", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/FromHex.mjs b/src/core/operations/FromHex.mjs index cccd7812..cd82d7df 100644 --- a/src/core/operations/FromHex.mjs +++ b/src/core/operations/FromHex.mjs @@ -32,62 +32,58 @@ class FromHex extends Operation { value: FROM_HEX_DELIM_OPTIONS } ]; - this.checks = { - input: { - regex: [ - { - match: "^(?:[\\dA-F]{2})+$", - flags: "i", - args: ["None"] - }, - { - match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$", - flags: "i", - args: ["Space"] - }, - { - match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$", - flags: "i", - args: ["Comma"] - }, - { - match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$", - flags: "i", - args: ["Semi-colon"] - }, - { - match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$", - flags: "i", - args: ["Colon"] - }, - { - match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$", - flags: "i", - args: ["Line feed"] - }, - { - match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$", - flags: "i", - args: ["CRLF"] - }, - { - match: "^(?:0x[\\dA-F]{2})+$", - flags: "i", - args: ["0x"] - }, - { - match: "^0x[\\dA-F]{2}(?:,0x[\\dA-F]{2})*$", - flags: "i", - args: ["0x with comma"] - }, - { - match: "^(?:\\\\x[\\dA-F]{2})+$", - flags: "i", - args: ["\\x"] - } - ] + this.checks = [ + { + pattern: "^(?:[\\dA-F]{2})+$", + flags: "i", + args: ["None"] + }, + { + pattern: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$", + flags: "i", + args: ["Space"] + }, + { + pattern: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$", + flags: "i", + args: ["Comma"] + }, + { + pattern: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$", + flags: "i", + args: ["Semi-colon"] + }, + { + pattern: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$", + flags: "i", + args: ["Colon"] + }, + { + pattern: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$", + flags: "i", + args: ["Line feed"] + }, + { + pattern: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$", + flags: "i", + args: ["CRLF"] + }, + { + pattern: "^(?:0x[\\dA-F]{2})+$", + flags: "i", + args: ["0x"] + }, + { + pattern: "^0x[\\dA-F]{2}(?:,0x[\\dA-F]{2})*$", + flags: "i", + args: ["0x with comma"] + }, + { + pattern: "^(?:\\\\x[\\dA-F]{2})+$", + flags: "i", + args: ["\\x"] } - }; + ]; } /** diff --git a/src/core/operations/FromHexContent.mjs b/src/core/operations/FromHexContent.mjs index 05f5087c..dc6c06f1 100644 --- a/src/core/operations/FromHexContent.mjs +++ b/src/core/operations/FromHexContent.mjs @@ -26,17 +26,13 @@ class FromHexContent extends Operation { this.inputType = "string"; this.outputType = "byteArray"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*.*?\\|([0-9a-f]{2})+\\|.*$", - flags: "i", - args: [] - } - ], + this.checks = [ + { + pattern: "\\|([\\da-f]{2} ?)+\\|", + flags: "i", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/FromHexdump.mjs b/src/core/operations/FromHexdump.mjs index b2d8cfb4..e8c25441 100644 --- a/src/core/operations/FromHexdump.mjs +++ b/src/core/operations/FromHexdump.mjs @@ -27,17 +27,13 @@ class FromHexdump extends Operation { this.inputType = "string"; this.outputType = "byteArray"; this.args = []; - this.checks = { - input: { - regex: [ - { - 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,}$", - flags: "i", - args: [] - }, - ] - } - }; + this.checks = [ + { + 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: [] + }, + ]; } /** diff --git a/src/core/operations/FromMorseCode.mjs b/src/core/operations/FromMorseCode.mjs index 98a1dfdb..b0aa4ef2 100644 --- a/src/core/operations/FromMorseCode.mjs +++ b/src/core/operations/FromMorseCode.mjs @@ -37,17 +37,13 @@ class FromMorseCode extends Operation { "value": WORD_DELIM_OPTIONS } ]; - this.checks = { - input: { - regex: [ - { - match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)", - flags: "i", - args: ["Space", "Line feed"] - } - ] + this.checks = [ + { + pattern: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)", + flags: "i", + args: ["Space", "Line feed"] } - }; + ]; } /** diff --git a/src/core/operations/FromOctal.mjs b/src/core/operations/FromOctal.mjs index f7ecde37..7060cdfb 100644 --- a/src/core/operations/FromOctal.mjs +++ b/src/core/operations/FromOctal.mjs @@ -32,42 +32,38 @@ class FromOctal extends Operation { "value": DELIM_OPTIONS } ]; - this.checks = { - input: { - regex: [ - { - match: "^(?:[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}))*$", - flags: "", - args: ["Comma"] - }, - { - match: "^(?:[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}))*$", - flags: "", - args: ["Colon"] - }, - { - match: "^(?:[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}))*$", - flags: "", - args: ["CRLF"] - } - ] + this.checks = [ + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Space"] + }, + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Comma"] + }, + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Semi-colon"] + }, + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Colon"] + }, + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["Line feed"] + }, + { + pattern: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", + flags: "", + args: ["CRLF"] } - }; + ]; } /** diff --git a/src/core/operations/FromQuotedPrintable.mjs b/src/core/operations/FromQuotedPrintable.mjs index 0ff1a625..7dce45b6 100644 --- a/src/core/operations/FromQuotedPrintable.mjs +++ b/src/core/operations/FromQuotedPrintable.mjs @@ -28,17 +28,13 @@ class FromQuotedPrintable extends Operation { this.inputType = "string"; this.outputType = "byteArray"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^[\\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: [] - }, - ] - } - }; + this.checks = [ + { + 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: [] + }, + ]; } /** diff --git a/src/core/operations/FromUNIXTimestamp.mjs b/src/core/operations/FromUNIXTimestamp.mjs index 57681ad2..50d8539e 100644 --- a/src/core/operations/FromUNIXTimestamp.mjs +++ b/src/core/operations/FromUNIXTimestamp.mjs @@ -33,32 +33,28 @@ class FromUNIXTimestamp extends Operation { "value": UNITS } ]; - this.checks = { - input: { - regex: [ - { - match: "^1?\\d{9}$", - flags: "", - args: ["Seconds (s)"] - }, - { - match: "^1?\\d{12}$", - flags: "", - args: ["Milliseconds (ms)"] - }, - { - match: "^1?\\d{15}$", - flags: "", - args: ["Microseconds (μs)"] - }, - { - match: "^1?\\d{18}$", - flags: "", - args: ["Nanoseconds (ns)"] - } - ] + this.checks = [ + { + pattern: "^1?\\d{9}$", + flags: "", + args: ["Seconds (s)"] + }, + { + pattern: "^1?\\d{12}$", + flags: "", + args: ["Milliseconds (ms)"] + }, + { + pattern: "^1?\\d{15}$", + flags: "", + args: ["Microseconds (μs)"] + }, + { + pattern: "^1?\\d{18}$", + flags: "", + args: ["Nanoseconds (ns)"] } - }; + ]; } /** diff --git a/src/core/operations/Gunzip.mjs b/src/core/operations/Gunzip.mjs index 9e6013db..d3d97f6d 100644 --- a/src/core/operations/Gunzip.mjs +++ b/src/core/operations/Gunzip.mjs @@ -27,17 +27,13 @@ class Gunzip extends Operation { this.inputType = "ArrayBuffer"; this.outputType = "ArrayBuffer"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\x1f\\x8b\\x08", - flags: "", - args: [] - } - ] + this.checks = [ + { + pattern: "^\\x1f\\x8b\\x08", + flags: "", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/ObjectIdentifierToHex.mjs b/src/core/operations/ObjectIdentifierToHex.mjs index b0b7c532..3e78cc03 100644 --- a/src/core/operations/ObjectIdentifierToHex.mjs +++ b/src/core/operations/ObjectIdentifierToHex.mjs @@ -25,17 +25,6 @@ class ObjectIdentifierToHex extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*([0-9]{1,3}\\.)+[0-9]{1,3}\\s*$", - flags: "", - args: [] - } - ] - } - }; } /** diff --git a/src/core/operations/ParseQRCode.mjs b/src/core/operations/ParseQRCode.mjs index a0691fed..77ab7d21 100644 --- a/src/core/operations/ParseQRCode.mjs +++ b/src/core/operations/ParseQRCode.mjs @@ -33,18 +33,14 @@ class ParseQRCode extends Operation { "value": false } ]; - this.checks = { - input: { - regex: [ - { - "match": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)", - "flags": "", - "args": [false], - "useful": true - } - ] + this.checks = [ + { + "pattern": "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)", + "flags": "", + "args": [false], + "useful": true } - }; + ]; } /** diff --git a/src/core/operations/ParseSSHHostKey.mjs b/src/core/operations/ParseSSHHostKey.mjs index efc03948..6472b287 100644 --- a/src/core/operations/ParseSSHHostKey.mjs +++ b/src/core/operations/ParseSSHHostKey.mjs @@ -38,17 +38,13 @@ class ParseSSHHostKey extends Operation { ] } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\s*([A-F\\d]{2}[,;:]){15,}[A-F\\d]{2}\\s*$", - flags: "i", - args: ["Hex"] - } - ] + this.checks = [ + { + pattern: "^\\s*([A-F\\d]{2}[,;:]){15,}[A-F\\d]{2}\\s*$", + flags: "i", + args: ["Hex"] } - }; + ]; } /** diff --git a/src/core/operations/ParseUNIXFilePermissions.mjs b/src/core/operations/ParseUNIXFilePermissions.mjs index 14263834..ae472a83 100644 --- a/src/core/operations/ParseUNIXFilePermissions.mjs +++ b/src/core/operations/ParseUNIXFilePermissions.mjs @@ -25,17 +25,13 @@ class ParseUNIXFilePermissions extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*d[rxw-]{9}\\s*$", - flags: "", - args: [] - } - ] + this.checks = [ + { + pattern: "^\\s*d[rxw-]{9}\\s*$", + flags: "", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/ParseUserAgent.mjs b/src/core/operations/ParseUserAgent.mjs index f94532b0..57ac9312 100644 --- a/src/core/operations/ParseUserAgent.mjs +++ b/src/core/operations/ParseUserAgent.mjs @@ -25,17 +25,13 @@ class ParseUserAgent extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^(User-Agent:|Mozilla\\/)[^\\n\\r]+\\s*$", - flags: "i", - args: [] - } - ] + this.checks = [ + { + pattern: "^(User-Agent:|Mozilla\\/)[^\\n\\r]+\\s*$", + flags: "i", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/ParseX509Certificate.mjs b/src/core/operations/ParseX509Certificate.mjs index d551a903..2c123f45 100644 --- a/src/core/operations/ParseX509Certificate.mjs +++ b/src/core/operations/ParseX509Certificate.mjs @@ -35,17 +35,13 @@ class ParseX509Certificate extends Operation { "value": ["PEM", "DER Hex", "Base64", "Raw"] } ]; - this.checks = { - input: { - regex: [ - { - "match": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$", - "flags": "i", - "args": ["PEM"] - } - ] + this.checks = [ + { + "pattern": "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$", + "flags": "i", + "args": ["PEM"] } - }; + ]; } /** diff --git a/src/core/operations/RawInflate.mjs b/src/core/operations/RawInflate.mjs index a50ffeb8..4555f287 100644 --- a/src/core/operations/RawInflate.mjs +++ b/src/core/operations/RawInflate.mjs @@ -60,14 +60,12 @@ class RawInflate extends Operation { value: false } ]; - this.checks = { - input: { - entropy: { - input: [7.5, 8], - args: [0, 0, INFLATE_BUFFER_TYPE, false, false] - } + this.checks = [ + { + entropyRange: [7.5, 8], + args: [0, 0, INFLATE_BUFFER_TYPE, false, false] } - }; + ]; } /** diff --git a/src/core/operations/RenderImage.mjs b/src/core/operations/RenderImage.mjs index 1616d75e..5dee6d3c 100644 --- a/src/core/operations/RenderImage.mjs +++ b/src/core/operations/RenderImage.mjs @@ -35,21 +35,17 @@ class RenderImage extends Operation { "value": ["Raw", "Base64", "Hex"] } ]; - this.checks = { - input: { - regex: [ - { - "match": "^(?:\\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" + this.checks = [ + { + 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" + } } - }; + ]; } /** diff --git a/src/core/operations/StripHTMLTags.mjs b/src/core/operations/StripHTMLTags.mjs index f456f720..9670cc3d 100644 --- a/src/core/operations/StripHTMLTags.mjs +++ b/src/core/operations/StripHTMLTags.mjs @@ -35,17 +35,13 @@ class StripHTMLTags extends Operation { "value": true } ]; - this.checks = { - input: { - regex: [ - { - match: "^(\\S|\\s)*$", - flags: "i", - args: [true, true] - } - ] + this.checks = [ + { + pattern: "(||)", + flags: "i", + args: [true, true] } - }; + ]; } /** diff --git a/src/core/operations/StripHTTPHeaders.mjs b/src/core/operations/StripHTTPHeaders.mjs index 9cb811a1..2160e3e7 100644 --- a/src/core/operations/StripHTTPHeaders.mjs +++ b/src/core/operations/StripHTTPHeaders.mjs @@ -24,17 +24,13 @@ class StripHTTPHeaders extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: "^\\s*HTTP(.|\\s)+?(\\r?\\n){2}", - flags: "", - args: [] - } - ] + this.checks = [ + { + pattern: "^HTTP(.|\\s)+?(\\r?\\n){2}", + flags: "", + args: [] } - }; + ]; } /** diff --git a/src/core/operations/URLDecode.mjs b/src/core/operations/URLDecode.mjs index 33f3f216..7d6544ac 100644 --- a/src/core/operations/URLDecode.mjs +++ b/src/core/operations/URLDecode.mjs @@ -24,17 +24,13 @@ class URLDecode extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; - this.checks = { - input: { - regex: [ - { - match: ".*(?:%[\\da-f]{2}.*){4}", - flags: "i", - args: [] - }, - ] - } - }; + this.checks = [ + { + pattern: ".*(?:%[\\da-f]{2}.*){4}", + flags: "i", + args: [] + }, + ]; } /** diff --git a/src/core/operations/Untar.mjs b/src/core/operations/Untar.mjs index deecbf7f..4e6af250 100644 --- a/src/core/operations/Untar.mjs +++ b/src/core/operations/Untar.mjs @@ -27,17 +27,13 @@ class Untar extends Operation { this.outputType = "List"; this.presentType = "html"; this.args = []; - this.checks = { - input: { - regex: [ - { - "match": "^.{257}\\x75\\x73\\x74\\x61\\x72", - "flags": "", - "args": [] - } - ] + this.checks = [ + { + "pattern": "^.{257}\\x75\\x73\\x74\\x61\\x72", + "flags": "", + "args": [] } - }; + ]; } /** diff --git a/src/core/operations/Unzip.mjs b/src/core/operations/Unzip.mjs index 47126a43..2e8be411 100644 --- a/src/core/operations/Unzip.mjs +++ b/src/core/operations/Unzip.mjs @@ -40,17 +40,13 @@ class Unzip extends Operation { value: false } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)", - flags: "", - args: ["", false] - } - ] + this.checks = [ + { + pattern: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)", + flags: "", + args: ["", false] } - }; + ]; } /** diff --git a/src/core/operations/ZlibInflate.mjs b/src/core/operations/ZlibInflate.mjs index 753e0ac9..a24d7476 100644 --- a/src/core/operations/ZlibInflate.mjs +++ b/src/core/operations/ZlibInflate.mjs @@ -59,17 +59,13 @@ class ZlibInflate extends Operation { value: false } ]; - this.checks = { - input: { - regex: [ - { - match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)", - flags: "", - args: [0, 0, "Adaptive", false, false] - }, - ] - } - }; + this.checks = [ + { + pattern: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)", + flags: "", + args: [0, 0, "Adaptive", false, false] + }, + ]; } /** diff --git a/tests/lib/TestRegister.mjs b/tests/lib/TestRegister.mjs index 2557b711..0236fc9f 100644 --- a/tests/lib/TestRegister.mjs +++ b/tests/lib/TestRegister.mjs @@ -97,10 +97,14 @@ class TestRegister { 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() : "unknown"; + test.expectedMatch ? test.expectedMatch.toString() : + test.unexpectedMatch ? "to not find " + test.unexpectedMatch.toString() : + "unknown"; ret.output = [ "Expected", "\t" + expected.replace(/\n/g, "\n\t"), diff --git a/tests/operations/samples/Images.mjs b/tests/operations/samples/Images.mjs new file mode 100644 index 00000000..663fa201 --- /dev/null +++ b/tests/operations/samples/Images.mjs @@ -0,0 +1,43 @@ +/** + * Images in various formats for use in tests + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +/** + * A small animated gif of a smiley + * 15x15 + */ +export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffce00000000ffb500ff9c00ffff94ffff10ffffc6ffffefffffff00000000000000000000000021ff0b4e45545343415045322e30030100000021f9040532000b002c000000000f000f0000045a7049096a9d785595ce19170670081204c2600013d09de899aed411108480e229eb9a38194f553998044854725028c6623a14b3727cea7453c0404090790944cdb6abe40e40943317170ca7cff082bb0528d80b2b568662d14f220021f904050a000b002c030009000900010000040530483165040021f904050a000b002c04000a000700010000040530ac3943040021f904050a000b002c040004000700010000040550042943040021f904050a000b002c030004000900020000040a3010228298575c5949040021f904050a000b002c03000400090002000004093008492921415e11010021f9040532000b002c040004000700010000040590904565040021f9040519000b002c030004000800020000040990acb0960c52d41b010021f9040519000b002c030004000900020000040930084264a0128b49220021f904050a000b002c04000400080002000004097005b1ea24b26211010021f904050a000b002c030004000900020000040a3010228298575c5949040021f904050a000b002c03000400090002000004093008492921415e11010021f9040532000b002c040004000700010000040590904565040021f9040519000b002c040003000700030000040a90904525bd54882b42040021f9040519000b002c030003000800020000040990acb0961492da19010021f9040519000b002c030003000900020000040af0044244982408aa71040021f9040519000b002c050003000700030000040a308445c5a098128277040021f904051e000b002c0400040008000200000409902cb1961432d41b010021f904050a000b002c04000a000700010000040590ac3949040021f904050a000b002c030009000900010000040590ac491789003b"; + +/** + * The CyberChef logo + * 32x32 + */ +export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082"; + +/** + * Sunglasses smiley + * 32x32 + */ +export const JPG_B64 = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVFBQUFBQUFP/AABEIACAAIAMBEQACEQEDEQH/xAAbAAACAQUAAAAAAAAAAAAAAAAGBwkAAQIDCP/EAC4QAAIBAwIFAQcFAQAAAAAAAAECAwQFEQYSAAcIITFxIjJBQlJhwQkUFSORE//EABwBAAEFAQEBAAAAAAAAAAAAAAYAAgQFBwgDAf/EADARAAECBAQEBAYDAQAAAAAAAAECEQMEBSEABhIxQVFhoRMicZEUMnKBwdEVUrFC/9oADAMBAAIRAxEAPwCTPU+qDZ3jo6REnuUy71WQ4SJPG98d8Z7ADuT6EgSrlc/jiJaWAVHUHAPypG2pTXZ7AC6i4BDEi3kZETAMWKWQOW5PIfk8PYYDqif9y264XKrrZD5AnaGMeiIQMeuT9+M0jTJjHVOzK4iuiihP2SggN9Wo8ycESEaA0CGlI9AT7qfsw6YqmnFMwe33GropB4BnaaM+qOSP8wfvw6BM+CrVJTC4avqUtP3SsqDemk8iMJadYaPDSoegB90sfd/TBjpjU5u7yUdWiQ3GJd5EZ9iVPG9M98Z7EHuCR5yCdJolc/kSZaZATHSHt8qhtqS92exBukkAkggkdnpES4EWEXQbX3B5H8Hj7jEX/Vf1Xc3eTHUPqakm1HHTaZuGysskcNrp3V6YFoiju6FiyMhBAb5g3beBxT02VpmY/iJxST4mtSVeYuyCUp9BpD8nKuL4kzMSZp5hwQfKACLc7nv2bA5yz/UZ1fe9W2qyXOwUurDcqlKSCOywtR1gduynEkjRP385MQUZJOBwPZgyZLS8pEnJeaMMIDnXdLDqkBQ6WUSbAYnSFYiLiphRIYU9rWPe3cYy5m/qPatseqbrZLVp2k0q9tqWpJ0vkbVlWXXs3sxSLHH38ENKGGCDgjhZfyZLx5WHOTE0YgWHGiyWO11Ak9bJI2wp+sRERFQocPS1r3PYt3OC3pD6sObHO/n3Z6c32kk0xakasu8clrjT+pmWJY43UBgzFye5IxGx77cG6q0tTsufDTUMHxPESlPm4KISt+mk++nESUiTFQ8SEW06STbiLjv2fD16oemzTvO6WosGpoqilnt9VJNb7nQsq1FOshDEKWBBVht3KQQdo8FQRhs1WqpkrME1Dl2YqJ0lylSVEqSeFwDuNi4uHwZiVlqvIwlxN2FxuCLH/MKrp46NNBcnNe19xpbpcNRaqtka7P5IIgpI5lYCWONQM7gJE3kkZWRRghuPLMmdatXpFEGIhMOCs/8ALnUUnYknhYt1BNmxHkaXLSMXxASVDnwxr6jOjHQnN3Xdtu1XdblpzUt4YwN/GxrKlX/yiLGSRCp27URUMmQuTGpyzLl2Wc7VWhyS5eGhMSDDv5nGnUWYF7uS+lifmOwOPk9S5aejeIVFKjy44anS50zac5HVEVj00tVV1Nyqopbhcq5w086xkkA7QFVVBfCgfMckk54fArdTztX5SFMABIUCEpcBKQQpR4lyE7k8hbEn4SWpEjFWjdtzxOw7nHXWt9DQ6qRJ4isNwhG1JG911+lvwfhk8bpnLJ0LM0IRYJCJhAYE7Ef1VxZ9jdr2L4B6XVFSBKFXQe3UYTuqeVUFynhe8Wab93TKyQV9M0kM8KtjcI6iIh1DbVyFYZ2jPgcczR6RXqEtUGLLrAO/l1oLbHZSD0e4fg+DFM3LzI1IWPdj+8W0vyop7dUyy2izVD1s6CKW4VcktRUSICSqvUTMzlQSSFLYGTgcKBSa9XFJgwZdZHDyaEDrslAPc9cJU1Ly3mWse7n94cWiNCxaWR6iVlmuEq7WdfdRfpX8n44HHS+TMmw8swjGjELmFhiRskf1TxZ9zZ7WDYD6pVVT5CE2QO55nH//2Q=="; + +/** + * Meerkat picture with EXIF information + * 200x150 + */ +export const EXIF_JPG_HEX = "ffd8ffe12cd645786966000049492a000800000008000f01020004000000534f4e5910010200060000006e0000001a01050001000000740000001b010500010000007c0000002801030001000000020000003101020011000000840000003201020013000000960000006987040001000000aa000000300200004453432d483546000000010000004600000001000000506963746f6d696f20312e322e33312e3000323031303a30373a30342032333a33313a31330018009a82050001000000d00100009d82050001000000d80100002288030001000000030000002788030001000000c80000000090070004000000303232310390020013000000e00100000490020013000000f401000001920500010000000802000002920500010000001002000004920500010000001802000005920500010000002002000007920300010000000500000008920300010000000a0000000992030001000000100000000a920500010000002802000000a30700010000000300000001a30700010000000100000001a40300010000000000000002a40300010000000100000003a40300010000000100000006a40300010000000000000008a40300010000000000000009a4030001000000000000000aa40300010000000000000000000000010000007d000000250000000a000000323030383a30393a30312031333a32343a343600323030383a30393a30312031333a32343a34360043490d0048e801004b9a390040420f00030000000a0000000300000001000000480000000100000006000301030001000000060000001a010500010000007e0200001b010500010000008602000028010300010000000200000001020400010000008e0200000202040001000000402a00000000000048000000010000004800000001000000ffd8ffee000e41646f626500640000000001ffdb0084000604040405040605050609060506090b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010707070d0c0d18101018140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f00068bb671e5ec1500c895b5400786055e0605b5ea299129b545514c16ab82e2b6b80c516b82e295ca315b5c46050b9062825b0a2b8a82adf55b836ef70b133411b057900a852454571a357d11c62ebaa826f51b50f5af862032979ac5708eb0cad546da094f6ff8adbfe346c953ae8e43827c32feee5f47f47fa2b9e4890ee457c303b0b433dcc209a9c09b506d56d83701b9c3c2bc4be1bf59eb6ccb40ff00ddb1e9c8fec9f66cb211b15fe95c5cf5cf9ff3ff00a51412464b1d3e4f85812f68e7a83dd3018f107439316fe19feb6197fbd745752c442c8ed1988f10c3aa7b1ff23fe23950241a29d2eb4e3f44fe8ff728860797271490ee581d9ab92301541da4e24476fde63284bfb58d11a651d0fef546d556f84ed8217f49ff0035d16a3181c94ed4b346fbd67b71461fefc8bfaad7fe0732f04fbf91630f5c2bf8a1fee3fe3aff00ffd00a99c717af541b9c0abc75c8aaa0029810bc0c8b2545c50bc0df155d4c2ad8a57052b7551df0d2b46788756c095a2fe05069b9c6d0a2faa00d451538f35b0ad6be60d46c64f56df70769216dd1d7f95864a13312d5931c6628a672d85bf9821375e5f6105ea0adce8f25036dd5a13fb43db2e38c4b787fa4718669e2353f547f9fff0014904f1dca318a6a823692361423da9d8e5039b7e58472468f229dfe83b6d4b4d8a6d32491b51863a5cdb486a6523a98cff353f63f97098f1721bffba70f067384f873e5fce48dec4f1e5f687ed53a83e0464625cff1624d214daf097971ad7a65b128914472e2952a30128017dc017f685e3dae6021891d6a3bd7df264dfa87f9ceb357a6b143fad8ff00e23fe250a6637aa250804f1ad24a7ed53c464270120e9b248e4dcfd4b6deec5bd15aaf68db78b467dbfc9caa122369391a3d71c468ef044cc11d0c7b3c32a90ac3a6e3a8396bbac9a686685c7aa4a92b251892ae84c335363edfc460eb4f2e4984bb8fd2ff00ffd10a8338e2f5eaa06f8155141c0aa82806e70522da7b98106ec2be18045287975544601456b92114134abfa45a80f1d8f438d23896bdf4bd875c8af129b4b7527d9db088a0cd62add13bb6f87851c4b9ada50b5663538084095a7b169364b60f73688ba85b955fac06052e2dde9bfd93bc7fe5633c46b8a2767132659835f4cbf87f9934b24b6f4c7ab17ef21e95fda53e0c3f8fd9c8c4b660d40c9b7d331fc2a6e4b0fe188e6e5014a96beac12a4d1318e543c91d0d0823b82325747662636c95751d2bcc016df592b65aa00041aa28a249e0b3affc6f97090c9cfd32fe77f39c4962962de1ea8ff33fe252dbed3f54d16f84572a632778e4527830ecc8c3299c4c4d14ce10d4436e63fd8bae1c5f3996e1fd3bb3ff001f4a29ccf8c8077ff2ff00e0b2b323767fd37fc53ac198c7d19072ff004d14bae24961611dec7e993f62e00fddb7d236fbb2e05be3aa303eaf543f9fff0014a77514b1d07246e42a287b1c85efbb990d5e326add6cd2dbc8b3aa6e36643d194f5072709f0972270138d21af81b2bb5beb6158243fbc4f0af63f3c998806ba179ccf78f271ffa78fe3f9ebef204a0bb87e2b79802c3b0aff03954a025b1e6babd38006487d13ff62820cf6a76abdab1fb3dc1febff12caa3220d16ad26b27825b7d3fcd53d4214172b223036f7c940dd848b4ebe06bc72d98dafb975e2329f1c7e9c9eaff0039ffd2297d4d15c2a8a839c707af34179bf97a05df145b5ebde3123a62c6db617463a16dfdb07328b5392d4800b3127ae4e96d171431f004ee461000624a2e4e2c828294cac9dd0b68b415eb8d3605e84a76d8f7c04b1215912bf10c36c486a9f1d1bece56c805682f27b0ba5b9b37f4e551bf7523c1877192848c4d844f1898a298b2daea8a6eb4c516f7e809b8b0ea187ed345fccbfcd1e4e5112de3f57f35d66a34f28ef7b8fa727fbd9a56d12ca098978cabbbc1fc57c46439b769b5b67827e99a902c69e18097654af00b633d273f0d36f0afbfb6188079b0cbc5c3e9e69b58799ededa3fd0faec667d2a43488b1a98fc1a193b7fa87fd8e64c0edc32dc3a59e7a96ffbb9ff003bf9dfd66f56f2ec9a7c02f6ca517fa44dbc7709bb28fe5900e9feb65797098efce2db908ce3f9b947fb34ae2d45d216b690896ce5eb1b74affc6ad98129cb1ec3787f37fe25d4f1981a28196d2e2de3792dd45d5883592d9b7741f2ff008d866463cf190f2652200b8ef1fe6495f4e8c5f2b0d3642cc054db48431fa2b43970c065f4b6e1cf21f41ff3565f42f1c452e6231edc655208f87c457ba9f8b24227e929cf9f8fea1fd197e3fa29758cb2c32358330742498586ea6bd40f66eb9127ab6766e61be19fd32fa575c46622548ac4db53f81cae71120e36af48714abf84fd28195163a249fbcb673553dc1fe0c3230279170f96c5ffd32211af3dfa8e99c800f5d2e6888622d257af86202248dfabd08276c34d56a72bf13c7be00caad6a51fedf6e986d055a092dc13cba0ed8c9785106970bfbad80db2ba21452d96d98a56b4230025b5aa3fa7d6a063694c6f345d5ec638de45564963128f498390a7beddbdd79603ce8b8b1d46394b86f740a0661d7e9c69c85f50053c31a4b71318d8491b157520a3a9a104770460ded4ee374da2b9b3d68ac53b8b5d5c1fdcdcfd98e66f06a7d893fcafb2f969a9794ffdd3aad568b6b1cbfdc7fc750d3412099ad2ed3eada826df17c2b27f46c8f0dedca4d5a5d7981e0c9fe99012218e42ae0ab0eaa7ae45dd8208b0a8ab585926412c2dd636dc7d1844e8b8f9f4b0ca2a415749d4356d11dae347737362dfef4e9b2fc5f0f7a03d73371e5f8879fd4693260363d51466a0ba6ea369fa53455e11c86975647a2b81f677de371fb20fc2d9467c11ab8fd2d5927e20bfe2ff0075ff001e4aa1b978caba315a6c8e36653dc11fad7355931189b0e3d90a5796915c49eb4245adef50cbb4521f114fb0d96e0d4d6c51f615f6be63ba15b0d52ac07c244c390dfc6bff001219b2f16446c6dcec19f1cbd3947f9e965d5b34523440fc517ef2071dd0ee3fe072a27ab899f19c73a1d3e9ff007a8c82fe09d394e9bb0e32f1e95ff3df2b96c5d80d7f890e198b43dcdb888d0fef20907c2c3bff004619331121b3af9c1fffd42c58b91661d00ce40bd792dc3ca36af6ee31b6063688e72ccb55d80c06458d529143ea02c7a75c2cc2a3aab10577f1f0c1c94058ab116a30d8f7c46e83b23ade35896887639191400a8cacc877c8b30a203a8a75070aa3f4ed52e2d53d0957eb1624d4c0cc54a31fda89c7c51bff00abf0b7ed61e2da8ef171751a5865e7b4bf9c8b92c6ceea269e09c705f89e42a15d3dae117fe4f47f07f938401f0fc7d7ff0014e18cb9706d3f547f9c965eda5c5b4aa93af10e2a8e0d51c78ab0d98602087658b2c662e26d41c88854ee0e45b691a34b6f85e19e19f90078a3153bef41cc283f41c8d8e4e29d6e38cb865e93fd24c56f62bc45d375c0d132505a5f91f1c7e01ff9e2ff0088e59c40ed2e7d24e2eab42320e28295d40d677315b6b508709436f74a6a92276f887da4cb7ad486ff00ee9d760d5cf09e13c9d7bf50a0f4a06891bf95f9a9f913956402f61c2ee716632162424a115bc4afc92565237029be40d8dd8fe66f6215923892ebeb30bac170e384f4da3997f9655fd4dfb39918b383cdd4e6c70e2e286c7f9a83d4adbd190cc8b589fe223afd1b771fcd94e5c5c27fa25c59c6f7412ba940e87d489ba8e841fe0d987970b8c546ea28a5840947a908d9251f6e33e1ff0036fd9c8e2cc6068b13f620156e2df8a337a8aa795b4c375207da4dfecffaa73620c6412096c4c2d66f5177b69c7c60ff0029fe287235628f36fd2e6109fa85c25f57e3fa28d7b365857837c2fd509a8f620e4632a2edf51a08ff0001ff0035ffd501c82ab713b1ed9c7bd700d23a1a03d09ef8548d959d8a6c83e123a60456ca45a80f3ef86d695a368d14721f6b011690e9e307651d7a1c4162559632b1835ebd6b903cd905601ca003607be0b56dd0a05e7dc540ee7082c429cce480476e83109a55b396ecdcc5f530df5a0691fa7f68d7b7cb271049a1cd84c4787d5f4b38b2f2dffa2a8d5648ad965359b4f51ea2127a3a8a8f424f1e0dc73698b424c7d66bfa2e8252109de226946ebf2f744a97fd2ce905392c7c14b807fca27f8627b3203f88b991ed29d7d22d45fc8b1c11b369fa899108afa73a0e276ee41ff8d72acbd9408da5c5fd644b5b1c9b64884a6edae34e7f42e151a3ea6094196023a555beda7cd4e6bce1962347fd2ffc4b18e98fd5825fe6a67a5de6837b6bfa2ef58c56b21ac704edcc46c7f6ade71dbfe2b7cb61c321c3f8ff00364e36a32196d9070cd29d56c2ff00406fab4dfe93a6b9adb5d2f415f7ec7db25663b49c3b3050b6d4f4e423eb711656feee688f1a9f0607a1cb31e3c52e6ccea67de8c924f2f4a2b5b841dca80f8cb4986f9ca29fcc4b9a94b71e5d4b79214be75256b1acd191461b8de9b6f968d3438684b883664d5f10dc6ec6a42f0c9eb440153f6d3f64d7e5d8e6b251e13479380762afc9197d6b7358dbeda36e47f92c3f8e533c36a47721cd54996dbb7f7b036e36dfa7ed2e5512607763cb928ac2970af1c3fb557488fda560370bfccad994725ee9ab1411de5fb8b1bbb57d3ef1bd2b886a6da6f14fe53fea1ff85ccb842131bed273f4ba89c8708dcc5fffd62e2d1a76a8ce429ec02ee49455a6e7f562c51317062431fb382904a9ba2b0a8dab884ba4456403baee298dad2a293c4002a460b4220ab98771be42d2136d2b4bb1d42d1520d4238b56a9a595d8f4a3735dbd397752dfe4b71cb23107aeee364cb281dc7a3f9d14bf55d3356d3ee8c5a84124131fe71b37faac3e161feae40dc79b7639c642e25423579691c6a5a47215146e6a76184032200644888b2cdb4893cb3e54b6336af3ac7a83292ce7720569c540cdfe9b1471c7fa4e8b5396594ff45bb9f32f9635711a5b5d24f2ca0b2321dc53dbe9e99394c35460428db5f69d0235c6a13d225709f113c4ef415fa72066032e1279215ff343c9b15d0b54ba018311c56a7a1e950388c94667a20e33d54dfcc9a2ea704b1c4ad3d93539b0a7250687e1af7195e694251a2d98e3381b0a175a4e8f0dcc56d697ea7eb2bce2827d89a0dc123fa66a351a7e11c4370e59d4898ac91e256867d774b431bc5f59b13b3c47f7d111f8f1fa728c7a9ff383893d2c25fddcbfcc9b4961e57d4987a55d3e67ad6d64de073edfcb43fca73263c24d8d9d7f00068ffa54a2f3cb1e63d297d78e332c0bb928dce9feab0fb43fd60b96891fe20c8e107789ff0034a845e608e54f4eeada398aecd55e2e3e63194011e96b333c8b7789672c6b35922a8414922049047c8ee331e62fd32148901561296ac0fce22551beff00f6c7fc3653026268b4722b9f9831bb0f4e47f8a2957ec3fba9fd6b872e1a163e9654a6ea2570ea7d3b91b823e10c7dbf95b31b80c7972470f5085914cae493e8dd21fb7f64337f95fcad97e3c888488363693fffd7284042904743b67216f6055e40c2441d88d8e218ae50cac5fa8aef816955a930544aa9c15482a8d1180508e5e38a04ada32102aa37187609ab56866924251bbe0a5269d2451d0ab50f8644858c933b1f366b16500b39c26a3a69eb65783d4403fc83f6e3ff00627271c846c7d43fa4d13d3449b1e897f3a299e95a6e89ab5e473e8ef369d78ac19ac660668bad498e61461feac9993a7803306361c6cf39c62632a90fe7241f9afe5ed5db50bbbc1207b168d15054171c7ed514d396fbe6ca397864e098dc764abf2a3c9d2b6a4758b90b15880fc5c218d49216a029a7876cbf2512d512427df985a59d574afaae92448e18cad0024315535fc40ca274241b604d178f693e5dbd97524b60a23bb576352bc7663521c9fe5f0cb6796222c63024bd67c9fe49d52c619d6e6506adeb471a7d9236d8fcf304dccb90642229865d45a8cde7d8da69c036d31892db91a8404f6e9b29cb8802041602746de8769eb0b9e16b7c2dfda5ad01f0233512d0891e8ce5adc331eb8ee9a4a616b4922bf9ad660c391e04a3123ba9ecdf4e2745388da71feacdc0cd2c67e9bf8acb0bbbdb3547d36f44b048392db5c1ad40ea0378ff00ac32a8ea278feb1ff12d3b859a845e5ed5ff00777d6a6c2fcf475f86bee0fd96ccd8668cb741024c6afbcbdaad8b97b63f5c8177e49b4aa3dd7bfd197736a31212f59a3950f5046cebd0823bd33172e3bf7b1e6bad2fa3b626daf944ba7cc6aebfc8dfefc43dbdf23872f0ec79318cab6289d5343b9b51ea467eb36cc392b8a160a7715a75f9e5d9f4a63b8e4db49638499784a68c05165ea76ecd4ea3308e3ea10637ef7fffd00170010be9ee0e723c9eb22e347401b623a60660351875aa1dc1ef85079a2ad8c48c4d7e2191218485a8dc5ecccc5a9551d3084c634d5bcfcfed0fa723216ced13c68448ad80ecc4eedba31fde570246cac9cb6246d879312ca3f2fa48135b01a42924a0aa252a0fb9f0cced1c85f9b83ac04c7c93ed6344b5d7219ac6edaa049cd68487001ec46640209ddc3a23931df37dfcba2e976b63a6dba3adb0e1c2bc78af124763fb54cc939a31e6d51c464c2f43f336a53eb0d2cf115423821614353ef41b7f93951cd122f6e26df048dba3255f2ce9d7f787519a2add2303c81f85c0dc0651e1e3944e61946c724fadeede3bc48cafc007150bb8dbc680e571cbea4ca1b24b3f9322bbf3bbdcc6844660f57d4509512b7c14a12a5bc59466466c91aabab7127b452fd634ebbd22e85beab6efe937f73728483c7fc863f6a9fc8f98128189d9c3be13b8b0b224bdf4fd4b5956eedc9a54ecc3d88f1c0353d241bce28917095fbfea529ae450c732342dd40229f10e85586c1b2c12891b38e491cdd1eb37889c2455bc807db8651b8a7707ae60cf07866e3c981994c6c358b69a9159cc6294fd9b4b92684ffc572f6fa72dc7a9e859c660a8ea02c669e97b0345743666145947fc692ae6613637410121b8b6e1c918f38abf04bdb7f1fe5afbe62ce37b8e6d442eb2d4e7b54f459d82447f77de9e2847f2f8618e690aa2d90c9b51576161a9ab4d69fbaba5152a07eedfdbd9b2e204b97a65fcd6c23a87ffd12f0a562a035e39c8757aeb6a542c10d695c348b6d832fc34f6c78934ac901552f5de9915e2535914c6477aef849400a91491315420815f888eb4ef4c36106d381a3d8ddd4e9b732301d6299417fba3f8bfe49e08c78b93892d54a1b4e3b7f3a2b2f346d52de225a0631af5953e351f32bf67fd971c07198f30db8f538e7c8a0e12c45396d95f15f26eaa4c749d4e7d2af16ea2557e26bc4fdd9762cbc06dab2631314f44b4d42df51b48f50b7014c83e21d3891d41ccbe3bddc094083494eb1a569b79306912aeca049434a657395ac7648c794b4622408b346e2abca4228a2bd57e7951f26de328bd3f4bb1d3c3bc4feacb2ecd23b135c78875606dafaf14708c3f7c0d100ee3da995f8b4764f0a1efa695e213dbb8498305a3350353b577197e5c232e3162da2f18954f92c4f306abf57fab6a56c97f675afa7200e07cabd3fd8f1cc38e2cb8fe926bf9b3fde47fe291934f8663d12dfba4ba3f2f699342752d26692c08204a95f563527f6658dbe30bff000b96649ed790708ff54c7eb87f9dfc5175671189db6217ae9f21602ed63319eae94643ee2bb8ff0054e4b0608cb712e28ff3a2dd1c808a9734bf5bd12d804934d2a6702ac8a405703b7f92dfcb99392a3b5d844b4f62c31a78d665e480abf75e8790fd4c330f361af547938262985a6b933c4b697b0a5e47fb21fe1627fc87fd893fe27870e6de8b38e5bd8ae7b64995a5b0769507f796f200b711fb11d1d7dd7334c2d35dc95dc43ccf25346028e00f0fe65ff9a7318e3218108753756ee67b298c5311f1f1a71703c474e43be5f872744d90ff00ffd22949080c3af13be722367ae905d72dc91590d08eb838b7481b2a890b052db62854329008ec702045608d1d7929dfc3254b6b9762283e9c8952adf0ad1f951874a1debed95d8b5e6c8f40f3079c22751691cf7c8365596269683c0494e43fe0f2cf1a71ebfe99c3cfa7c279d459645656bac0ff0073fe5b16329eb7892c7137cfe1657ff8247c075388fd437fe8ff00c75c1390e3fa27c412db8fcbad3e798a691ae461bbdbdd71661f278cfeb4c94714642e12ff004cdd0d791f5453ef2ef95752d1ada5b6b9659a3958346f112ca187c86d5cc9c3c5f498b4cf52272ba416a86381dc90102ee4fbf8644c69b6d8ab6adb33716925249e26953bf615ca886c545d423112b4dfb9077552286bf2e995982da166bf86e61758e391e36d8c82818d7dc6f8c61ba540daac5a618880de838969522aadef4d8e6c0c4986db3839cf522d0713233016f3c91b9e9139afdc0f5ff639872cd387316e1d425cb6475a4fae5acc2e2dca995450f6e4bdd595b6653e193c7aa89626241468371707d4d1cfd4f50a1693469cd60980ea6d98fd9ff8c5957e5f1c8f1633c12fe83120a5f1f9834c9a530ea103e9d76878bb50940dfe52f55c264794c710fe747eaff4a88e523af0a9eaba33381776a55b97fbb633ca3907b91d1b2fc5115e93c516331691dcc120e42542adfb5dc1fa47ed663e6d3f58b44a2bac2e6396758ae2e3eaf2f486edba57b2c8474ff5ff00e0b2cd366fe19158c935b9b69c03fa4613b7d9bf828c0ffad4fe399b38ed6dc3cd2abbb392302746aa56a9731ee0f71c8663ca1ba4c5ffd32755e124849fa33912f5cac5a2921a5006c48a505a721a0a537182f7485cfc8046a6ddf0a2ddb03b1a5705aaba384fb5be0a410985b798b5bb4b7582d2e7d0856b4e11c61b73ddf8f33f7e3640e7b34cb4f091b22cfc5d3ebfabcfbcda8dc313d47aac07dc0819031059470407f084b26b8f5d88798c87fcb62dface4a806e1103905f193171646e0c0ecca6847d2322931bd8bd0ff2dbcc37d717eb612cd2cecc6bcd8d4220ebbf535f7ccbd21919d5ecea35da611a94470a2bf3157d1b3b8643f0d682869bb6cb5cccc9005c7849e7d149a847468e345e43e295b76f6a023318c29bc1b577b5b8b93598991d507c4c766af811c57e8c81d99029859da2470807a7ed329345246c061ab412a66ee4b6be590bfa90d402ae05180a6cc1b3261c9a642d177ba368fa9ca52cd974fd40d196d6427eaf2d77fddb9de36ff272a911c5c279b8797466b8a3c921b97d5f4ab936f7b1392bfeea9766a78a3f47198d974913b869c59ce33ea1c4a91dd5bdf0e319f897e2e1bacaa4771dff00d92e5021c06c7376909e0cb1f3fe6a2e592d75702db593e8dd20e36fabd29d3a2dc01d47fc59993098c9b1da4eb32e3df7ff004c9330d6fcb77a501e15dd93ed432af8ff002b03954b1989b0784b8a41814e6daeb40d6e2e4b27e8fd400fde44c098be629ba8ff0085ff002732239a276973671225e452fd53cb92467948b40c2825520a381d0861f0b7fc4b232d303b844b12034cbbb9d32f543c9208a9c680fdc190ecc3dd72b8ca78f9221e93bb52df0b6bb926b623eaf29acb6bd0a13e0a7f61bc32dc7949e6ccc8479727ffd42466596d8bd7e2e8df46721d5eba97aa30b4471b9184f34c5561642943b138a0af662001db012a22d33fb7d38a533f2fdb2b34b2cd6d6d7aa365b7b8b892061fe50f4fed035ee725c60731c5f371b513aea61fe6f1a71cae789f43cb163c47ed27ab747fe4e93ff0b9299321b461feedc784a27fcacbfdc25afe62bcb79bd2163656cde1f5440dff000e09ca08efdbfd8b923003d652ff00396bf9a35fe4bc2e5235ff008ae1857f5263c16bf968777db2566f32f98aa07d79b7ff00253fe69c8f004fe5b1f77decaff2e757bfbad6592ee6965a46c56a144751eeaa0d733b45000934e1eb30c6205045f9cafa2b995a009536afeac887a1a8201269db2fc991c68c5848bfe6ecc92701c78d1791dc6d53405572156cea940f195ffd22a217350fc89e247ecd6871e101368998358462e2da43242c49915aad4db6d872f96428f4643cd2c9aebeb91cb2ccb20263aa46e18a923607c48a8cb4028e4c87cb7ac5f32c96b2ba7aa2929f5539ab03e15048a6473eabc281911c510e1ea6040b89a4d751924be8cc3711413c1d9412a41f14e5f60ffaa730476c69e7d785c137d77627a97966e50fa96cacea0d53f9d7e4cb9911c98f27d2449a8c1029aadf5b1f4afd1a4886deb05fde01efd9f2271516633486c7746c52fd66c1a2b722ff004f5a911ad4c90b1ebc01fb23c626ff0063970163f9cbc625ee49eef4d92255bcb462d086a2cab50c8e3f65875561fc8d9464c25a658eb70af61e63d4237da758e66fb6928e56d37b3a7ec31fe75c8c32ca277dd9433743f8feb265eb68baa4861914e95a89a73b5987285891d53b80ddb8ff00c0e665821b051f2280bfd2af2cc832a7c1d119bf79130f05906e3e59038fb9062fffd5298ade308c0f47e99c853d7deeb232d11680f4fd9c20a3aae34014d69e3812ab2042a38b57db10a5750f0e95c4a86a2241a9aedd30154645a85e29f858b01b8e5bfe3d72424438f934b8e7cc27565e74b95845bddc1f588c76722407db8ccb22fddc72d19cd6ee29ecf03e891822d6ff00c85a811f5bb0fa9b9fdb843c06bff3ccc917fc2e3c58cf31c3f8fe8a383550e47c46e4f2ef956715b2d66487c05c46b2affc1c457f15c1e144f2923f94271fae09df923ca93d96b1f5c8f5282784a32708096e60eff102071cbf4f88c4d92c33eb61963406e87d7ee4df6b7a9dbc287d08e2559ae29f0a12df0af4dcb53b6195924f46036018bc1e947f0dada9bb1521e595b82b536341b9f1ed938ee105d6f3d9bcbe92c724570e2bc1a80141debf65b89c05907094c7231a290013c36a96dff6bb7f2fd9c1114c8a5a4348222b2845b49c9f8b66e3bd003ff356106b74d222caf9d6e65588fab216288d21a00ecdc885eff463216082d792161447986559de2bc468d9588631b10cbf30763f76687269803c817591d4989a946331fecbfd3232defeee4606caf3d4ff0021b67fb8f5ff0062d950c1889e5c1272e12d364e44e392bcda9dd8a8bcb24bb03af052b27bf4cccc67247612e21fed9ff14c3369384583c4a1696da2debb5e69d34963729f6d88200f6778f7ff00918999d1c86bd40c3fdcb8421d42b5cc77f67ceee789a51320569e3e32dbcc0741281f0b7b306f5172d80eb7c4194a5e4c7f51b4b19a92db37a6d27dbb77af243e1520735fe56fb5fcd95ce01c79c41e497ccee10417aac427f7721ddd076a1fda4f6ca2371361ab96c51b67adea56038349f58b390746f8c11f4fdafa7e25ccd8c848586e8e521fffd62884b00a877e3df390b7ad28a9e389944a3ed0db05b1050cebc89a8a03bd30d36872ac4803826bdc61e881b96c5d56ab4a60b4f0af8837527aef8690aa0480120ed8d215adda22a796c722420a84f2c319a861bf8ed8d81cd953a34ba9d87d5e29253ff152337fc441c3c24f204fb831240e65eb3e44d256d34c7bd76324cb1105e5478e58f9f543cf8d77f6cc9d348efb174d9c478f9525f7d6732f976ee92f17bab9ac9213bf053422bff054cbe5f4a0736377b259da5cada24fe90e20c4c0f21e3e0c37e9804acec9aea837983b299191258fe2695457e0ad2878ff001c8d9b6c0104ecb13b7350a82a5665342caec7c7a32ef846ccb9a9492a8778e451342e94691762c79029cbb7c4a7638ad2cbb8ace082194d4490721242e7b720439f7a7ed64cb00776437d7e97f1aa6a9a726a36ea8384ab486f107f9130da4ff55f30f2cc035270f369f6bb07fa29249e598ee18c9a0de0b96039369f703d0bc51fea9f864f9a6552c008db775f2c5bff00c520e2f31eafa74a60b842eabb3c1382187b03f687df94c606276ff64c0e4947605151eb1e5bba9565134da56a03a4a3fe6aaf165f67ccd8e7007d3fe95946609df628a8f53b9b776749cd9cd5df50b65e56b283d3eb101aa0aff32e1c79632e5b16e9c48ebfe95ab8d634a7262d72c56091a9c752d3be28181fda684d7fe132ebb69240e63fd2b9bcb6973099f4eba4bdb6fd9303026be0637e9f21f1644e2894880291cf61716f234662a57edc26b1b57c78b6d5f96446120d863c0fffd72bb7bb8c2947143fcd9c8bd690b595cb32ab6c771869545e59540461d3a1c0cc056440103f51df15537953951571092c8348d0f4dbbb54b9bef3058e9cadfee86124b381ef1a014ff82cb630891bce31ff00672713267903421297fb94c7ea5f97168b59757d435393fdf76b6eb6ea7fd94d5387f723ae49fc383fdd3571ea0f28c61fd62a6baf7942d36b0f2d89abd24d42e6498ffc8b4e2983c487480ff929233ff629f0731faa75fd48b67cf5aac3fef058e9b62bdbd0b38f97fc13f3c31d4e41b0e187f52293a289faa5397f9ca727e6079e652ab1eaf325762b12c7181ff02ab88cf94ff14becfd4a745840e5f6c9ea3e5b69e4f2a7d6ee6633cf70cccf3b906bc7c4edcb7ea7326aa2eb881c7405283d92cba1c35dd7d3e649ef5deb8c86ca0bcf6e2d25861904919592688fc40024346d5500f8d3e1a656090d9cd27fac178123a17676e0dfcc40fb40d295a83837b6ca58f44f459872474f816848508dc69f4e125900b3d38feacb2280aca38bc6a2a4bc4db487af20c8324189288b9b759ccb0b9502f362e76a2a1aa9f1e5f695b2d1dcd375bb5797b736b398623fbb00710f1923dfe25cc0d4c883cb670f31225610d77aca5e8482ea088fa7bc722b706047f2b7507e9ca4e527c9878c09f50130aa35a8a58843a9c5fa4add471569c52e14760b3a54b7fcf446c98ca0f369998f4e5fd2ff008a42cda0797ef559b4dd4e3b77ff00963bff00dd9f92c9f61bfe17260c4f56a301d364ae4b2d6b4c2c9196109eaa8c2585bfe049189882c4714792eb6d5ecf68ee53ead216f88b7c56ec0f8803927cf271321cfd413e25f30ad25898e6375a44cd693b529c24aa31f0571f0b8ff25f2c8cef92f0750ad1f9df5081bea7afdaaca8363214e54ff5a33423fd68993fd5cb626f932190f22fffd0202c01a5363b31ce469ebc96a3e71cdc0b547ec9f6c2b4bf9c84988ee3b1380326e19f8068a4fa0e14014be3a7daa54e21495552b20ad28463485c5011b1a634ad53e120b570a0af88803e2dc74c8a944699a7cf7faa5b59db426e249dc208aa541a9fda23a28cb31c788d535e59f0c49ba7d037da7c7a7683058a11c2da3e145145d86f41e199d945507498e5c52252fbb2b35988536e7c13e82301dd9311f37c11c002ab16450637047206bdb6f7c8c8328961822416deaf32ace4142bd449fb4483e206544d378dd4657412b492025437114eabca95217bd695c883bb3ad94212e6628d192dc02ab93b80c6aae69ec007cb22c24173098db321955e783d38a1604072180ea3fcae996823ab510ad3dfc6b04ad13bc8b6af49850b3287028d41fb072bca080e26a06d610a9a8595d2543c5282770ca09feb98c780f30e089169ac2cdf711d3de26ff8d4e446289e492a0fa502a78ca69e1227f4c4e15010ff00a32ee2de250c3c636e3f86d80e028e052992e07c332bf03fefc40e3fe1860e0218f0a1238d2266312aa06356542c8a4fbaee9f864b88a88ab4f7114f088ee237650280ecf4f91d9a996c667b948b7fffd18fc75a7c5fecbe59c93d7aa20844c37e408fbbefc507c95a416d5055be2f0c4a624f550a45c8890d3c0e1648880807a557b62c1104afa678af6d8ed80207343815277a7df926c5d185a354febc894351d431ee3241059dfe4f45a51f372cb773b2ddc68c2c6db8b524908ebc94151c57fdf85732f46071dff17f0bafed132e0a1c9e95a9cba8fd6292c27d025b9355761f7e33bb70b1d56c83d23d4faaabce7fd3787148c7f396346afd9d874df2c8f2f344987f9a05c7a8c01a283f19a0ddc529d77151ff000dc7212671a61b1862f2a82160561ea3ee433545280f4ca0b921467a1b98bd71c4ab398b86e58d771b7d38c52796ca363ea1924e1cc382c108a54c7c450ffc178e4c31921a90064170c1a4480052d5f8cf36f4cb765d8ed96061ee4cbcb5f5b8e56fabf099b98f5c27c0dcf71f75373fb3961e4d19792cf30c9a2bcc56ea2b78a7aeef6e794bfecb81ff00892e6264e1bf375f28c4f321049a5da1b532dbeb4aae378ed9e19cb1f62e102ae44c635b90c0c63d0a8c6fab2d0346ce3b303f0ffc3d300df95b59b1e68c8a4d5006ac558ff6e94a7d3434c27887716dc7c5e6a914b72410d0c8a3c432b2fe2572c893dc8bef0a5726d7fdd8233e21a80ffc29c96dd507c902c34863d4a37f9153fc307a18bfffd9ffdb0084000a07070708070a08080a0f0a080a0f120d0a0a0d1214101012101014110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010b0c0c15131522181822140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f004146684bbe5c06452bc6056c0c50b80c8a57818ab6062b6dd3156c0c55b03155d4c55b51814ba9be155e6293d2694213129e2ce06c09fe6c68d5a3885d2c5dfc29deb8292568215846e6a8768643ff00269ffe65be4a9c412f0a5c27fba97f77fd0fe836cc8bf3f0c0e5a934b1d7738ada91bc881e23738d2daf8ee4484c2c281bec13d2a7f65bfc97c9445ecd393bff00e567f510ca849faa3fc2412d6ec7a83fb51e2458759286fc1fe7609ffbcfc7f1b92674a0762863340c3aa7b1ff008aff00e2190068d15c3a8e1f4cbe8ff70aa41ad5b67ea4d7635c3c3d1cd94481b7ef71285cc48aa641d8fef074d9be16db046fe92eb32c40e4d4352adbd6587a8fe78ffaa57fe032fc72ff004b2447d51fe963ff00a67ff1c7ffd0457340ef970eb81578c0ab80c0ab86055c3155c3156e98ab862adede38ab46441df156beb318c554daf003b0c56d522d4aead9bd487becf19fb2c3f95c64a32312c2711214514d6f16a89eb6947d2b95159b4e7a03eef6edfb6bfe7f065a6025bc7fd2348c9286d2f547fd512e916504a49f2743b1f91f039486d9c44e347e9923ff0047c5776b1c966ced791a52685f73211f69a223f6e9feebfe4c3c3c5cb9ff00bbfc7f31c6c790e33c124bcdbfc2187c43bd3b7b30c8872b8c5d289878bd695c9852556b45dc6280ba51f5a80b2ff7f11049effeb57fcac91ef70f3e2bd87fc92ffaa5ff0010a2643723d40b495451e9de9fcc3fcff932128821d7ca467bff0013514c22146ab5b9fa4a1f6ff2321135b16dc1a830d8fd0aae1594a1a346e080c3a6fdd4e58ec6586392363f892f572b4249565262929d7dbfe365c1d69d2d989fe6bfffd1457340ef978c0abc0c0ab87be34869a58d46e7052549ef1548a0ae48045aff00ad1a03c7ae0a45b4d70fe18136b4bccdd30808325a04c4f5c348b6cc4e16a4ee7010a0a609676e2d9a78145d4141eb72056685a9f17d83bc5fe5e19436b8b8f29caebe99ff00d2bc88568b80e71fc7174af704fecb8ff8dbec3e441678f289edf4cff98b5aa47f0c5bdb883232c8a4aba9aab29a107c4361bae4822d36fad5a6a748b5122def76115fa8f85fc16e57fe667fc432d044f9fa66e3984a1bc7d51fe6212e2daef4fb8114ea518eeac0fc2d4e8f1b8ffaeb2a9031e699463963b372b7d658c93370b8ff00968029c8f8caabfb5ff167fc1e44c8dd97084cc7d33fe1ff004f042caef1304b95e04fd9980f81beef87fe0726da3318fd5eb87faa2d99244a0aab545450f6c8db903342eadd11785c4aabb8d994f420f553928ca8b6ca2242946e2b6d38ba83789b665f9fec9ff5b2446ffd175392e12e2ff959f8ff006d5d3c6bb4f1ef0c82ac3b0aff005c818dec573e202a71feee6a00b43d3e2818fd9ee0ff00cd5ff13c84655b161833cb19dbe95b728a260ea47a374b40dd83ad3fe36e192977ff0035753465c51fa727fbb7ffd204d76a18003ae681df16feb0fd00df145bbd49c9a74c516e226e1b9dfdb145ad6868072249c349b57444e209ed8589577a328a64156fc34df1a6417292bdb638da297aad7718db1a753e2a374c832017a4d25b4cb3db3709146e7a823f9597f6972519107644a02428a2888af019ac944376a0996d3a861fb4d07f3a7f3c1933112de3f57f31c3cb888def7fe0cbff0055507c448098c51c6ed17fc6d1ff0032e41b316a2cf0cbd3916024d3c305b96ab1884c9fbdfb34dbc2bfe57b6102d8ceeb645dbeab1409fa3f534f56c1cfeec13529e0d6f2fecffc636ff6197c4ed52f53af965a3bfeef22ebcd31ed23facdbc9f5ad3e4fb132f55ff00265fe5ff005f213c7c3fd56722328fe6e5ff00a68848ee996330b1125b3f543d2bff001a3e62994a1b0fa1c0e2e128678258519e1027b406af0b6eca3e5ff1bae5b1c80864686e3e9ff5355b55fac822c9cb102a607218ff00b1ad0e583193c99e3c847d27fcc5b708510acc8536a48a6a3e1fe65e5dd0fc58403c8a7264e2e63fae85b7778ddad1983024fa646ea7c47faaff006b237d59e9320df1cbe993722fa6684551b6a7fc6a723216d39f0981afe143baaa7c2df1c2db83dc1fe0f8227a38efffd32e0a396fdba6684077a5511097af5f0c690511e96f538582d73c4d300654d2fc5f6be8c282be368aa6bd076c056954d251fbbe8302869e2256b5a1180166d1e417c40c09454f637b6caa5c2b074120f4d8390a7f6b6fd9ff002d39a62451a6819604d7f121d6ac3f8e2dcbaa29f2c695ca78fc4a68ca6aac0d0823a1046054624b0ea2424ac21bf07f773fd9491bfcba7f7537f97f624cb7eafe8e470b369f6db97fb8ff008e29ba3fa860b85f46ed76f8b657f9ff002be42af6fe261875263e99ff00a7433028c55810c3a83d703b1042f51fbb2aea2488f543d308953564c3198dd7595c5ee9acd369cc66b63fdf5949bededfcd99109fc9d565c12c7fd282bdc2da5d402f74d1c637349ed8f40e3f637de1947ec72f81f2bcb8c558fa18ca5c7bff0017fbbffab8838e52a55d188a7d971b329fe5a7fc4933065020d869e4b2782399bd44220b9ea0aed1b9f11fefa6c9e3cb4aba1d56615b5bea903622415a7cebff00135ccce32473e27271e489db20ff003d07342518c75f8a3f8e27f14ea3fe032bbeae3e48184abf9a888ee6395794abf6b6929d2b913b396353c71a90e252963f4f63f1c4ff0065bc7fe6975c9100b8b28bffd40812a4b0f0cd0bbeb7475435fbf1b6242af2790546c0624a1671f88127e78a57b052411f4e05a580256846d854ec898d44628a7639128a5c412a77c0c8298e40788c2a89b6ba9615f4987ab6b5afa4495e2dfefc8241f14327fa9f6ff6f089743ea8b465c319ff005959a0826432c72fc2bbb48568cbff00317127fd4443fbbff230d0fc7fbf71c4e78f69faa3fce42dc432c32059578f2155606aac3f991c7c2eb80821cd84c48582a6df00a9df22cd5fea676292452f21f655a84d7c3d4081bfd8e0d9a0ea200d1f44913eba4e16cf53aa32ed05d11f1c7fe4c95fef20ff0088659c40ec7fd3b4e6d3898e28ad951ade6483528c371a7a33835574ff005d7edc792ebeafa9c4c79a58f63c9b9feadb7089a353fcafcd7fd8b1c84aaf61c2ec2132458319a924481aaae41ea36df2076478dde1502a2cdebc6c229987194f44957f9264ff008dff00632e865ef706708ddc542ee231b9914551b7a75fa0d3f687f3ff00cdf95ce1c27fa0d247543861c4329e71b751efff001abe63cf1b4ac9911e3024f8e21b2483eda1f0ff009b3ec608643134843012c34527905358241f64d3768ffc8ff8c6d9940890505dea0824e6bbc128f881fe5ff9aa26c157b1e6d987208cbd5fddcbeb44340550056f85baa9dc7b303801a2e7e5d30fe12fffd50d5001a743db342ef69a0cbdf152a8c78ecbd0e05a595a57977c36b4a8a5140a8eb815d2283b0efd0e1085e14851ef91290a946e20740705ab6ca540e5dfa789c6d0b24627a7d03084af85e6f56336fcbeb00d1387daf9648593b7363202b7fa5905be927d102f5e3855cd64b351cd093feec400afd566fe6f45fd3ccd8e9cd7a9d592232bc7f4ac9bcb36352df5f658a9508554b01feb13ff001ae0fca447f13903552ee536f2e88958da5e7243bf0954713feb15ff009a3233d182363fe99075025b4e2829ccb68de8ca14a7530c80c909ed546fef22ff005a3cc430943628184fd588ff00988bb39b4d9e1fa8dc131dbbee90cadc8237f3da5d0ff935265b1e1229a32cb8b698e19a0af2dee74a3e8cdfbdb36358671eff00e57ecb7f938d91b168b315915ddaa91f588cb03f6258cd2a7c194f46c946302cbc592bbb696fbfef9478a80c313871f7ca29f14ac6974a589e35bb652455048845186e3e2a7c3be583146b6971329e7b1cbd494b728dbd48e943f693f64d7e5fb2d984451a2e31d8aa5548f5613543f694ef4ff21c6572c6aa7b825e1ff9e9136e36dfa7ed2640131e68e5c94d635943245fb5f12c67aab01b85fe647cb8cbaa6af92274c92dae2036970dc268f7824f15fe53ff0018cffc266408c6437fa9c8c3964457f31fffd60b545f7cd0bbe6f92d00a6f8a15938924376c696d632823c2b812e750540ee31b452e04d00037c55548631efd7236a8bb3b582e61558ee912ffb5b5c0f4d1b7f87d39f7566ff008adf2c1107facd53998f31e843de5b5e5acc52ee378a53d9fbff00aadf65ff00d8640d8e6ce244b929a866a2a02cec40551b9a9d8623734c8edbb21b26d234388cba84aa978c092dd4815a704033698a0203fa4eb32ce533fd06e6d5347bf08b14cb2bb82ca54ee29fe4f5eff672464180895386e2d63532dd4bf0060bb9d89ad057e9c89932a513e6ed0526102cc0106945af8f881c708920c1636aba7de44e91832da9a7223ed01d7e1af86466624516511289b0a7358d8c72a4105d29f5d794714c37341bf2236ff85cc0cb8a858fa5bfc6121538f12f49352b1528d1996d4ecd19fde4647fc371ff006595c32ff9cd12c313f41ff9273692df46bc61e9ff00a248fd6ddf785e9fcbfcbc4ff2365c29c5a1745053e93aad88f5550bc63af13ce9feac83ed2ffaea993b3d53e1dee1626a8b22f19a14969b1a8a38fa30188236626479174eb03a2c96aa1428a3c752411fea9f886552df63e94101046b1b7242429fbffeba5ff87cae248d8b5f26db90284fc2edf146ebf65bde33ff00124c33875fe14ac601d832fc13762360c7fc9fe47ca784c7faab5dca2c3d46a9fddcea7ed7d904ff0095fc8f96c64c6248363ea7ffd702010a4781cd0bbe2aad50cbe0462ae00825ba8c50a869251576c0ab8a18f6ebe38a2da2c7a8c3c95512467254e0a5269cf1ad0ab50d7052414541abdf5bc5f5770b75667adadc0f513fd81fb717fb06c9899e5f545aa5841dc7a25fd045595a58deceb269ed25a5c0209b69419631bffbaae168dfec66cbb144195869c9290152f525fe72d32f9aeae2e0306b564555151c871fb54434e59942745c6ab083f26686ed79fa4250a96a3951829452484f8550f1f0cb25bb006931f32da7d7ac8416043b54c862ad095535ff0086a6572e6d913b305b1d32e24bb5840093ab135229d773ea13fc9fcb9394c00c44492cdb43f2fde5aa4ab3383f17a8889d3e9f9e631f516db005241325cc9e645692500c3298d61aee1013dbfc94cb0d089620d1b651087137182e843febd4007c0ae609d3f177333a8c721ea08c90c6d03c777241203bfc278b123ba9fe7ff6589d3ca236947fa991c5c86079712db69ae2dc2b595c892371c96098f503ed717ff9ad72b19a50fa870ffb86b5b72ba5df9e17501b4bbec57e127dd7f61f326330774100a5371a65edb31684fd6235deabb4807894ff009a72cab60410865911d4d09dbed0ee0fcb31e714370dc243586e97d4b394d5d7f95bfdfd19edfe5638e75b1403dead79a74d07c4a7d6808a86142c01dc72a7fc4b2793098ee19a0db8c838b9a301412753feabff00366398f722adffd00d2d36e3d0e689de076cca2bb11d30320d2721f0f518a0ab45c1589afc43016245ac927909269503a61480d45272eb80864ad4e8c0e047373293f1d715545af71b6284dfcb2d12ea20331577042ad2a0fbff0093993808b71b3dd2657da7c3a94725adc36dcf98a1a3000f6cb41b71ea92cd72e1f4eb382dace25658471e35e345e24afecb7edf1cb8cc0e6c040963fa7ead772dfb492c6429f850b0a1a9f901f0ff0091903901eee267e191ee4dff00445b5d4e6ee58c99d483507e1603701957af1cae520c85a631ce52e156955028a06e36f1db2027ba98ec80974259fcc4d3229e062f53980bb48dfbba71629cbf99a35cb6721cbf9cd12e484bdb69ac6610dfc4dc4ff752a9a1a7fc54e7edf1ff007d49ff000998d28907671eeb98722dc84e70482e212695e8c3fc961fcd83c6e85b4c011712a724a374914c66b5008a7c43f695c6caf920411b3513dee5be9d5383aadc43fb514837dbf94f5cc6963e0de3c91c48ab6be8a4a476f27a6e7ecdbce4d2bff14cff00b3fecb2c865ef4892cb9fabc92d2e6229703a9145940ff0093770999077e682025b245c6aa4f28ebf0c9daa7f9bf9397f9594485ee3ea604376f77240be99660a87e0a6f4f18c8fe5c23248726719ed4554fd5af41920fddce057881f03fb7f92f93a07fa326443fffd10a010941db342ef5cea4853d31a5b71a8db0daaa2c741cbbd322b6b43028477c36a172321a2d36ef4eb85051df51b79ea6ca67603fdd72282df743fbcff9218816e39ce63f547fce82d9ecaee1425a23c17ac8bf1a8ff5997ec7fcf4e180c08e6d91cb19722a119a8d8d4642edb2a91567772d8ceb3a286e3bd0fdd96427c2c251e2d994c37515dc097708a73ea3a508ea32fbeae298d6c82beb2b49e40ccb566501e8694c84a56a364b868b60438512a30aad5cec057aa7fad912cf88abdad9db5af268dbd491fed3b126b82c3177d60ab0523f7a3651e23da990e3ae49a51b86774f52260b206a518d0353b57a65b3c6271dc35dc41f52d1a8defa5e8de42b756f5af0701c0f97fcdbc331c4270fa4fa7f9b93f7b044b16390f49ddb4d32ce443796123da114122d7d44527f62689ff78abfecb8659296d731c23fd5717ef21ff5520e11810578b67a8170a9c0f565a143feaf2f897fd46c71e312dc1e28ff003db04c72285d434f88716b220cbdd41a0603b7f92ffc9974aa2838ac584a5944ab55146eebd0d47fc45d731e78eb71f4b8c42261d424745b7b98d6e13f6437c249ff008ae41fdd4dff002730e3c9decc4ef62b8c42405ed59a451f6e1701674f665fb32a7f94b992636b4839103fc4bd40a3507fc497fe69ca0c29890a40cd0b196da429211f115fb2e3e5f6792fed65b8e49ba7ffd204ac6847f29cd1077a5b94d5415342305a405e1890396d8a17972011d8e05a5a1558541fa3254ad8dba0c89415cc5168c5803db7a1c8dee94d74dd535c461f5612dd20d943c6d2fdd2ff0078bff2332c139071f262c679fa53a4b68b50ff008ea68df5673d6e52448cfccf17497fe0e39309cb0fe2718c8c3e99712125f2bc124852c3525e5de19c02c3fe7a43ff0054b1108c85c4b6475247d4133d2b47bbd3a2786722449086468eaca08fa36cb217ca9ae59448da85d958d8d68a01a9f9e448a66929bdd8b156690d4d0d2a773f645720432541729c0349fbbaee01d8d7e5f6723c29507b98e58d8223b236c5c50135ff00294f2c44775533084b329407d261252a402a478d3e16cca22e2e3643d7ea5042a4d2191d1fb46db9fa01fb5fec731ce49479b4544f24442fa8c3209a123d451427a120f54746f85d0ff2e4e19c141890aebeb486ba7ffa35dd096d365358a403ed1b476fb3ff0018321e142478a1e89ffb5fe3d6c774326a7652394bb89ace753466009507fcb5fb4b8d9e531c7fd3ff008e289d7f456ded8b301710953cbfdd886b1bfcc8fb2f96406de9f5458cb74ba58dbe2122904f5ee0fd23f6b2ac98ba86b21bb79564915269bd293a45707a57f96561f67fe327fc1e4f0cfa151246cd14a056f63229d2ee2dc1a7f3d3fe36cc8316c41cf03a7ef54d56b559d3707baf35ca8c5487ffd3020717627eecd13be5f5464a537c6a94398d63a771815b6ad14d36c2aed81d8d305aaa2b71ebbe2c4a261d5351b788456f3fa510aeca881bfe0f87a9ff000d878880c258a24d90e9351bd97fbcbb9893d6b2301f703903ba46388e8829248e4243c9c8ff0094d5ff00891c9726c0172b2250ab0520ec41a11f7645245b28f2a6a93cd742d1a57998ef52410a83aeff006be2ff002b2fc26465e4e06a7081b81c288f340f4ede62a7e1edbd376d96b97ca36d512c611ee53e2455151bc8db9f6e208ca886db55304b39ac95770a3e26dc1ff558705ff63913b2844c10848c03d3b904d1491b2af7c54ad33b4370afc8bc75a156028694f85d5fe7fecffd865d16b22d52e2c6c6ee431c0cb69766856ddc9f464aeffb990fc513ff00919135745c79e03563e94ba57bdb398c3731b161feeb9366a7f34727d9917289e00d70c862771c4bd6586e8704dc8df86eb2291fb4bff35a65423c27673632c531e6acef0df7eeb512639d4521d4694e9d12f147ecff00c5d97c6427b7f13873877a008d4348b82a3e027765fb51c8a7fe15d5b2128906c7a64d2418a6114da66a29557faa5d81f1c6d531fe1f122ffc27fc57968c80f3fa990a285bcd2dd7775a06140e08e0dee1d7f76fff0012c89c37c906086b39a5b2b9157709d3634f9738cecebfe52e4019439223b1ddcf70219de480810bff0079074e04f8237fbadbf97270993cd9d81c9fffd42f243c25abbf439a177ab829f41586e461485e854aef8a96c9d80ed809400e27db14a2b4e843191de286e00d96296678587f94be97db5dff0069b2424073f534659575e0ff00378d1aab3807d2d1ad8a8eebea5c9fc266ff0088e489be51835c4c4ff94ff78856d4e58e4f4c5bdac0de1f5740dff25393656dc3103d67fe99b3abea808e33845ff223897f54782ad7c18af6d5b56a81f5b6fb97fe69c8d2f830ee4ebcaf7d773df95b89649288c4542f0ff8255079664e9e2372e3e7801c95b5cb849a43105a981bd4753d0d415562dfe4e59293500c7c5c962591f88e34f8791dc6d56e0a51707364a678c8dfbefeed8d43f226847ec06e2dff0012c14955706d544d0b978c925c354d36daaabcbfd5c1ee48423cbf59491e50fba5551c31534db97f332f25c98084d34bbeb960f048cbea6d21f517929af872183266e08f11f545a32c48dc232e99ee53d39922962eca095a1fe64e43f76dfea36637e7b14baf0b8dba4b75a44cbf1c2a5941aaff003afc9d32d8ca33fa489b03143adf5c43f05d2974ff007e01f18ff5bf664c1c1bb2190a211bd5b5290d2eecd7708b5e7113d7d30df614ff00be1fe1ff007de58058fe72d8297cd6ac8ab7103168eb45916a0ab0fd86fda4917fdf6fff000f954b1b5ca3d42adb6a972adb4ab1cadf69641ca097da58ff00dd6fff00162e08e431e698e4ef45f3d3ef58c6ca6c2f36e56f28e51313dd3f69797ecf0ff80cc8b0596c50d7367716e47a8bf0f442dfbc8c8f04947c4bfeae44c1487fffd5049120520fed74cd0bbe5aa4a5623d3b61b43668003f7e04af60081c4d710abb7e3d3150d275a9edd312aaeb7130e87901b8e5bff6e104b54f0c25cc23e1d7a6f4fd19e332a56a43307afb70b959d3fe078658329ead074a07d265055171e5aba3fbfb5fab37668c345bff00cf26960ff828f0f140f4470e68f5f11b6d2f48937b6d45d07fc5c8241ff23202b4ff0064991e089e457f3528fd514c7cbda34b6f7ff595bc8648f895e309e5c81fe6e4070cb7140c4f3639351198a0a7a8cdf5ad46f618d7f76a8ab24d4d9096f857a7c5cf8fece277b3fc2c46c93c5c176820370370f248dc54d3ad07c47f9b0852e8a4819f82aba4ce3ecb100151fb5cbfbb7e0d894b83f0726828013c76049a1fdbfd91fb1f6300494290cc232240a2de527e2d9b8efc457e8fdbc3cb74aadbdc309a458fe37e4514bec033372f87bffb1c4ee2984a361486a6dea324ea55949078310cbec47d9ff85cd64b0d1e5193863311b111c9f8fe7a222b89dc836d71cffc96d9bee6fb5fec1b2bf0b1df2e0937c4e19f596292a3dddc0a8b8b65b8a75e20ac9ff0b9911e38f29717fc358e4c15b8f5a943169f704dd59c8f6b327da720803da49a1dd7fe7bc7993191fe21c1fee1c7e1ee54985cdbf2b8951984aa14cc9c6486503ecace07c127f92cafeb2659115d78a2991f24b2ea1b6928f0b712ff006a16af253e15217d54fe493edff3e42510d5200a1a42c144372090a3e063bba8f6fe78bfc9ca85c4d860af05fdddafc25fd5b77eb5f8811fecbedffb2f8d332232b161b04cbfffd6031d47153bd33436ef4ab48a8407ee303105498549a8a57b61661c15147204fb8c2bcdc26ea302697257ae142f0180241db02aa4450835eb80a14a5923435e4057c4d30a5a42d291e8ab48dff1582dff0010ae1e1250481cd9b7972c961b56ba625e5084739119245e5d636f538f2f8b2ec479ecebf201c5c90b7104834ab8a49c5a79eaee4feca9e2c397d0dc72c3c9039a5770f6f6f32c0b2fa60806320f214ebe0fd7ece0b4d28349c88e6cab226ed22d0fc15e343c3e7fb591b64021d8842792855ea25534e4acc7c7ecbc7f1e1e4c963b80ccb20f52265ddc6c58f2529cff006793237c2d8aacb84b78e14735e71060f1b1edcb9090ff00b1fdbc9310534bab817400bdb45bc8828e2e0fa772a3fe2b9d7e197fd4972894c5d49c79e2dad2e3a4accc5b4b9fd7602ad6930f4ae947fa9f626ff5a3c89c40f2714c1463d56f6d5cc5282c17668a50430f60df6972a11ae4c7888d9596fb499dc49ea4b61783a4a3fe6baf075ff8c99903250e5fe919095f3565ba961667594daca4ef796eb5b792bff2d76a7947f17f3c7861901e5cd9c85352ded993e9ea76a2263bade597c51303fb4d6e797fc93cb2c16b3b736ce94268ccb6732dcc1d8c441dfc1a193a7faabf1e44c014f08297496f244e50a509fb711ac6d5f1e126dcbfd5c8f8647263c2ff00ffd70714cb4e2c287c7342ef08688624a83b1dc6492a6cee0056fbf032a54550072eddf155ace2b403154c2cec6d668565b9d52dad14ff00badb9c928ff5a28d47fc4f2c1189e72e16896420d08ce48af43cb10afc77d7778dfcb6f0ac2bff000571cb0feec759cffd830e2ca7946305a350d161ff0079b480fe0f773bcbf7c49c23c1c71e911fe7fad3e1e43ce5fe922dfe9ebd8ffde5b7b3b5f030db203ff0527a988cd21cb861fd48a9d38ea672ff00396bf98fcc52502ea128af5081100ff8045c7c599ea57f2f8c74ff0074ccb49323e8debcd2196491896918d6bc7c5bf6f7cb79071081c5b297a024d3a2a9aaf00f53debf157091b24318785e38dc321579233520026b1b5517e85f838e42e992044a5a354a162edc5bf9881b3a9a53972e5819ad242fa4cc2aacb5414242853c69fecbf6b092a16f051007501594717402a79c44d263fceaf1affc3e1082ab3442432c4c540b9d8b9da8a9f60ff373fb6af930d76eb8b896194c687e0005032123fe0d331b2920b44f9a8cf7e974162b88a3609ba386e2411fcac7ecff00c1657c67faac7c4dfd438d7fd7d5d047789f5d8945019852651e0b7517267ff9ed149931901e6d72ae9cbfa6a0fa76997009b3bd485bfe59ef3f767e4b2ff76fff00099214587084235bea365554e4233d42912447fe00b2e020140b8f25d0df5bec92afa0e4fc45be28181fe651f1c792163fa49e25ef6bc24f5ec2436f29e9c5eaa7d9255f8245ff0021f2519772f0f72a2f982e633f56d5610ea362c52b4ff5a13c78ff00ad6ef0ff00a99602912e85ffd02c247d07639a2a77d6e4e492712d51d8fb62abb93d781dc7638a5c9271aa3fd18a80b969d69be2abc10e2b4c690d9507be34aea6d4270a1b4a0ebbe04aa5b5b4973770c10c6667958288ebc6b5fe66fd95c9c059a613342de9d716cb69a6c76ab4e30a70a0141b0ecbfcb99193675b0366d0d391241e9aedcb8afd046259247ae46b180a09640383822a0d7f676ff2b22424243c07a3ea722acc415a6c43fed1f8bf994640ecd8163b28919dea579536eabca9c9957f6b953960b674a719632712956e202b13b80c6b1cbb7f2fc2b264c302e2243095e61a58824709068c4305a725ff002fece4ac302a92dca2c6ec8eccb03d24ea5806038bfc3feea6c8ceda328dad456ea09d6a1d2407af200ffcdd949e1ee71812d1b681ba253de36ff8d5b0080292a66cea3690d3c1d7fa63e1ad297d5264de350478a1a7f4c1e19470ac904c3e1903713fefc50dff001218f090b4a2aa884940aa18fc416aa0fcd3e28ffe170d9452a492a4b184951881b0e8f4ff0057ecb532624921ffd12c4ad37fa7e59a277cb97d3120ee298a151c4551c4efe18a45a97c153cfefc29568e95e9518b154a8e1b0f91c5429537eb4c5936a050d4e255cb5af88c21059179212cceb8b24f2309954fd5a1a3519c83bf25f87e04e5fdee5f82affa4e26aaf87c9975d3dcfaa03c7fbaab72351d3efc079b44690f63ea7a0ad37fbd3c6813fca25a8dfc9f0e4c72f34148b5712f3201d81f88d06ec38f1fb5d392ff00c3fa780b20912024c8010b1023d46dc866057ec86fb35ca8b7053937993d51420b98c2f526bf12ff00c4b10bd165bf2e4fc79730582914a94a0f8bfe0f2410548888151390ceb10a13fb5f1c9e8f3e8abb1c9b145693eba487d1e323721eaf0f85b9fc43dfe1e3f137fbaf24d53e4b7547d3da42b7090a4d5dda124c9fecf81ff89ae532a71881d4c50eb670984c916a0aa46e90b472927dbd454555c8d0ea58103a158ad7a281958f8107e1ff00929c700f26255d1af00354aa7ed5294fa78b53137fd1670e2fe92f47988358dc0f10415ff86e39304adf7ac9bd11f6f81f10680ffc2e1d9050a7ea27c54ff93538fa50ff00ffd9"; + +/** + * Duck Matrix avatar with no EXIF information + * 88x88 + */ +export const NO_EXIF_JPG_HEX = "ffd8ffdb008400080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080058005803012200021101031101ffc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00f39d2237f3223f398e3765047cb8c95ee0f1d6b73c66037852c2786479049772073d7e652ca09ef9da1067bedef597e15b382ffcd6b89248e08d1a57208c95040c73c67381fad6f6a176ff00f08d491adbdb5bc12cd3b24580f85405b71cf392463230319ae09de334cf16ab71aa9f6397b2bb824d34690d641e6ba789d67de4ec55dc08db8e739ffc77a77ad6f14c7e4e8f3a12c156ed157e5c06468f7af18e0ae48fc4d72d2cc069ab2c4e1255941054004647b723fce2afbea4b35bc534c91ce63456944a5fe7cf1cfcdea2b4941b69f6379d36e4a48c270c08638e4e79c1a78cb49c138dfcae00ae96d239b5dba8ec2db4eb37915c6c2a879382704e7a7afa558d6f4fb7d1960b696dedbce89dbed3322ee5dc73b541ce7181d7dcfb55f3f4ea5fb7d795ad4e6e20de747f7940751b94e0823dfd7393f8557946f676ddb882492ddfd4d74497da4b3208e21bd54b380a4ab10383c9fef13dbd2b2afedada1b62f1caccce0328ddca8c904118f507d288b77d8709b6f556330f2d96ce3a015bda8d9a4766080b1b9c30dc39202038f6ebfad610daad8dd93d2ba0d5ee20480c250b398c6370230c55727f43c7b83454bdd58755be68a464a320310192cbcb7bf3c7d2ad79c3fe790ffbec5500c1ee03e554f650381cf4ab7e637aaffdf34e511ca26ef871e38f4c2b72ec90dcc7246c40e87820f1fed0157ee58c1e1f8e1701fcfb7bb73701b2782c17278e4e31f8d67787525bab3b6b5891371903296c839049233d8607a7f2a97c617d6443450cafbc41e4f979cedc480e4e3f88e1f3e84d6325cd3b1c938f355e5f3ff339b1103a0ceed8c89230b93cf20f6ff3d2b4edec74a78205b9bc811c4232584ae33d7b0c743eb546403fe11e90855199a2048ebf75bfcfe745a45e749045bbefe130173d87f3ade5b5cea95da7adb5fd0f45d3751d3f4ad16eff00b25650af84fb43a005c842c4a8c7ca33dbdfd79a5b1d60ae9aaef70ce59fe645c640c77eb8f5ed54b50b29345f0d258c36acf700abf9dbb2a176307e339c92c3f2ac981e5b8d26178623b3cdd8caa48f9b1d40fcff004af1e718d6bcaf7573c274a15ef34ee9b23d62cac6fa39aeac24115c451ab02bf2994606e040ee3afe159fae5d68973046d60eff00687b687cc528c01942fef0e48ee467d39ae834ad2ede7d3cdc4c678eecec4822519121dca1b771c0c67b8fc78ae28c6ff69103e4183cc420f452303f9d77e167bc2f7b1e9611ef0bdec5265c3b1381c9ad2d5a4f308da98071839cf1b4553995448e064904d68eaa85d62906d0b21200ce4f0060febfa57549ea8ed93f7a2674118f35493d4f738ef5a1e5c7ea2a8daa05ba0092464638f715b388ff00baff0097ff005aa66f514e5a973c2d7690de69ee085114d997cb3c84dc324e781c1c0fcbbd67f8b12d12ee21668c525432f98c319dc49c019ec49ebcd47a6ca122910a9632945dc075f99491fa51ae4cb75696770a71b435bb26dc7cc9b4023eaa53f106a52b4ccd46d56e432b29f0dedd8438953e6f6c356cf83a289b534bc755cc4b84c91f78a63fa1ac09a50da394c6312263fef8357bc3b7820bd87cc70a98663ce390b91fd696222dd29242c44252a334ba9deea69fdadaed858c7ff1eed3624562402157241f6e2ae8f045b2ea4f7104b2a83f398a33f2ff00fab9e94786d22bbf10ea17330c24312c28ad93b778dcdd47a103f3adbbb92ce0b416af6eec8b242d12a9daa02306c75f415f3739384a34a32b7f57ff0023e5a729539468c25cbdfe7aff0091c668ccb040efd337b2246a4fdd507a7f21f8572dacc022d55e751b7ed11173df2df2e7fc7f1aded5266b5d64c31102d64b93329c1ea71b81ff003deb06eaf61943b48c15a3b726204fdf62ca08c7d39fcabd3c2425ed1545d51ebe0e12f69ed57da4624aaf966e0f3cfeb52dd2954419184381f2f3d05432c81d9f039dd525e3670dcfcc7238ed815eb3bdd1ec6ba1108df7a32fca4fcd9f6ab3be7ff9eaf4e28c90db3908721bd39edf851bff00d95ffbed6a1b6c4e4c8d09f29b24001b8c724d47733a3e9f1c25b748269246c0e06768fcfe53fa540642c140e0f5a85f00c9c9232467f1ab51d4d1435279189d373dbcdc0ffbe6b5bc3da59d46e115c95b645dccfbb1db381ee6b24465f4c8c2ae59a7238ea785c0fd6bd074cb78b4ed36ce348b6489bdda403efb6d1819faf4ed58e2eafb38596ece6c6d6f654da8eecdfb4bcd1747b4bab97b88fcc91cccf1abee21b0011d4ff7455af0f78874bf107da229191368f944bfc5e983eb9ae07c4897579abb2b4437f92dd0e78cb1e4f6ea063f0ad34b77b6d2e196097c989275dcc0fcb8cf07df91d3fc6bc6960a125cf277933c196029b5ed24ef264fabe971b6a0f34d231637281610782bb179cfae4f35c36b9118278d55711053b4eece7393f875aeb2d01934fb58be4dd34b82fdf3c6093ebcd50f12e9d35a68c84aab2994124804ed2a0a9cf6aedc34dc26a127e477e12aba7523093f238f0c431ee2ac5c1dc839c76e9ec2aae3939e2accdf740230700f1f415eabdd1ed496a89d9898d12304b1183c74e9f9537ecf71fdc6ff00bee9f02949c646723af07d2aef3ea3fef81fe358b958c5cb976326509bd4c671c66a13cc9202d9249008e879a9a28fcc915482d8c74f4f4fd29b2c47cc28000ccc7a718e6b54eda1b276d0d9d374c59921921bdda613e7b0d9feace40e4fe031f515d6a5fdc5c4762218484077361b710c1704e3fc79fc2b8101ed8c76e18b1620b2a92703d0d7576d7d7b234652297ca8711ab20c053c33738ea1413ea33cd7257829ee79f8aa7cf66f52cebe5a59b0a479e20e7202600c7279e7e503afb7b55b8b4d17761299278d48995941e8c4f619e9c8ed9eb5951debb089dd415bd690c8ef92480aa38c7beeff0022b46db599ed34d82285329f69655ce0b1c8c8cfbe4e7a0e9dfb72ba524924724a9ce315189b6be1f96c7c356b7df6a19494c8230be8aa7f9f1f8573b7c50e9f3aa157064390e3214f039ad0bbd4ef648058cb18110060f32318071cf5efc05ebea69935846da7cb6f05d7cdbbcc65765f987ca4120fa8dbd339352e9fbe9a308c1a92933ce6f23733190a0505413b5703a75a7dc6d65520a9278f93d38c1ae8d3435d56e21820956dd6e6421372ee0ad8395c819eddbd6b2752d352c228e179775cabb2b2e38e081c1eff00e7d89f4a3513b23db8568c9a8f51212f13a606ed8a7273db231f5ea2adfdaffd95fcab3e26de09dc49200faf200a93ca7f43fe7f1a9924dea4ca2ba9bda07832e6f744fedb9e4f2ac62c8760a4b37254e077e78fc863ad564d08ac575a82c53f90a5b0cc46460f53ff00d6f41eb5e91e1eff009230bff5d07fe94d611ff9136f3fedb7f4acab4dc76ea7155c4ce327eb6fc4c4b1d19934d6d42e1dff0079033e32b9298c76c93ce39c63247d6a16d1ee12de44123652356711b10199c16230072428231ffeaaddff0099661ffb0537fe8694f8fef5cffd744ffd024acf99dd99fb69ddbfeb4665da5919e7b7d309002c6b3b4c80b1562776d23db38ff0a8a08becd10bcf3e5024b860d2956dc0a052ac08e33b891dfaf6ad2d0ffe461baffaf71ffb2d55b9ff009142dffebea6ff00da7426f99af41a9be7b7a7e25f8352fece85a2f3ae64dea920287a000aed6f4ce0023dbad56b6be83c889bcd966b52de5323aab051d53195279c9c71fe150c9d67ff00ae6bff00a35ea869bff2094ffaf8b7ff00d0452b68d87b34937e65775bb8c491492b8b4998491859182ab60a838fa8c671e9cd634d1bca249b73b4a8db999c92d9cf27fc6ba3bfff008f3b3ffae51ffe8c35889d6fbfdd6ffd0ab7a6fa9d9464dab95ac7f7bbe4567f300195c71d6ae66e7fb8ff0098ff001aaba37df9ff000ad7aaa9a4ac6951da563fffd9"; + +/** + * Jelly beans + * 50x50 + */ +export const JPG_RAW = "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xdb\x00\x43\x00\x03\x02\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x32\x00\x32\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1c\x00\x00\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x07\x04\x05\x00\x02\x03\x01\x08\xff\xc4\x00\x1a\x01\x00\x03\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x05\x06\x03\x02\x01\x07\xff\xda\x00\x0c\x03\x01\x00\x02\x10\x03\x10\x00\x00\x01\xe7\x14\xd4\x6e\x92\x6e\xe0\x67\xd3\x01\x2e\xe2\x61\x94\xcc\xb8\xa2\x6a\x9e\xa0\x8a\x71\xfa\xde\xdc\x52\xd3\xd5\x89\x16\xe1\xbd\x57\x6b\x4c\xc9\xc9\x02\xad\xcd\x3f\x3d\xe3\x0e\xfc\xcd\x61\x95\xe9\x08\xa8\x74\x05\x4e\xc3\x14\x07\x5d\x62\xc5\x22\x57\xb8\x0f\xbd\x49\xd9\x50\xd2\x6b\x46\x3c\xe3\x8f\xa1\xd5\x83\x2d\x27\xa5\xbd\xf3\x24\x99\x82\x11\xf5\xd5\xf3\xf0\x05\x8f\x34\xbc\x16\xa5\x83\x00\x74\xaa\x86\x66\xb4\x8e\xf2\x89\x13\x88\xd9\xe2\x16\x56\xe5\xb3\x4a\x8c\xc9\xc9\x61\xa1\x95\xa5\x1d\x7e\xb8\xa8\x67\x65\xf3\xbd\xa4\xa7\xff\xc4\x00\x21\x10\x00\x02\x03\x00\x02\x02\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x01\x02\x05\x00\x06\x11\x12\x13\x14\x16\x21\x24\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\xd9\xa5\x49\x5a\x1d\x6a\x39\xf8\xfa\xd5\x03\x98\xe6\x61\x44\x16\xa2\xc9\x82\xb4\xbc\x97\xae\x9e\xe4\x63\xec\x33\xd6\x24\x4b\x29\xa4\x98\xad\x5c\x4a\x68\xae\x4e\x5e\x41\x3c\x3f\xc8\x20\x0c\x4b\xc8\xd4\x42\x34\xb8\x7c\x2f\x3a\xd1\xea\x3a\x36\x19\xf4\x4d\x42\xd9\x41\xe9\x02\xc5\x8d\xbc\xd1\x45\xeb\xf5\x12\xcc\xb3\x9b\xc0\x8b\x17\x23\x99\x8e\xad\x9a\x67\xb7\x46\x65\x35\xd6\xa5\x9c\x81\xf8\x8b\x5e\x9f\x2e\x83\x4c\x35\xcd\xb3\x83\x45\x1c\xe1\xd9\x85\x35\xf3\x1c\xd2\x73\xad\x3a\x1a\xbd\x67\x87\xed\x89\x96\x96\x79\xb6\x11\x45\x9c\x9e\xb3\x03\x9d\x0c\x77\x06\xf2\xb8\x9b\x9f\x0b\x5a\x42\xaa\x4b\x58\xa4\xf6\x14\x45\xf4\x3b\x1d\x2a\x4c\x6c\xe5\x82\xba\x7d\x8f\xf9\x91\xcf\xa5\x46\xa6\xbf\xeb\x12\x0d\x7f\x1f\xff\xc4\x00\x2f\x11\x00\x01\x04\x01\x02\x03\x06\x04\x07\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x04\x11\x12\x31\x05\x13\x21\x14\x22\x41\x51\xa1\xf0\x32\x42\x71\x81\x23\x24\x52\x53\x61\x91\xf1\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\xbf\x0e\x98\xc3\xc0\xfb\xa1\x19\x71\xca\xa8\x5b\x5d\xed\x73\xd3\x38\xe3\x98\xf7\x35\xad\x1a\x73\xfc\xa7\xcf\xda\x7b\xce\xf1\x4d\xb0\x21\x69\x0d\x0b\x4b\xcf\xce\x54\x5f\x98\xac\x1b\x28\xdf\x1f\xd6\x56\x98\x23\x9a\x37\x39\xbd\x4e\xde\xfd\x17\x16\xae\xd7\x5a\xdf\xa1\xea\x9d\x0c\x6d\x6e\x85\x2b\x66\x2d\x0d\x8c\x74\x5c\x2a\x06\x13\x87\x0c\xe1\x3d\xa0\x38\x85\x74\x4d\x5a\x00\xe8\xc6\xdf\x4f\xa2\xb1\x62\x6b\x04\x03\xd7\xc9\x43\x34\x92\x3f\x4b\xdd\x9c\xa6\x70\xfa\xad\xf9\x7b\xde\x6a\xd5\xc8\xe0\x7e\x83\xb8\x50\xdb\x9f\x99\xad\x87\x01\x3a\xce\xb7\x17\x13\xba\x3a\x2d\xf0\xf1\x8d\xb4\xfa\xff\x00\xaa\x0a\xd6\x2a\x1e\x7e\x94\x6a\x56\xbc\xe6\xcf\x19\xeb\xef\xd5\x5d\x12\x4b\x16\x23\x2a\xd5\x52\x23\x2e\x27\x38\x5c\x3e\x28\xa5\x92\x31\x27\xc3\xe2\xb1\x18\xe8\x1a\x14\x1c\x4a\x0a\xf0\xb7\x4e\xe0\x6c\xac\xf1\x37\xd8\xee\xe3\xba\x9c\x49\x87\x9b\x0e\xe3\x65\xda\x6c\xb2\x42\xf2\xed\xf7\x54\xa4\x80\xc4\xd9\x2c\x63\x27\xcf\x65\xc4\xed\x40\xf7\x35\x91\xbb\xa8\x59\x72\xbf\x15\x53\x8e\x46\xfe\xfe\xcb\x46\x32\x15\x2c\xb4\x38\x65\x5c\x8f\x97\x28\x78\xf1\xea\xa4\xa3\xda\x86\xac\xe1\x4b\xc3\xa1\x90\x08\x88\xc1\xf3\x43\x81\xd2\xfd\xc3\xe8\x9d\xf1\x39\x40\x01\x99\x80\xf9\x85\x60\x72\xec\x38\x33\xa7\x54\xd3\xf8\x79\x55\x09\x70\x76\xa5\x6f\x67\x95\xce\x93\xf5\x15\xff\xc4\x00\x2f\x11\x00\x01\x03\x02\x03\x06\x05\x03\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x04\x21\x11\x13\x31\x05\x12\x22\x41\x51\x61\x71\xa1\xb1\xc1\xf0\x23\x32\xd1\x33\x81\x91\xe1\xf1\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\xd9\x04\xef\x90\x2c\x3d\x4e\x1e\xca\xb2\x67\xc2\xc0\x19\x70\xa4\x95\xc6\x1e\x23\x74\xd9\xef\x8b\xee\x70\xbe\x9a\x76\xfc\x2a\x9a\x82\xe9\x4e\x04\x80\xb3\x09\xb3\x8e\x3e\x3e\x48\x6d\x9d\xdb\x64\xb7\xf8\x51\xc2\xd8\x2b\xfe\x96\x83\x1f\x45\x0b\xf8\xae\xab\x33\x62\x95\xed\x6d\xef\xeb\xa7\x9d\x94\x59\xd2\xcb\x8b\xec\x42\x73\x23\x67\x2f\x9c\x96\xc9\xa5\x8a\x79\x1c\x65\x18\xf0\xd9\x09\x48\x18\x0f\x45\x43\x4d\x9b\x2b\xa4\x71\xd7\x45\x2e\xfc\x2e\x31\xcc\x6c\x54\xad\x8a\x30\x66\x2d\xd1\x06\xc4\x00\x99\xfa\x15\x56\x59\x39\x73\xe0\x1c\x3e\xea\x16\xcf\x01\xce\x88\x1b\xe9\xd1\x3f\x67\x4a\xf7\x17\x11\xaa\x86\x4d\xe3\xbc\x3a\xa9\xaa\x29\x6a\x1c\x23\x79\xfd\xd5\x7d\x29\x7c\x6e\x11\x1c\x07\x44\xfa\x82\xfd\xd1\x26\x16\xeb\xa2\x64\x9c\x43\x28\x6e\xe2\xa1\x9c\xc4\xe9\x1b\x25\xc0\xbf\x6d\x7c\xb5\x42\x68\xb0\xfb\xbd\x11\x95\xad\xa7\xc8\xe6\xa9\xa9\x44\xd8\x1c\x78\x8f\x92\xa7\x7e\x55\x66\x4c\xda\x1d\x7a\x76\xf9\xe2\xa4\xa3\x8a\x46\x6e\x39\xbf\x31\x54\xf1\x06\xcd\x23\x59\x89\x23\x9f\x8f\xf7\x8e\x2a\xbd\x8d\x8f\x8d\xd6\xd2\xc8\xe4\x63\xa9\x55\x55\x70\xc8\x04\xad\x07\xba\xa6\xaa\x19\x8d\x7b\x6c\xb6\xa3\x9b\x23\x98\xe0\xdf\x9e\xfa\xaa\x08\xc1\xa7\x11\xbd\x45\x3c\x9b\x29\xfb\xae\x18\xa3\x2b\xaa\x5f\xbe\xe3\xa9\xd3\xb7\xfa\x8e\xcd\x18\xd9\x3b\x90\xef\xf9\x54\xc4\x87\x38\x8e\x40\xa9\x1e\xf7\x81\xbc\x71\xb7\xb2\xd9\xd2\xbc\xd8\xb9\x48\xf7\x1a\x9b\x9e\xbe\xaa\x8f\xf5\x23\xf1\xf7\x47\x55\xff\xc4\x00\x2f\x10\x00\x02\x01\x03\x02\x03\x07\x02\x07\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x00\x04\x11\x12\x21\x13\x22\x31\x23\x32\x41\x51\x61\x71\x91\x33\xf0\x05\x15\x42\x52\x72\x81\xb1\xa1\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x4d\x71\xf2\xc8\x74\x97\x23\x97\xd0\x1f\x9a\x4b\x62\x0e\x95\x50\x4c\x63\x65\xd2\x69\xa5\xe0\x17\x94\x12\xe3\x9b\x53\x1f\x21\x4b\x24\x7a\x56\xed\x54\x1d\x12\xf4\xff\x00\x95\x1c\x57\x3c\x27\x98\x13\x92\x17\x6c\xe6\x99\x63\x0a\x90\xb0\xea\xa3\x07\x39\xde\x9d\xbf\x36\xbb\x19\x39\xc6\x05\x42\x67\x71\x3c\x93\x91\xac\x28\xdb\x3a\xaa\x07\xe1\x2c\x4c\xd9\x8f\x5f\x4e\xa3\x1b\x8a\x33\x63\xe8\xe7\x58\xf4\xf3\xf8\xa8\x73\x20\x3a\xfa\x11\xb8\xac\xb3\xa9\x45\xc9\x5e\x7d\xab\x07\x94\xe0\xb0\x22\x97\x55\xc2\x83\x8d\xc6\xa1\x56\xb6\x82\xec\xdb\x88\x70\x57\x4c\x7f\x53\x02\xb8\xd7\x40\xf6\x03\x66\x3d\xd6\xf5\xac\x22\x95\x4e\xb8\x5e\x95\xa9\x53\x97\x57\xd3\x45\xf5\xa6\x78\xad\x9c\xc5\xfb\x54\xe9\xfe\xfd\x29\xa0\x96\xe9\x4d\xc4\x6b\xd3\xc4\x7b\xd0\x4f\xdb\xb6\xf4\x62\x90\x88\xe5\x83\x1d\x5b\x1c\xc3\xd6\x83\x7e\x22\xdc\x18\x50\x03\x11\x55\xc3\xb1\xf3\x7f\xb1\x53\x76\x41\xb3\xe6\xdd\x3c\x32\x2a\x49\xa6\xb7\x6b\xce\x1a\xe1\x44\x60\x64\x93\xef\x5d\x94\x26\xd2\x72\x46\x1c\x91\x81\xbf\xd8\xa5\x62\x07\x1e\xe0\xe0\xe8\x18\xd7\x81\x9a\xe8\xc3\xd3\x02\x96\x6e\x49\x84\x8e\x18\x37\x9f\xf7\x49\xca\xca\x9a\x87\x67\xe0\x7d\xea\xde\xe4\x8d\x06\x16\xd5\x86\x3d\xdf\x03\x51\x49\x12\x34\x90\xe7\x02\x42\xa7\x07\xcf\x7a\x71\x15\xbb\x5c\x5a\xa0\x05\x94\x0c\x8c\xef\xb9\xfb\xf0\xa2\xef\x6c\xd2\x28\xe5\x17\x19\xc2\xc4\xd8\xe9\x83\xd7\x3b\x6e\x28\xf6\xac\x3d\xa8\x8b\xbb\x6e\xcc\x6e\x22\xea\x99\xf3\xa7\x9a\x2b\x45\x8d\x8a\xe5\x4a\xae\x9c\x7c\x55\xd6\x26\x26\x44\x8b\x05\x41\xca\x82\x4f\xfb\xb0\xa9\x97\xaa\x89\x0c\x40\x8d\xb4\x8f\xbc\xd4\xb1\xc2\x99\xfd\x32\x06\x3f\x18\xab\xbb\x9b\x7d\x1c\x69\x4e\xa7\x8c\xf7\x4e\xfb\xd1\xc4\x7b\x7b\x1a\x80\x1d\xc7\x1b\xa1\xfe\x55\x74\xac\x03\x29\x2a\x30\x7f\x98\xa6\x68\xa2\x48\xd8\xb9\xc9\x45\xc7\xeb\xa9\x38\x5d\x96\x48\xee\x6d\xe1\x50\xba\xa8\x57\x6d\x1a\x98\x0d\xcf\x66\xb5\x70\x06\xc3\x82\xdf\xe5\x77\xdb\xe6\xbf\xff\xc4\x00\x22\x10\x01\x00\x02\x02\x02\x03\x00\x03\x01\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xf0\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x10\x32\xcf\xff\x00\x55\x6d\x07\xd7\x39\x55\x4c\x4f\x10\x53\x39\x7d\x17\x25\x21\xb4\x98\xf1\x0e\xb7\xde\x3e\x30\xd6\x2b\xcd\xeb\x1f\x75\x91\x1d\x35\x56\x4e\xce\x9c\x8a\x38\xb5\xaa\x29\xa9\xa2\xf0\x19\x37\xe0\xef\x5a\xc4\x09\x6c\x1f\x40\xf9\x13\xf7\x26\x8e\x52\xf0\x50\x51\xb9\x8b\xc0\xb0\x23\xe9\x2f\xda\xdc\x6f\x1d\x93\x08\x40\xa5\xdc\xf5\x94\xb2\x20\x4b\x48\xee\x3b\xc1\x3a\x59\x1a\x13\x5c\xfa\xe3\x1c\xd5\x99\x0a\x1c\x9a\xc2\xb0\x09\x24\xdd\x77\xee\x30\x2c\xeb\x99\x13\x50\x0e\x89\xdc\x34\x67\x1f\x94\xb8\xf6\x4e\xb2\x5e\x0d\x8c\x21\xf0\x0f\xb5\x8e\x6c\xa2\x01\x86\x9e\xd8\x24\xc4\x93\x28\xd0\xa3\x9a\x7f\x78\x4d\x28\xc6\x04\xd6\x21\xd1\x28\x94\x1c\xcf\xd1\x33\xcd\x63\x8b\x38\x94\xea\xce\x0a\x88\x2c\xde\xae\x12\x19\x8c\x3c\x38\x17\x61\xeb\x23\x79\x0d\x51\x5c\x40\xfa\xb8\x72\x01\xe3\x03\x0b\xee\x78\x79\x3c\x60\x5b\xb8\xe4\x38\xb7\xbd\x18\x20\x57\x3c\x3c\x4c\xa8\x62\xd5\xeb\x97\x00\x63\xc0\x83\xd1\xdd\xa8\x5b\xd7\xdc\x74\x8c\xc8\x4f\x0a\x9b\x89\x3f\xe7\x2b\xbc\x16\x68\x95\x23\x86\xce\x67\x22\x49\x35\xad\xc1\xf7\x5f\xe3\x2a\x6b\xe4\x21\x26\x44\xc1\xa1\x5e\x9c\xa6\x12\x75\x08\x32\xad\xfb\xe2\x54\x02\xdd\x3a\xc8\x0c\x7c\x9e\x25\xe5\x1b\x3e\x62\xb8\x63\x6a\x26\x6d\x04\x7e\x26\x74\x61\xae\x21\x26\xfb\xa2\x3b\x76\x99\xeb\x0a\xb8\x2d\x22\xad\x2e\x77\xfd\xcd\x46\x8c\xa9\x59\x47\x71\x36\x73\x18\x9b\x39\xd7\x56\x08\x63\x91\xb0\x4a\xe3\x17\x08\x72\x26\x98\xc1\x6b\xe0\x89\x88\x12\x98\x99\x5d\x87\x2e\xdc\x64\xf7\xad\x05\x6f\x6f\x36\xbf\x9c\x4b\x0e\x0c\xf6\xc4\x8f\xe8\xcf\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x89\x4a\x5d\xe3\xb4\xf3\x74\xe6\x50\xee\x11\x27\xec\x65\x8f\xfc\x21\x26\x5f\xff\xc4\x00\x23\x11\x01\x00\x02\x02\x02\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xf0\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x69\xa6\x38\x70\x4d\x4f\x85\x62\x78\xd6\x40\x85\xbf\x37\xff\x00\x7f\x98\x74\x08\x6d\x78\x9d\xa4\xd4\x9c\x71\x3f\x78\xb9\x0e\x8e\xdb\xda\xcd\xc9\xb8\x0f\x9c\x59\x47\x22\xce\x2b\x5b\x9e\xb9\xe6\xfc\x61\x66\x9d\x91\x11\x3a\x67\xc6\xb4\x78\xf3\x8b\x25\xfb\x1c\x04\xb8\xd8\x95\x60\xbf\x47\xcd\x6b\x13\xa0\x74\x44\x1a\x0a\xaa\x46\x4b\x32\x48\x69\xc7\x11\x1e\xa7\x7b\xf9\x91\xc1\x43\x4d\xf9\x9e\xfe\x71\xf1\x4b\x70\x7f\x7a\xc4\x00\xa0\xb2\x77\x32\xfe\x0f\x8f\x38\x0c\x26\x17\x9f\x39\x11\xc2\x33\x74\x22\x12\x6d\x99\xd1\xad\xae\x2d\x92\x28\x07\x6f\x07\x6b\xf2\xd7\x46\x18\x56\x89\x6d\x9e\xa5\xb8\xfd\x7a\xc1\x79\x02\x64\xb1\x31\xc8\xc1\x1d\x46\xfe\x63\x08\x5a\x57\x05\x5d\x84\xce\xef\x67\x67\xa3\xca\x0d\xd4\x24\xcc\x5d\xfa\xe9\x86\x9c\x2b\x91\x2e\xbb\xbc\x14\x35\x5d\x9a\x01\x2a\xbd\xc3\x9f\x9a\x9c\xa6\x10\x0c\x8b\x69\xb7\xd3\x06\xb7\xba\xee\x00\x9c\xd8\xd9\xd3\x14\x03\xef\xd3\x38\xdd\x42\xb2\x93\xc1\xc1\xd4\xee\x28\xfc\x61\xee\x70\x9e\xcf\x9c\xae\x44\xa4\x98\xb8\x5d\x9c\x4c\x4e\x98\xe7\x00\xd3\x9a\xde\xbe\xb0\xa2\x44\x04\x09\x69\x0b\x36\x6e\xe6\x65\x83\x58\x26\x9e\x64\xca\xdf\x2d\x57\x8f\xb9\x6f\x24\x6c\x04\xa2\x93\x84\xfd\xf8\xd4\x60\x9a\x8c\x38\x43\x14\x49\xe0\xc7\x60\x40\x02\x25\x0b\x71\xea\x12\x64\x24\xe6\xf0\xa4\x59\x61\x51\xc5\xf7\xf6\x79\x19\xc2\x03\x58\xc2\x81\x3b\x01\x38\xe4\x88\x3d\x44\x6f\x1b\x98\xc9\x92\x92\x7a\x3b\xf4\xd1\x8c\x8a\xc0\x2b\xf1\xee\xa7\x8f\xee\x18\xa2\x0d\x31\x76\x0c\x47\xf2\x69\x36\xe4\x0e\x88\x0d\x1d\x93\x5e\xa7\x7c\xc4\x39\x04\x91\x7f\xe7\x59\xb3\xe3\xf8\x61\x29\x23\x21\xdd\xf3\x84\x1a\x1c\x0a\x3f\x18\x88\x6d\x85\x3c\x9c\x56\x4a\xe9\xa3\x77\xd6\x10\x36\xe1\xfd\x64\xbf\xe8\xe7\xff\xc4\x00\x24\x11\x01\x01\x00\x02\x02\x02\x01\x04\x03\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x31\x00\x41\x51\x61\x71\x81\x91\xb1\xc1\xa1\xd1\xf1\xe1\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x10\xd7\xa7\x57\x3d\x84\x75\x41\x50\xae\x6b\xe7\x8e\x43\x43\xe5\x3b\xff\x00\x9f\x7e\x68\xbc\x16\x48\xbe\xe6\xaf\x67\x7d\x78\xe2\x89\x90\xa0\x53\x16\x3a\x80\x1b\x59\xc2\xdd\x06\x5b\x21\x0b\xa2\x02\xa1\x8c\xef\x1d\x6f\xcb\x98\x8a\x0b\x93\x8c\x3d\x9c\xb5\xdb\x0d\xda\xc2\x20\xe0\xc7\x03\x46\x8d\x02\xdc\x88\xef\x76\xbf\x4c\x57\x9e\xd8\x3c\xf5\x44\xbe\xa7\xfb\xc0\x0b\x48\x65\xf0\xfe\x19\x6c\x4c\x75\xc1\x70\xe0\x22\x42\x6e\x47\x53\xbf\x1d\xf8\x40\x99\xb1\x95\x73\x83\xcf\xdd\xc1\x98\x0e\x39\x17\xcc\x83\xa6\xbb\x9a\x67\xee\xf8\xe0\x44\x00\xeb\xfd\x73\x0a\x4d\xa9\x17\x2b\x69\xd7\xdf\x63\x21\x78\x88\xe4\x17\x1b\x2e\x3a\xa6\x97\xb3\x13\xbe\x04\x46\x2d\xe8\xf1\x83\x67\xae\xf1\xee\xa3\xb2\x0b\x64\xcf\xbf\xae\x2f\xc7\x1a\xb3\x19\x60\xe1\x73\x82\x4d\x1d\x84\xcf\x28\x89\x91\x03\x95\x14\xf8\x83\x77\xf7\xc8\x99\xea\x57\x33\x2e\x74\x10\xf8\x38\x62\x58\xe9\xeb\x52\x75\x8a\x43\xe3\x61\xc7\xce\xa2\x40\x58\xac\x2b\xe2\xc2\x98\xa9\x9a\x50\xbb\xca\xb0\x4c\x56\x9a\x8d\x77\x93\x4c\xa7\x10\x14\x6c\xec\xf6\x91\xd4\x4e\xf3\x31\xc6\x1d\xc2\xdd\xc2\x76\xa4\xea\x77\xae\xf8\xb7\xd2\x04\xc0\xa0\xa1\xe5\xb7\x5b\xc7\x7c\x70\x7f\x3e\x60\x54\xef\x48\xb9\xcd\x7d\xe6\x9e\xf5\xc3\x46\x51\x2b\xac\x1c\x86\x72\x4d\xfd\x08\x71\x1c\xed\x00\xe5\x62\xaa\xe7\xa3\xda\xa9\x3a\xe6\x63\xa2\xc9\x66\x6b\x0f\xe9\xf7\xcb\x80\x6b\x83\x80\x98\x3a\xb1\x82\x36\x9a\x67\x14\xa4\x25\x13\x2e\x58\xe0\xd0\xd6\x2f\x56\x50\xa2\xd3\xee\x1f\xd7\x03\x71\xcc\x66\x78\x1a\xec\xcc\x62\xf5\x71\xc9\x6f\x24\x75\x07\x66\x8c\x7e\x3e\xb7\x84\x88\xc3\x7c\xa9\x02\x47\x02\xb7\xe4\x9b\x78\x02\xe1\x11\x2f\x4a\xfe\x9d\x7d\x39\x8c\x7b\xef\x60\xb1\xbd\x4e\xf1\x1b\xa3\x7c\xa8\xa9\x24\x14\xab\x37\x8c\x46\x44\x42\xa6\x6b\xcb\xd4\xce\x3c\x75\x2b\xf9\x6b\xef\xc4\x0a\x28\x1e\xcc\x3a\xf1\xc5\x67\x46\x15\x59\x72\x97\x5c\x96\xe4\xb2\x56\x4f\x1c\x39\x56\x31\x97\x19\x9f\x8c\x71\xa9\xaf\xf9\xc3\x98\x20\xe7\xff\xc4\x00\x1f\x10\x01\x01\x01\x01\x01\x01\x00\x02\x03\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\xd1\x91\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\xca\x95\xf8\x23\xa1\xff\x00\xa4\x51\xaa\x3a\xfa\xba\x8a\x07\x12\x09\xa8\x42\x89\x66\x0b\x78\x98\x94\xbb\x7a\x81\x41\xf3\x68\x54\xa4\x3f\x3f\x99\xc1\xac\x14\x9f\xe5\xc9\xa2\x63\xd4\x20\x1b\x60\x03\x7e\x78\x61\xc5\x9d\xc9\x6c\xce\x48\x04\x84\xb7\x5f\x9a\x7d\x70\x8f\xbd\x3f\xd3\x67\x03\x79\x27\x33\x40\x32\x80\x81\x2e\x33\xcb\xb5\xa4\xcd\x43\x4a\x92\x3e\x10\x97\xe1\xaa\xf3\x20\x83\x66\x0b\x16\x9a\x80\x3d\xec\x0c\x91\xb3\x44\xe8\x5b\x0b\x8d\x1f\x15\xe0\x07\xc3\x51\x49\x28\x68\x37\x84\xfc\xfd\x79\x70\x08\x93\xb5\x3c\x31\x4b\xf5\x4c\xf5\xe7\x5a\x4a\x54\x8a\x27\xc4\x7e\x72\x15\xef\x43\x85\x70\x3f\x25\x2a\x81\x64\x77\x7f\xa5\x88\xd3\x25\xd2\x8a\x07\x81\xcf\xe8\x65\xa6\xd2\x16\x0a\x8e\x3f\x5f\x97\x84\xd5\x81\x42\x90\x9f\x1c\xac\x10\x3c\x87\x7a\x81\xe8\x2e\x58\x00\x97\xc1\xbb\x76\xf0\x0e\xf9\x41\x10\x80\x53\x24\x8d\xf8\x8f\x36\x34\x8d\x9c\x21\x6b\x6e\x7d\xde\x42\x2f\x58\x58\x0d\x08\x88\x44\x6b\xc5\x38\x44\x28\x0a\x56\xb5\x1d\xdb\x2a\xe0\x71\x40\xe6\xd7\x40\x8d\xc4\xa0\x02\xe2\x8a\xa0\xf9\x1b\x8f\x96\x33\x41\x0a\x26\xbc\x2a\xfb\x8e\x25\x08\xf0\xbf\xb3\xed\xca\x89\x8f\x41\xa8\x18\xda\x07\xd8\x1a\x88\xe6\x60\x11\x2f\xd3\x5b\x9f\xbd\xe6\x98\x60\x8c\xc5\x3e\x18\x03\x63\x3d\x87\x04\x50\x82\x8a\xc5\x70\x53\x01\x29\x9e\x1d\xec\xd3\x64\x68\xc0\x80\x91\x5f\xc0\xe0\x04\xab\x86\x18\x84\x04\x92\xfa\x1a\x8f\xa4\xe9\xbb\x42\xa6\xa8\xfe\xd0\x1a\x15\x21\x73\x6e\xd0\x53\x3c\x60\x00\x28\x86\x5a\xf3\x95\xfb\x8c\x82\xf8\x33\xce\x7e\xee\x61\xdf\x91\x84\x0f\x45\xf4\xbe\x5e\x97\xcc\x8b\x06\xca\xc1\x34\xa5\x65\xe9\x16\xd6\x05\xda\x00\xc4\x11\x49\x27\x0c\x3a\xaa\x84\x8a\x5a\x11\x70\x81\xf5\x84\xe5\x4c\x1d\x0d\x86\x1e\x12\x8b\x82\x3e\x1c\xe9\xe7\x22\x03\x5b\x0e\x59\x08\x31\x4e\x73\x89\x22\x5d\x2d\x66\xdf\xc7\x01\x35\x22\x85\x04\x7d\x13\x27\xe3\x88\x8b\x69\x72\x89\x62\x7e\xb8\xcf\x34\xdf\x40\x00\xa0\x28\x5f\x05\x38\x49\x00\x4b\xf4\xa5\xc5\xd5\x7f\x95\x7a\x26\x52\x46\x28\x4b\x69\x1b\xf5\x3f\x79\xdc\x04\x5a\x04\x8e\x7e\xb9\xad\x75\x05\x5f\xf6\xef\xff\xd9"; diff --git a/tests/operations/tests/Image.mjs b/tests/operations/tests/Image.mjs index ad3408dc..2ca363b8 100644 --- a/tests/operations/tests/Image.mjs +++ b/tests/operations/tests/Image.mjs @@ -9,6 +9,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; +import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../samples/Images.mjs"; TestRegister.addTests([ { @@ -21,7 +22,7 @@ TestRegister.addTests([ }, { name: "Render Image: raw gif", - input: "4749463839610f000f00b30b00424242ffe700ffef00ffce00000000ffb500ff9c00ffff94ffff10ffffc6ffffefffffff00000000000000000000000021ff0b4e45545343415045322e30030100000021f9040532000b002c000000000f000f0000045a7049096a9d785595ce19170670081204c2600013d09de899aed411108480e229eb9a38194f553998044854725028c6623a14b3727cea7453c0404090790944cdb6abe40e40943317170ca7cff082bb0528d80b2b568662d14f220021f904050a000b002c030009000900010000040530483165040021f904050a000b002c04000a000700010000040530ac3943040021f904050a000b002c040004000700010000040550042943040021f904050a000b002c030004000900020000040a3010228298575c5949040021f904050a000b002c03000400090002000004093008492921415e11010021f9040532000b002c040004000700010000040590904565040021f9040519000b002c030004000800020000040990acb0960c52d41b010021f9040519000b002c030004000900020000040930084264a0128b49220021f904050a000b002c04000400080002000004097005b1ea24b26211010021f904050a000b002c030004000900020000040a3010228298575c5949040021f904050a000b002c03000400090002000004093008492921415e11010021f9040532000b002c040004000700010000040590904565040021f9040519000b002c040003000700030000040a90904525bd54882b42040021f9040519000b002c030003000800020000040990acb0961492da19010021f9040519000b002c030003000900020000040af0044244982408aa71040021f9040519000b002c050003000700030000040a308445c5a098128277040021f904051e000b002c0400040008000200000409902cb1961432d41b010021f904050a000b002c04000a000700010000040590ac3949040021f904050a000b002c030009000900010000040590ac491789003b", + input: GIF_ANIMATED_HEX, expectedOutput: "", recipeConfig: [ { op: "From Hex", args: ["Space"] }, @@ -30,7 +31,7 @@ TestRegister.addTests([ }, { name: "Render Image: hex png", - input: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082", + input: PNG_HEX, expectedOutput: "", recipeConfig: [ { op: "Render Image", args: ["Hex"] } @@ -38,7 +39,7 @@ TestRegister.addTests([ }, { name: "Render Image: base64 jpg", - input: "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVFBQUFBQUFP/AABEIACAAIAMBEQACEQEDEQH/xAAbAAACAQUAAAAAAAAAAAAAAAAGBwkAAQIDCP/EAC4QAAIBAwIFAQcFAQAAAAAAAAECAwQFEQYSAAcIITFxIjJBQlJhwQkUFSORE//EABwBAAEFAQEBAAAAAAAAAAAAAAYAAgQFBwgDAf/EADARAAECBAQEBAYDAQAAAAAAAAECEQMEBSEABhIxQVFhoRMicZEUMnKBwdEVUrFC/9oADAMBAAIRAxEAPwCTPU+qDZ3jo6REnuUy71WQ4SJPG98d8Z7ADuT6EgSrlc/jiJaWAVHUHAPypG2pTXZ7AC6i4BDEi3kZETAMWKWQOW5PIfk8PYYDqif9y264XKrrZD5AnaGMeiIQMeuT9+M0jTJjHVOzK4iuiihP2SggN9Wo8ycESEaA0CGlI9AT7qfsw6YqmnFMwe33GropB4BnaaM+qOSP8wfvw6BM+CrVJTC4avqUtP3SsqDemk8iMJadYaPDSoegB90sfd/TBjpjU5u7yUdWiQ3GJd5EZ9iVPG9M98Z7EHuCR5yCdJolc/kSZaZATHSHt8qhtqS92exBukkAkggkdnpES4EWEXQbX3B5H8Hj7jEX/Vf1Xc3eTHUPqakm1HHTaZuGysskcNrp3V6YFoiju6FiyMhBAb5g3beBxT02VpmY/iJxST4mtSVeYuyCUp9BpD8nKuL4kzMSZp5hwQfKACLc7nv2bA5yz/UZ1fe9W2qyXOwUurDcqlKSCOywtR1gduynEkjRP385MQUZJOBwPZgyZLS8pEnJeaMMIDnXdLDqkBQ6WUSbAYnSFYiLiphRIYU9rWPe3cYy5m/qPatseqbrZLVp2k0q9tqWpJ0vkbVlWXXs3sxSLHH38ENKGGCDgjhZfyZLx5WHOTE0YgWHGiyWO11Ak9bJI2wp+sRERFQocPS1r3PYt3OC3pD6sObHO/n3Z6c32kk0xakasu8clrjT+pmWJY43UBgzFye5IxGx77cG6q0tTsufDTUMHxPESlPm4KISt+mk++nESUiTFQ8SEW06STbiLjv2fD16oemzTvO6WosGpoqilnt9VJNb7nQsq1FOshDEKWBBVht3KQQdo8FQRhs1WqpkrME1Dl2YqJ0lylSVEqSeFwDuNi4uHwZiVlqvIwlxN2FxuCLH/MKrp46NNBcnNe19xpbpcNRaqtka7P5IIgpI5lYCWONQM7gJE3kkZWRRghuPLMmdatXpFEGIhMOCs/8ALnUUnYknhYt1BNmxHkaXLSMXxASVDnwxr6jOjHQnN3Xdtu1XdblpzUt4YwN/GxrKlX/yiLGSRCp27URUMmQuTGpyzLl2Wc7VWhyS5eGhMSDDv5nGnUWYF7uS+lifmOwOPk9S5aejeIVFKjy44anS50zac5HVEVj00tVV1Nyqopbhcq5w086xkkA7QFVVBfCgfMckk54fArdTztX5SFMABIUCEpcBKQQpR4lyE7k8hbEn4SWpEjFWjdtzxOw7nHXWt9DQ6qRJ4isNwhG1JG911+lvwfhk8bpnLJ0LM0IRYJCJhAYE7Ef1VxZ9jdr2L4B6XVFSBKFXQe3UYTuqeVUFynhe8Wab93TKyQV9M0kM8KtjcI6iIh1DbVyFYZ2jPgcczR6RXqEtUGLLrAO/l1oLbHZSD0e4fg+DFM3LzI1IWPdj+8W0vyop7dUyy2izVD1s6CKW4VcktRUSICSqvUTMzlQSSFLYGTgcKBSa9XFJgwZdZHDyaEDrslAPc9cJU1Ly3mWse7n94cWiNCxaWR6iVlmuEq7WdfdRfpX8n44HHS+TMmw8swjGjELmFhiRskf1TxZ9zZ7WDYD6pVVT5CE2QO55nH//2Q==", + input: JPG_B64, expectedOutput: "", recipeConfig: [ { op: "Render Image", args: ["Base64"] } @@ -68,7 +69,7 @@ TestRegister.addTests([ }, { name: "Extract EXIF: meerkat jpeg", - input: "ffd8ffe12cd645786966000049492a000800000008000f01020004000000534f4e5910010200060000006e0000001a01050001000000740000001b010500010000007c0000002801030001000000020000003101020011000000840000003201020013000000960000006987040001000000aa000000300200004453432d483546000000010000004600000001000000506963746f6d696f20312e322e33312e3000323031303a30373a30342032333a33313a31330018009a82050001000000d00100009d82050001000000d80100002288030001000000030000002788030001000000c80000000090070004000000303232310390020013000000e00100000490020013000000f401000001920500010000000802000002920500010000001002000004920500010000001802000005920500010000002002000007920300010000000500000008920300010000000a0000000992030001000000100000000a920500010000002802000000a30700010000000300000001a30700010000000100000001a40300010000000000000002a40300010000000100000003a40300010000000100000006a40300010000000000000008a40300010000000000000009a4030001000000000000000aa40300010000000000000000000000010000007d000000250000000a000000323030383a30393a30312031333a32343a343600323030383a30393a30312031333a32343a34360043490d0048e801004b9a390040420f00030000000a0000000300000001000000480000000100000006000301030001000000060000001a010500010000007e0200001b010500010000008602000028010300010000000200000001020400010000008e0200000202040001000000402a00000000000048000000010000004800000001000000ffd8ffee000e41646f626500640000000001ffdb0084000604040405040605050609060506090b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010707070d0c0d18101018140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f00068bb671e5ec1500c895b5400786055e0605b5ea299129b545514c16ab82e2b6b80c516b82e295ca315b5c46050b9062825b0a2b8a82adf55b836ef70b133411b057900a852454571a357d11c62ebaa826f51b50f5af862032979ac5708eb0cad546da094f6ff8adbfe346c953ae8e43827c32feee5f47f47fa2b9e4890ee457c303b0b433dcc209a9c09b506d56d83701b9c3c2bc4be1bf59eb6ccb40ff00ddb1e9c8fec9f66cb211b15fe95c5cf5cf9ff3ff00a51412464b1d3e4f85812f68e7a83dd3018f107439316fe19feb6197fbd745752c442c8ed1988f10c3aa7b1ff23fe23950241a29d2eb4e3f44fe8ff728860797271490ee581d9ab92301541da4e24476fde63284bfb58d11a651d0fef546d556f84ed8217f49ff0035d16a3181c94ed4b346fbd67b71461fefc8bfaad7fe0732f04fbf91630f5c2bf8a1fee3fe3aff00ffd00a99c717af541b9c0abc75c8aaa0029810bc0c8b2545c50bc0df155d4c2ad8a57052b7551df0d2b46788756c095a2fe05069b9c6d0a2faa00d451538f35b0ad6be60d46c64f56df70769216dd1d7f95864a13312d5931c6628a672d85bf9821375e5f6105ea0adce8f25036dd5a13fb43db2e38c4b787fa4718669e2353f547f9fff0014904f1dca318a6a823692361423da9d8e5039b7e58472468f229dfe83b6d4b4d8a6d32491b51863a5cdb486a6523a98cff353f63f97098f1721bffba70f067384f873e5fce48dec4f1e5f687ed53a83e0464625cff1624d214daf097971ad7a65b128914472e2952a30128017dc017f685e3dae6021891d6a3bd7df264dfa87f9ceb357a6b143fad8ff00e23fe250a6637aa250804f1ad24a7ed53c464270120e9b248e4dcfd4b6deec5bd15aaf68db78b467dbfc9caa122369391a3d71c468ef044cc11d0c7b3c32a90ac3a6e3a8396bbac9a686685c7aa4a92b251892ae84c335363edfc460eb4f2e4984bb8fd2ff00ffd10a8338e2f5eaa06f8155141c0aa82806e70522da7b98106ec2be18045287975544601456b92114134abfa45a80f1d8f438d23896bdf4bd875c8af129b4b7527d9db088a0cd62add13bb6f87851c4b9ada50b5663538084095a7b169364b60f73688ba85b955fac06052e2dde9bfd93bc7fe5633c46b8a2767132659835f4cbf87f9934b24b6f4c7ab17ef21e95fda53e0c3f8fd9c8c4b660d40c9b7d331fc2a6e4b0fe188e6e5014a96beac12a4d1318e543c91d0d0823b82325747662636c95751d2bcc016df592b65aa00041aa28a249e0b3affc6f97090c9cfd32fe77f39c4962962de1ea8ff33fe252dbed3f54d16f84572a632778e4527830ecc8c3299c4c4d14ce10d4436e63fd8bae1c5f3996e1fd3bb3ff001f4a29ccf8c8077ff2ff00e0b2b323767fd37fc53ac198c7d19072ff004d14bae24961611dec7e993f62e00fddb7d236fbb2e05be3aa303eaf543f9fff0014a77514b1d07246e42a287b1c85efbb990d5e326add6cd2dbc8b3aa6e36643d194f5072709f0972270138d21af81b2bb5beb6158243fbc4f0af63f3c998806ba179ccf78f271ffa78fe3f9ebef204a0bb87e2b79802c3b0aff03954a025b1e6babd38006487d13ff62820cf6a76abdab1fb3dc1febff12caa3220d16ad26b27825b7d3fcd53d4214172b223036f7c940dd848b4ebe06bc72d98dafb975e2329f1c7e9c9eaff0039ffd2297d4d15c2a8a839c707af34179bf97a05df145b5ebde3123a62c6db617463a16dfdb07328b5392d4800b3127ae4e96d171431f004ee461000624a2e4e2c828294cac9dd0b68b415eb8d3605e84a76d8f7c04b1215912bf10c36c486a9f1d1bece56c805682f27b0ba5b9b37f4e551bf7523c1877192848c4d844f1898a298b2daea8a6eb4c516f7e809b8b0ea187ed345fccbfcd1e4e5112de3f57f35d66a34f28ef7b8fa727fbd9a56d12ca098978cabbbc1fc57c46439b769b5b67827e99a902c69e18097654af00b633d273f0d36f0afbfb6188079b0cbc5c3e9e69b58799ededa3fd0faec667d2a43488b1a98fc1a193b7fa87fd8e64c0edc32dc3a59e7a96ffbb9ff003bf9dfd66f56f2ec9a7c02f6ca517fa44dbc7709bb28fe5900e9feb65797098efce2db908ce3f9b947fb34ae2d45d216b690896ce5eb1b74affc6ad98129cb1ec3787f37fe25d4f1981a28196d2e2de3792dd45d5883592d9b7741f2ff008d866463cf190f2652200b8ef1fe6495f4e8c5f2b0d3642cc054db48431fa2b43970c065f4b6e1cf21f41ff3565f42f1c452e6231edc655208f87c457ba9f8b24227e929cf9f8fea1fd197e3fa29758cb2c32358330742498586ea6bd40f66eb9127ab6766e61be19fd32fa575c46622548ac4db53f81cae71120e36af48714abf84fd28195163a249fbcb673553dc1fe0c3230279170f96c5ffd32211af3dfa8e99c800f5d2e6888622d257af86202248dfabd08276c34d56a72bf13c7be00caad6a51fedf6e986d055a092dc13cba0ed8c9785106970bfbad80db2ba21452d96d98a56b4230025b5aa3fa7d6a063694c6f345d5ec638de45564963128f498390a7beddbdd79603ce8b8b1d46394b86f740a0661d7e9c69c85f50053c31a4b71318d8491b157520a3a9a104770460ded4ee374da2b9b3d68ac53b8b5d5c1fdcdcfd98e66f06a7d893fcafb2f969a9794ffdd3aad568b6b1cbfdc7fc750d3412099ad2ed3eada826df17c2b27f46c8f0dedca4d5a5d7981e0c9fe99012218e42ae0ab0eaa7ae45dd8208b0a8ab585926412c2dd636dc7d1844e8b8f9f4b0ca2a415749d4356d11dae347737362dfef4e9b2fc5f0f7a03d73371e5f8879fd4693260363d51466a0ba6ea369fa53455e11c86975647a2b81f677de371fb20fc2d9467c11ab8fd2d5927e20bfe2ff0075ff001e4aa1b978caba315a6c8e36653dc11fad7355931189b0e3d90a5796915c49eb4245adef50cbb4521f114fb0d96e0d4d6c51f615f6be63ba15b0d52ac07c244c390dfc6bff001219b2f16446c6dcec19f1cbd3947f9e965d5b34523440fc517ef2071dd0ee3fe072a27ab899f19c73a1d3e9ff007a8c82fe09d394e9bb0e32f1e95ff3df2b96c5d80d7f890e198b43dcdb888d0fef20907c2c3bff004619331121b3af9c1fffd42c58b91661d00ce40bd792dc3ca36af6ee31b6063688e72ccb55d80c06458d529143ea02c7a75c2cc2a3aab10577f1f0c1c94058ab116a30d8f7c46e83b23ade35896887639191400a8cacc877c8b30a203a8a75070aa3f4ed52e2d53d0957eb1624d4c0cc54a31fda89c7c51bff00abf0b7ed61e2da8ef171751a5865e7b4bf9c8b92c6ceea269e09c705f89e42a15d3dae117fe4f47f07f938401f0fc7d7ff0014e18cb9706d3f547f9c965eda5c5b4aa93af10e2a8e0d51c78ab0d98602087658b2c662e26d41c88854ee0e45b691a34b6f85e19e19f90078a3153bef41cc283f41c8d8e4e29d6e38cb865e93fd24c56f62bc45d375c0d132505a5f91f1c7e01ff9e2ff0088e59c40ed2e7d24e2eab42320e28295d40d677315b6b508709436f74a6a92276f887da4cb7ad486ff00ee9d760d5cf09e13c9d7bf50a0f4a06891bf95f9a9f913956402f61c2ee716632162424a115bc4afc92565237029be40d8dd8fe66f6215923892ebeb30bac170e384f4da3997f9655fd4dfb39918b383cdd4e6c70e2e286c7f9a83d4adbd190cc8b589fe223afd1b771fcd94e5c5c27fa25c59c6f7412ba940e87d489ba8e841fe0d987970b8c546ea28a5840947a908d9251f6e33e1ff0036fd9c8e2cc6068b13f620156e2df8a337a8aa795b4c375207da4dfecffaa73620c6412096c4c2d66f5177b69c7c60ff0029fe287235628f36fd2e6109fa85c25f57e3fa28d7b365857837c2fd509a8f620e4632a2edf51a08ff0001ff0035ffd501c82ab713b1ed9c7bd700d23a1a03d09ef8548d959d8a6c83e123a60456ca45a80f3ef86d695a368d14721f6b011690e9e307651d7a1c4162559632b1835ebd6b903cd905601ca003607be0b56dd0a05e7dc540ee7082c429cce480476e83109a55b396ecdcc5f530df5a0691fa7f68d7b7cb271049a1cd84c4787d5f4b38b2f2dffa2a8d5648ad965359b4f51ea2127a3a8a8f424f1e0dc73698b424c7d66bfa2e8252109de226946ebf2f744a97fd2ce905392c7c14b807fca27f8627b3203f88b991ed29d7d22d45fc8b1c11b369fa899108afa73a0e276ee41ff8d72acbd9408da5c5fd644b5b1c9b64884a6edae34e7f42e151a3ea6094196023a555beda7cd4e6bce1962347fd2ffc4b18e98fd5825fe6a67a5de6837b6bfa2ef58c56b21ac704edcc46c7f6ade71dbfe2b7cb61c321c3f8ff00364e36a32196d9070cd29d56c2ff00406fab4dfe93a6b9adb5d2f415f7ec7db25663b49c3b3050b6d4f4e423eb711656feee688f1a9f0607a1cb31e3c52e6ccea67de8c924f2f4a2b5b841dca80f8cb4986f9ca29fcc4b9a94b71e5d4b79214be75256b1acd191461b8de9b6f968d3438684b883664d5f10dc6ec6a42f0c9eb440153f6d3f64d7e5d8e6b251e13479380762afc9197d6b7358dbeda36e47f92c3f8e533c36a47721cd54996dbb7f7b036e36dfa7ed2e5512607763cb928ac2970af1c3fb557488fda560370bfccad994725ee9ab1411de5fb8b1bbb57d3ef1bd2b886a6da6f14fe53fea1ff85ccb842131bed273f4ba89c8708dcc5fffd62e2d1a76a8ce429ec02ee49455a6e7f562c51317062431fb382904a9ba2b0a8dab884ba4456403baee298dad2a293c4002a460b4220ab98771be42d2136d2b4bb1d42d1520d4238b56a9a595d8f4a3735dbd397752dfe4b71cb23107aeee364cb281dc7a3f9d14bf55d3356d3ee8c5a84124131fe71b37faac3e161feae40dc79b7639c642e25423579691c6a5a47215146e6a76184032200644888b2cdb4893cb3e54b6336af3ac7a83292ce7720569c540cdfe9b1471c7fa4e8b5396594ff45bb9f32f9635711a5b5d24f2ca0b2321dc53dbe9e99394c35460428db5f69d0235c6a13d225709f113c4ef415fa72066032e1279215ff343c9b15d0b54ba018311c56a7a1e950388c94667a20e33d54dfcc9a2ea704b1c4ad3d93539b0a7250687e1af7195e694251a2d98e3381b0a175a4e8f0dcc56d697ea7eb2bce2827d89a0dc123fa66a351a7e11c4370e59d4898ac91e256867d774b431bc5f59b13b3c47f7d111f8f1fa728c7a9ff383893d2c25fddcbfcc9b4961e57d4987a55d3e67ad6d64de073edfcb43fca73263c24d8d9d7f00068ffa54a2f3cb1e63d297d78e332c0bb928dce9feab0fb43fd60b96891fe20c8e107789ff0034a845e608e54f4eeada398aecd55e2e3e63194011e96b333c8b7789672c6b35922a8414922049047c8ee331e62fd32148901561296ac0fce22551beff00f6c7fc3653026268b4722b9f9831bb0f4e47f8a2957ec3fba9fd6b872e1a163e9654a6ea2570ea7d3b91b823e10c7dbf95b31b80c7972470f5085914cae493e8dd21fb7f64337f95fcad97e3c888488363693fffd7284042904743b67216f6055e40c2441d88d8e218ae50cac5fa8aef816955a930544aa9c15482a8d1180508e5e38a04ada32102aa37187609ab56866924251bbe0a5269d2451d0ab50f8644858c933b1f366b16500b39c26a3a69eb65783d4403fc83f6e3ff00627271c846c7d43fa4d13d3449b1e897f3a299e95a6e89ab5e473e8ef369d78ac19ac660668bad498e61461feac9993a7803306361c6cf39c62632a90fe7241f9afe5ed5db50bbbc1207b168d15054171c7ed514d396fbe6ca397864e098dc764abf2a3c9d2b6a4758b90b15880fc5c218d49216a029a7876cbf2512d512427df985a59d574afaae92448e18cad0024315535fc40ca274241b604d178f693e5dbd97524b60a23bb576352bc7663521c9fe5f0cb6796222c63024bd67c9fe49d52c619d6e6506adeb471a7d9236d8fcf304dccb90642229865d45a8cde7d8da69c036d31892db91a8404f6e9b29cb8802041602746de8769eb0b9e16b7c2dfda5ad01f0233512d0891e8ce5adc331eb8ee9a4a616b4922bf9ad660c391e04a3123ba9ecdf4e2745388da71feacdc0cd2c67e9bf8acb0bbbdb3547d36f44b048392db5c1ad40ea0378ff00ac32a8ea278feb1ff12d3b859a845e5ed5ff00777d6a6c2fcf475f86bee0fd96ccd8668cb741024c6afbcbdaad8b97b63f5c8177e49b4aa3dd7bfd197736a31212f59a3950f5046cebd0823bd33172e3bf7b1e6bad2fa3b626daf944ba7cc6aebfc8dfefc43dbdf23872f0ec79318cab6289d5343b9b51ea467eb36cc392b8a160a7715a75f9e5d9f4a63b8e4db49638499784a68c05165ea76ecd4ea3308e3ea10637ef7fffd00170010be9ee0e723c9eb22e347401b623a60660351875aa1dc1ef85079a2ad8c48c4d7e2191218485a8dc5ecccc5a9551d3084c634d5bcfcfed0fa723216ced13c68448ad80ecc4eedba31fde570246cac9cb6246d879312ca3f2fa48135b01a42924a0aa252a0fb9f0cced1c85f9b83ac04c7c93ed6344b5d7219ac6edaa049cd68487001ec46640209ddc3a23931df37dfcba2e976b63a6dba3adb0e1c2bc78af124763fb54cc939a31e6d51c464c2f43f336a53eb0d2cf115423821614353ef41b7f93951cd122f6e26df048dba3255f2ce9d7f787519a2add2303c81f85c0dc0651e1e3944e61946c724fadeede3bc48cafc007150bb8dbc680e571cbea4ca1b24b3f9322bbf3bbdcc6844660f57d4509512b7c14a12a5bc59466466c91aabab7127b452fd634ebbd22e85beab6efe937f73728483c7fc863f6a9fc8f98128189d9c3be13b8b0b224bdf4fd4b5956eedc9a54ecc3d88f1c0353d241bce28917095fbfea529ae450c732342dd40229f10e85586c1b2c12891b38e491cdd1eb37889c2455bc807db8651b8a7707ae60cf07866e3c981994c6c358b69a9159cc6294fd9b4b92684ffc572f6fa72dc7a9e859c660a8ea02c669e97b0345743666145947fc692ae6613637410121b8b6e1c918f38abf04bdb7f1fe5afbe62ce37b8e6d442eb2d4e7b54f459d82447f77de9e2847f2f8618e690aa2d90c9b51576161a9ab4d69fbaba5152a07eedfdbd9b2e204b97a65fcd6c23a87ffd12f0a562a035e39c8757aeb6a542c10d695c348b6d832fc34f6c78934ac901552f5de9915e2535914c6477aef849400a91491315420815f888eb4ef4c36106d381a3d8ddd4e9b732301d6299417fba3f8bfe49e08c78b93892d54a1b4e3b7f3a2b2f346d52de225a0631af5953e351f32bf67fd971c07198f30db8f538e7c8a0e12c45396d95f15f26eaa4c749d4e7d2af16ea2557e26bc4fdd9762cbc06dab2631314f44b4d42df51b48f50b7014c83e21d3891d41ccbe3bddc094083494eb1a569b79306912aeca049434a657395ac7648c794b4622408b346e2abca4228a2bd57e7951f26de328bd3f4bb1d3c3bc4feacb2ecd23b135c78875606dafaf14708c3f7c0d100ee3da995f8b4764f0a1efa695e213dbb8498305a3350353b577197e5c232e3162da2f18954f92c4f306abf57fab6a56c97f675afa7200e07cabd3fd8f1cc38e2cb8fe926bf9b3fde47fe291934f8663d12dfba4ba3f2f699342752d26692c08204a95f563527f6658dbe30bff000b96649ed790708ff54c7eb87f9dfc5175671189db6217ae9f21602ed63319eae94643ee2bb8ff0054e4b0608cb712e28ff3a2dd1c808a9734bf5bd12d804934d2a6702ac8a405703b7f92dfcb99392a3b5d844b4f62c31a78d665e480abf75e8790fd4c330f361af547938262985a6b933c4b697b0a5e47fb21fe1627fc87fd893fe27870e6de8b38e5bd8ae7b64995a5b0769507f796f200b711fb11d1d7dd7334c2d35dc95dc43ccf25346028e00f0fe65ff9a7318e3218108753756ee67b298c5311f1f1a71703c474e43be5f872744d90ff00ffd22949080c3af13be722367ae905d72dc91590d08eb838b7481b2a890b052db62854329008ec702045608d1d7929dfc3254b6b9762283e9c8952adf0ad1f951874a1debed95d8b5e6c8f40f3079c22751691cf7c8365596269683c0494e43fe0f2cf1a71ebfe99c3cfa7c279d459645656bac0ff0073fe5b16329eb7892c7137cfe1657ff8247c075388fd437fe8ff00c75c1390e3fa27c412db8fcbad3e798a691ae461bbdbdd71661f278cfeb4c94714642e12ff004cdd0d791f5453ef2ef95752d1ada5b6b9659a3958346f112ca187c86d5cc9c3c5f498b4cf52272ba416a86381dc90102ee4fbf8644c69b6d8ab6adb33716925249e26953bf615ca886c545d423112b4dfb9077552286bf2e995982da166bf86e61758e391e36d8c82818d7dc6f8c61ba540daac5a618880de838969522aadef4d8e6c0c4986db3839cf522d0713233016f3c91b9e9139afdc0f5ff639872cd387316e1d425cb6475a4fae5acc2e2dca995450f6e4bdd595b6653e193c7aa89626241468371707d4d1cfd4f50a1693469cd60980ea6d98fd9ff8c5957e5f1c8f1633c12fe83120a5f1f9834c9a530ea103e9d76878bb50940dfe52f55c264794c710fe747eaff4a88e523af0a9eaba33381776a55b97fbb633ca3907b91d1b2fc5115e93c516331691dcc120e42542adfb5dc1fa47ed663e6d3f58b44a2bac2e6396758ae2e3eaf2f486edba57b2c8474ff5ff00e0b2cd366fe19158c935b9b69c03fa4613b7d9bf828c0ffad4fe399b38ed6dc3cd2abbb392302746aa56a9731ee0f71c8663ca1ba4c5ffd32755e124849fa33912f5cac5a2921a5006c48a505a721a0a537182f7485cfc8046a6ddf0a2ddb03b1a5705aaba384fb5be0a410985b798b5bb4b7582d2e7d0856b4e11c61b73ddf8f33f7e3640e7b34cb4f091b22cfc5d3ebfabcfbcda8dc313d47aac07dc0819031059470407f084b26b8f5d88798c87fcb62dface4a806e1103905f193171646e0c0ecca6847d2322931bd8bd0ff2dbcc37d717eb612cd2cecc6bcd8d4220ebbf535f7ccbd21919d5ecea35da611a94470a2bf3157d1b3b8643f0d682869bb6cb5cccc9005c7849e7d149a847468e345e43e295b76f6a023318c29bc1b577b5b8b93598991d507c4c766af811c57e8c81d99029859da2470807a7ed329345246c061ab412a66ee4b6be590bfa90d402ae05180a6cc1b3261c9a642d177ba368fa9ca52cd974fd40d196d6427eaf2d77fddb9de36ff272a911c5c279b8797466b8a3c921b97d5f4ab936f7b1392bfeea9766a78a3f47198d974913b869c59ce33ea1c4a91dd5bdf0e319f897e2e1bacaa4771dff00d92e5021c06c7376909e0cb1f3fe6a2e592d75702db593e8dd20e36fabd29d3a2dc01d47fc59993098c9b1da4eb32e3df7ff004c9330d6fcb77a501e15dd93ed432af8ff002b03954b1989b0784b8a41814e6daeb40d6e2e4b27e8fd400fde44c098be629ba8ff0085ff002732239a276973671225e452fd53cb92467948b40c2825520a381d0861f0b7fc4b232d303b844b12034cbbb9d32f543c9208a9c680fdc190ecc3dd72b8ca78f9221e93bb52df0b6bb926b623eaf29acb6bd0a13e0a7f61bc32dc7949e6ccc8479727ffd42466596d8bd7e2e8df46721d5eba97aa30b4471b9184f34c5561642943b138a0af662001db012a22d33fb7d38a533f2fdb2b34b2cd6d6d7aa365b7b8b892061fe50f4fed035ee725c60731c5f371b513aea61fe6f1a71cae789f43cb163c47ed27ab747fe4e93ff0b9299321b461feedc784a27fcacbfdc25afe62bcb79bd2163656cde1f5440dff000e09ca08efdbfd8b923003d652ff00396bf9a35fe4bc2e5235ff008ae1857f5263c16bf968777db2566f32f98aa07d79b7ff00253fe69c8f004fe5b1f77decaff2e757bfbad6592ee6965a46c56a144751eeaa0d733b45000934e1eb30c6205045f9cafa2b995a009536afeac887a1a8201269db2fc991c68c5848bfe6ecc92701c78d1791dc6d53405572156cea940f195ffd22a217350fc89e247ecd6871e101368998358462e2da43242c49915aad4db6d872f96428f4643cd2c9aebeb91cb2ccb20263aa46e18a923607c48a8cb4028e4c87cb7ac5f32c96b2ba7aa2929f5539ab03e15048a6473eabc281911c510e1ea6040b89a4d751924be8cc3711413c1d9412a41f14e5f60ffaa730476c69e7d785c137d77627a97966e50fa96cacea0d53f9d7e4cb9911c98f27d2449a8c1029aadf5b1f4afd1a4886deb05fde01efd9f2271516633486c7746c52fd66c1a2b722ff004f5a911ad4c90b1ebc01fb23c626ff0063970163f9cbc625ee49eef4d92255bcb462d086a2cab50c8e3f65875561fc8d9464c25a658eb70af61e63d4237da758e66fb6928e56d37b3a7ec31fe75c8c32ca277dd9433743f8feb265eb68baa4861914e95a89a73b5987285891d53b80ddb8ff00c0e665821b051f2280bfd2af2cc832a7c1d119bf79130f05906e3e59038fb9062fffd5298ade308c0f47e99c853d7deeb232d11680f4fd9c20a3aae34014d69e3812ab2042a38b57db10a5750f0e95c4a86a2241a9aedd30154645a85e29f858b01b8e5bfe3d72424438f934b8e7cc27565e74b95845bddc1f588c76722407db8ccb22fddc72d19cd6ee29ecf03e891822d6ff00c85a811f5bb0fa9b9fdb843c06bff3ccc917fc2e3c58cf31c3f8fe8a383550e47c46e4f2ef956715b2d66487c05c46b2affc1c457f15c1e144f2923f94271fae09df923ca93d96b1f5c8f5282784a32708096e60eff102071cbf4f88c4d92c33eb61963406e87d7ee4df6b7a9dbc287d08e2559ae29f0a12df0af4dcb53b6195924f46036018bc1e947f0dada9bb1521e595b82b536341b9f1ed938ee105d6f3d9bcbe92c724570e2bc1a80141debf65b89c05907094c7231a290013c36a96dff6bb7f2fd9c1114c8a5a4348222b2845b49c9f8b66e3bd003ff356106b74d222caf9d6e65588fab216288d21a00ecdc885eff463216082d792161447986559de2bc468d9588631b10cbf30763f76687269803c817591d4989a946331fecbfd3232defeee4606caf3d4ff0021b67fb8f5ff0062d950c1889e5c1272e12d364e44e392bcda9dd8a8bcb24bb03af052b27bf4cccc67247612e21fed9ff14c3369384583c4a1696da2debb5e69d34963729f6d88200f6778f7ff00918999d1c86bd40c3fdcb8421d42b5cc77f67ceee789a51320569e3e32dbcc0741281f0b7b306f5172d80eb7c4194a5e4c7f51b4b19a92db37a6d27dbb77af243e1520735fe56fb5fcd95ce01c79c41e497ccee10417aac427f7721ddd076a1fda4f6ca2371361ab96c51b67adea56038349f58b390746f8c11f4fdafa7e25ccd8c848586e8e521fffd62884b00a877e3df390b7ad28a9e389944a3ed0db05b1050cebc89a8a03bd30d36872ac4803826bdc61e881b96c5d56ab4a60b4f0af8837527aef8690aa0480120ed8d215adda22a796c722420a84f2c319a861bf8ed8d81cd953a34ba9d87d5e29253ff152337fc441c3c24f204fb831240e65eb3e44d256d34c7bd76324cb1105e5478e58f9f543cf8d77f6cc9d348efb174d9c478f9525f7d6732f976ee92f17bab9ac9213bf053422bff054cbe5f4a0736377b259da5cada24fe90e20c4c0f21e3e0c37e9804acec9aea837983b299191258fe2695457e0ad2878ff001c8d9b6c0104ecb13b7350a82a5665342caec7c7a32ef846ccb9a9492a8778e451342e94691762c79029cbb7c4a7638ad2cbb8ace082194d4490721242e7b720439f7a7ed64cb00776437d7e97f1aa6a9a726a36ea8384ab486f107f9130da4ff55f30f2cc035270f369f6bb07fa29249e598ee18c9a0de0b96039369f703d0bc51fea9f864f9a6552c008db775f2c5bff00c520e2f31eafa74a60b842eabb3c1382187b03f687df94c606276ff64c0e4947605151eb1e5bba9565134da56a03a4a3fe6aaf165f67ccd8e7007d3fe95946609df628a8f53b9b776749cd9cd5df50b65e56b283d3eb101aa0aff32e1c79632e5b16e9c48ebfe95ab8d634a7262d72c56091a9c752d3be28181fda684d7fe132ebb69240e63fd2b9bcb6973099f4eba4bdb6fd9303026be0637e9f21f1644e2894880291cf61716f234662a57edc26b1b57c78b6d5f96446120d863c0fffd72bb7bb8c2947143fcd9c8bd690b595cb32ab6c771869545e59540461d3a1c0cc056440103f51df15537953951571092c8348d0f4dbbb54b9bef3058e9cadfee86124b381ef1a014ff82cb630891bce31ff00672713267903421297fb94c7ea5f97168b59757d435393fdf76b6eb6ea7fd94d5387f723ae49fc383fdd3571ea0f28c61fd62a6baf7942d36b0f2d89abd24d42e6498ffc8b4e2983c487480ff929233ff629f0731faa75fd48b67cf5aac3fef058e9b62bdbd0b38f97fc13f3c31d4e41b0e187f52293a289faa5397f9ca727e6079e652ab1eaf325762b12c7181ff02ab88cf94ff14becfd4a745840e5f6c9ea3e5b69e4f2a7d6ee6633cf70cccf3b906bc7c4edcb7ea7326aa2eb881c7405283d92cba1c35dd7d3e649ef5deb8c86ca0bcf6e2d25861904919592688fc40024346d5500f8d3e1a656090d9cd27fac178123a17676e0dfcc40fb40d295a83837b6ca58f44f459872474f816848508dc69f4e125900b3d38feacb2280aca38bc6a2a4bc4db487af20c8324189288b9b759ccb0b9502f362e76a2a1aa9f1e5f695b2d1dcd375bb5797b736b398623fbb00710f1923dfe25cc0d4c883cb670f31225610d77aca5e8482ea088fa7bc722b706047f2b7507e9ca4e527c9878c09f50130aa35a8a58843a9c5fa4add471569c52e14760b3a54b7fcf446c98ca0f369998f4e5fd2ff008a42cda0797ef559b4dd4e3b77ff00963bff00dd9f92c9f61bfe17260c4f56a301d364ae4b2d6b4c2c9196109eaa8c2585bfe049189882c4714792eb6d5ecf68ee53ead216f88b7c56ec0f8803927cf271321cfd413e25f30ad25898e6375a44cd693b529c24aa31f0571f0b8ff25f2c8cef92f0750ad1f9df5081bea7afdaaca8363214e54ff5a33423fd68993fd5cb626f932190f22fffd0202c01a5363b31ce469ebc96a3e71cdc0b547ec9f6c2b4bf9c84988ee3b1380326e19f8068a4fa0e14014be3a7daa54e21495552b20ad28463485c5011b1a634ad53e120b570a0af88803e2dc74c8a944699a7cf7faa5b59db426e249dc208aa541a9fda23a28cb31c788d535e59f0c49ba7d037da7c7a7683058a11c2da3e145145d86f41e199d945507498e5c52252fbb2b35988536e7c13e82301dd9311f37c11c002ab16450637047206bdb6f7c8c8328961822416deaf32ace4142bd449fb4483e206544d378dd4657412b492025437114eabca95217bd695c883bb3ad94212e6628d192dc02ab93b80c6aae69ec007cb22c24173098db321955e783d38a1604072180ea3fcae996823ab510ad3dfc6b04ad13bc8b6af49850b3287028d41fb072bca080e26a06d610a9a8595d2543c5282770ca09feb98c780f30e089169ac2cdf711d3de26ff8d4e446289e492a0fa502a78ca69e1227f4c4e15010ff00a32ee2de250c3c636e3f86d80e028e052992e07c332bf03fefc40e3fe1860e0218f0a1238d2266312aa06356542c8a4fbaee9f864b88a88ab4f7114f088ee237650280ecf4f91d9a996c667b948b7fffd18fc75a7c5fecbe59c93d7aa20844c37e408fbbefc507c95a416d5055be2f0c4a624f550a45c8890d3c0e1648880807a557b62c1104afa678af6d8ed80207343815277a7df926c5d185a354febc894351d431ee3241059dfe4f45a51f372cb773b2ddc68c2c6db8b524908ebc94151c57fdf85732f46071dff17f0bafed132e0a1c9e95a9cba8fd6292c27d025b9355761f7e33bb70b1d56c83d23d4faaabce7fd3787148c7f396346afd9d874df2c8f2f344987f9a05c7a8c01a283f19a0ddc529d77151ff000dc7212671a61b1862f2a82160561ea3ee433545280f4ca0b921467a1b98bd71c4ab398b86e58d771b7d38c52796ca363ea1924e1cc382c108a54c7c450ffc178e4c31921a90064170c1a4480052d5f8cf36f4cb765d8ed96061ee4cbcb5f5b8e56fabf099b98f5c27c0dcf71f75373fb3961e4d19792cf30c9a2bcc56ea2b78a7aeef6e794bfecb81ff00892e6264e1bf375f28c4f321049a5da1b532dbeb4aae378ed9e19cb1f62e102ae44c635b90c0c63d0a8c6fab2d0346ce3b303f0ffc3d300df95b59b1e68c8a4d5006ac558ff6e94a7d3434c27887716dc7c5e6a914b72410d0c8a3c432b2fe2572c893dc8bef0a5726d7fdd8233e21a80ffc29c96dd507c902c34863d4a37f9153fc307a18bfffd9ffdb0084000a07070708070a08080a0f0a080a0f120d0a0a0d1214101012101014110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010b0c0c15131522181822140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f004146684bbe5c06452bc6056c0c50b80c8a57818ab6062b6dd3156c0c55b03155d4c55b51814ba9be155e6293d2694213129e2ce06c09fe6c68d5a3885d2c5dfc29deb8292568215846e6a8768643ff00269ffe65be4a9c412f0a5c27fba97f77fd0fe836cc8bf3f0c0e5a934b1d7738ada91bc881e23738d2daf8ee4484c2c281bec13d2a7f65bfc97c9445ecd393bff00e567f510ca849faa3fc2412d6ec7a83fb51e2458759286fc1fe7609ffbcfc7f1b92674a0762863340c3aa7b1ff008aff00e2190068d15c3a8e1f4cbe8ff70aa41ad5b67ea4d7635c3c3d1cd94481b7ef71285cc48aa641d8fef074d9be16db046fe92eb32c40e4d4352adbd6587a8fe78ffaa57fe032fc72ff004b2447d51fe963ff00a67ff1c7ffd0457340ef970eb81578c0ab80c0ab86055c3155c3156e98ab862adede38ab46441df156beb318c554daf003b0c56d522d4aead9bd487becf19fb2c3f95c64a32312c2711214514d6f16a89eb6947d2b95159b4e7a03eef6edfb6bfe7f065a6025bc7fd2348c9286d2f547fd512e916504a49f2743b1f91f039486d9c44e347e9923ff0047c5776b1c966ced791a52685f73211f69a223f6e9feebfe4c3c3c5cb9ff00bbfc7f31c6c790e33c124bcdbfc2187c43bd3b7b30c8872b8c5d289878bd695c9852556b45dc6280ba51f5a80b2ff7f11049effeb57fcac91ef70f3e2bd87fc92ffaa5ff0010a2643723d40b495451e9de9fcc3fcff932128821d7ca467bff0013514c22146ab5b9fa4a1f6ff2321135b16dc1a830d8fd0aae1594a1a346e080c3a6fdd4e58ec6586392363f892f572b4249565262929d7dbfe365c1d69d2d989fe6bfffd1457340ef978c0abc0c0ab87be34869a58d46e7052549ef1548a0ae48045aff00ad1a03c7ae0a45b4d70fe18136b4bccdd30808325a04c4f5c348b6cc4e16a4ee7010a0a609676e2d9a78145d4141eb72056685a9f17d83bc5fe5e19436b8b8f29caebe99ff00d2bc88568b80e71fc7174af704fecb8ff8dbec3e441678f289edf4cff98b5aa47f0c5bdb883232c8a4aba9aab29a107c4361bae4822d36fad5a6a748b5122def76115fa8f85fc16e57fe667fc432d044f9fa66e3984a1bc7d51fe6212e2daef4fb8114ea518eeac0fc2d4e8f1b8ffaeb2a9031e699463963b372b7d658c93370b8ff00968029c8f8caabfb5ff167fc1e44c8dd97084cc7d33fe1ff004f042caef1304b95e04fd9980f81beef87fe0726da3318fd5eb87faa2d99244a0aab545450f6c8db903342eadd11785c4aabb8d994f420f553928ca8b6ca2242946e2b6d38ba83789b665f9fec9ff5b2446ffd175392e12e2ff959f8ff006d5d3c6bb4f1ef0c82ac3b0aff005c818dec573e202a71feee6a00b43d3e2818fd9ee0ff00cd5ff13c84655b161833cb19dbe95b728a260ea47a374b40dd83ad3fe36e192977ff0035753465c51fa727fbb7ffd204d76a18003ae681df16feb0fd00df145bbd49c9a74c516e226e1b9dfdb145ad6868072249c349b57444e209ed8589577a328a64156fc34df1a6417292bdb638da297aad7718db1a753e2a374c832017a4d25b4cb3db3709146e7a823f9597f6972519107644a02428a2888af019ac944376a0996d3a861fb4d07f3a7f3c1933112de3f57f31c3cb888def7fe0cbff0055507c448098c51c6ed17fc6d1ff0032e41b316a2cf0cbd3916024d3c305b96ab1884c9fbdfb34dbc2bfe57b6102d8ceeb645dbeab1409fa3f534f56c1cfeec13529e0d6f2fecffc636ff6197c4ed52f53af965a3bfeef22ebcd31ed23facdbc9f5ad3e4fb132f55ff00265fe5ff005f213c7c3fd56722328fe6e5ff00a68848ee996330b1125b3f543d2bff001a3e62994a1b0fa1c0e2e128678258519e1027b406af0b6eca3e5ff1bae5b1c80864686e3e9ff5355b55fac822c9cb102a607218ff00b1ad0e583193c99e3c847d27fcc5b708510acc8536a48a6a3e1fe65e5dd0fc58403c8a7264e2e63fae85b7778ddad1983024fa646ea7c47faaff006b237d59e9320df1cbe993722fa6684551b6a7fc6a723216d39f0981afe143baaa7c2df1c2db83dc1fe0f8227a38efffd32e0a396fdba6684077a5511097af5f0c690511e96f538582d73c4d300654d2fc5f6be8c282be368aa6bd076c056954d251fbbe8302869e2256b5a1180166d1e417c40c09454f637b6caa5c2b074120f4d8390a7f6b6fd9ff002d39a62451a6819604d7f121d6ac3f8e2dcbaa29f2c695ca78fc4a68ca6aac0d0823a1046054624b0ea2424ac21bf07f773fd9491bfcba7f7537f97f624cb7eafe8e470b369f6db97fb8ff008e29ba3fa860b85f46ed76f8b657f9ff002be42af6fe261875263e99ff00a7433028c55810c3a83d703b1042f51fbb2aea2488f543d308953564c3198dd7595c5ee9acd369cc66b63fdf5949bededfcd99109fc9d565c12c7fd282bdc2da5d402f74d1c637349ed8f40e3f637de1947ec72f81f2bcb8c558fa18ca5c7bff0017fbbffab8838e52a55d188a7d971b329fe5a7fc4933065020d869e4b2782399bd44220b9ea0aed1b9f11fefa6c9e3cb4aba1d56615b5bea903622415a7cebff00135ccce32473e27271e489db20ff003d07342518c75f8a3f8e27f14ea3fe032bbeae3e48184abf9a888ee6395794abf6b6929d2b913b396353c71a90e252963f4f63f1c4ff0065bc7fe6975c9100b8b28bffd40812a4b0f0cd0bbeb7475435fbf1b6242af2790546c0624a1671f88127e78a57b052411f4e05a580256846d854ec898d44628a7639128a5c412a77c0c8298e40788c2a89b6ba9615f4987ab6b5afa4495e2dfefc8241f14327fa9f6ff6f089743ea8b465c319ff005959a0826432c72fc2bbb48568cbff00317127fd4443fbbff230d0fc7fbf71c4e78f69faa3fce42dc432c32059578f2155606aac3f991c7c2eb80821cd84c48582a6df00a9df22cd5fea676292452f21f655a84d7c3d4081bfd8e0d9a0ea200d1f44913eba4e16cf53aa32ed05d11f1c7fe4c95fef20ff0088659c40ec7fd3b4e6d3898e28ad951ade6483528c371a7a33835574ff005d7edc792ebeafa9c4c79a58f63c9b9feadb7089a353fcafcd7fd8b1c84aaf61c2ec2132458319a924481aaae41ea36df2076478dde1502a2cdebc6c229987194f44957f9264ff008dff00632e865ef706708ddc542ee231b9914551b7a75fa0d3f687f3ff00cdf95ce1c27fa0d247543861c4329e71b751efff001abe63cf1b4ac9911e3024f8e21b2483eda1f0ff009b3ec608643134843012c34527905358241f64d3768ffc8ff8c6d9940890505dea0824e6bbc128f881fe5ff9aa26c157b1e6d987208cbd5fddcbeb44340550056f85baa9dc7b303801a2e7e5d30fe12fffd50d5001a743db342ef69a0cbdf152a8c78ecbd0e05a595a57977c36b4a8a5140a8eb815d2283b0efd0e1085e14851ef91290a946e20740705ab6ca540e5dfa789c6d0b24627a7d03084af85e6f56336fcbeb00d1387daf9648593b7363202b7fa5905be927d102f5e3855cd64b351cd093feec400afd566fe6f45fd3ccd8e9cd7a9d592232bc7f4ac9bcb36352df5f658a9508554b01feb13ff001ae0fca447f13903552ee536f2e88958da5e7243bf0954713feb15ff009a3233d182363fe99075025b4e2829ccb68de8ca14a7530c80c909ed546fef22ff005a3cc430943628184fd588ff00988bb39b4d9e1fa8dc131dbbee90cadc8237f3da5d0ff935265b1e1229a32cb8b698e19a0af2dee74a3e8cdfbdb36358671eff00e57ecb7f938d91b168b315915ddaa91f588cb03f6258cd2a7c194f46c946302cbc592bbb696fbfef9478a80c313871f7ca29f14ac6974a589e35bb652455048845186e3e2a7c3be583146b6971329e7b1cbd494b728dbd48e943f693f64d7e5fb2d984451a2e31d8aa5548f5613543f694ef4ff21c6572c6aa7b825e1ff9e9136e36dfa7ed2640131e68e5c94d635943245fb5f12c67aab01b85fe647cb8cbaa6af92274c92dae2036970dc268f7824f15fe53ff0018cffc266408c6437fa9c8c3964457f31fffd60b545f7cd0bbe6f92d00a6f8a15938924376c696d632823c2b812e750540ee31b452e04d00037c55548631efd7236a8bb3b582e61558ee912ffb5b5c0f4d1b7f87d39f7566ff008adf2c1107facd53998f31e843de5b5e5acc52ee378a53d9fbff00aadf65ff00d8640d8e6ce244b929a866a2a02cec40551b9a9d8623734c8edbb21b26d234388cba84aa978c092dd4815a704033698a0203fa4eb32ce533fd06e6d5347bf08b14cb2bb82ca54ee29fe4f5eff672464180895386e2d63532dd4bf0060bb9d89ad057e9c89932a513e6ed0526102cc0106945af8f881c708920c1636aba7de44e91832da9a7223ed01d7e1af86466624516511289b0a7358d8c72a4105d29f5d794714c37341bf2236ff85cc0cb8a858fa5bfc6121538f12f49352b1528d1996d4ecd19fde4647fc371ff006595c32ff9cd12c313f41ff9273692df46bc61e9ff00a248fd6ddf785e9fcbfcbc4ff2365c29c5a1745053e93aad88f5550bc63af13ce9feac83ed2ffaea993b3d53e1dee1626a8b22f19a14969b1a8a38fa30188236626479174eb03a2c96aa1428a3c752411fea9f886552df63e94101046b1b7242429fbffeba5ff87cae248d8b5f26db90284fc2edf146ebf65bde33ff00124c33875fe14ac601d832fc13762360c7fc9fe47ca784c7faab5dca2c3d46a9fddcea7ed7d904ff0095fc8f96c64c6248363ea7ffd702010a4781cd0bbe2aad50cbe0462ae00825ba8c50a869251576c0ab8a18f6ebe38a2da2c7a8c3c95512467254e0a5269cf1ad0ab50d7052414541abdf5bc5f5770b75667adadc0f513fd81fb717fb06c9899e5f545aa5841dc7a25fd045595a58deceb269ed25a5c0209b69419631bffbaae168dfec66cbb144195869c9290152f525fe72d32f9aeae2e0306b564555151c871fb54434e59942745c6ab083f26686ed79fa4250a96a3951829452484f8550f1f0cb25bb006931f32da7d7ac8416043b54c862ad095535ff0086a6572e6d913b305b1d32e24bb5840093ab135229d773ea13fc9fcb9394c00c44492cdb43f2fde5aa4ab3383f17a8889d3e9f9e631f516db005241325cc9e645692500c3298d61aee1013dbfc94cb0d089620d1b651087137182e843febd4007c0ae609d3f177333a8c721ea08c90c6d03c777241203bfc278b123ba9fe7ff6589d3ca236947fa991c5c86079712db69ae2dc2b595c892371c96098f503ed717ff9ad72b19a50fa870ffb86b5b72ba5df9e17501b4bbec57e127dd7f61f326330774100a5371a65edb31684fd6235deabb4807894ff009a72cab60410865911d4d09dbed0ee0fcb31e714370dc243586e97d4b394d5d7f95bfdfd19edfe5638e75b1403dead79a74d07c4a7d6808a86142c01dc72a7fc4b2793098ee19a0db8c838b9a301412753feabff00366398f722adffd00d2d36e3d0e689de076cca2bb11d30320d2721f0f518a0ab45c1589afc43016245ac927909269503a61480d45272eb80864ad4e8c0e047373293f1d715545af71b6284dfcb2d12ea20331577042ad2a0fbff0093993808b71b3dd2657da7c3a94725adc36dcf98a1a3000f6cb41b71ea92cd72e1f4eb382dace25658471e35e345e24afecb7edf1cb8cc0e6c040963fa7ead772dfb492c6429f850b0a1a9f901f0ff0091903901eee267e191ee4dff00445b5d4e6ee58c99d483507e1603701957af1cae520c85a631ce52e156955028a06e36f1db2027ba98ec80974259fcc4d3229e062f53980bb48dfbba71629cbf99a35cb6721cbf9cd12e484bdb69ac6610dfc4dc4ff752a9a1a7fc54e7edf1ff007d49ff000998d28907671eeb98722dc84e70482e212695e8c3fc961fcd83c6e85b4c011712a724a374914c66b5008a7c43f695c6caf920411b3513dee5be9d5383aadc43fb514837dbf94f5cc6963e0de3c91c48ab6be8a4a476f27a6e7ecdbce4d2bff14cff00b3fecb2c865ef4892cb9fabc92d2e6229703a9145940ff0093770999077e682025b245c6aa4f28ebf0c9daa7f9bf9397f9594485ee3ea604376f77240be99660a87e0a6f4f18c8fe5c23248726719ed4554fd5af41920fddce057881f03fb7f92f93a07fa326443fffd10a010941db342ef5cea4853d31a5b71a8db0daaa2c741cbbd322b6b43028477c36a172321a2d36ef4eb85051df51b79ea6ca67603fdd72282df743fbcff9218816e39ce63f547fce82d9ecaee1425a23c17ac8bf1a8ff5997ec7fcf4e180c08e6d91cb19722a119a8d8d4642edb2a91567772d8ceb3a286e3bd0fdd96427c2c251e2d994c37515dc097708a73ea3a508ea32fbeae298d6c82beb2b49e40ccb566501e8694c84a56a364b868b60438512a30aad5cec057aa7fad912cf88abdad9db5af268dbd491fed3b126b82c3177d60ab0523f7a3651e23da990e3ae49a51b86774f52260b206a518d0353b57a65b3c6271dc35dc41f52d1a8defa5e8de42b756f5af0701c0f97fcdbc331c4270fa4fa7f9b93f7b044b16390f49ddb4d32ce443796123da114122d7d44527f62689ff78abfecb8659296d731c23fd5717ef21ff5520e11810578b67a8170a9c0f565a143feaf2f897fd46c71e312dc1e28ff003db04c72285d434f88716b220cbdd41a0603b7f92ffc9974aa2838ac584a5944ab55146eebd0d47fc45d731e78eb71f4b8c42261d424745b7b98d6e13f6437c249ff008ae41fdd4dff002730e3c9decc4ef62b8c42405ed59a451f6e1701674f665fb32a7f94b992636b4839103fc4bd40a3507fc497fe69ca0c29890a40cd0b196da429211f115fb2e3e5f6792fed65b8e49ba7ffd204ac6847f29cd1077a5b94d5415342305a405e1890396d8a17972011d8e05a5a1558541fa3254ad8dba0c89415cc5168c5803db7a1c8dee94d74dd535c461f5612dd20d943c6d2fdd2ff0078bff2332c139071f262c679fa53a4b68b50ff008ea68df5673d6e52448cfccf17497fe0e39309cb0fe2718c8c3e99712125f2bc124852c3525e5de19c02c3fe7a43ff0054b1108c85c4b6475247d4133d2b47bbd3a2786722449086468eaca08fa36cb217ca9ae59448da85d958d8d68a01a9f9e448a66929bdd8b156690d4d0d2a773f645720432541729c0349fbbaee01d8d7e5f6723c29507b98e58d8223b236c5c50135ff00294f2c44775533084b329407d261252a402a478d3e16cca22e2e3643d7ea5042a4d2191d1fb46db9fa01fb5fec731ce49479b4544f24442fa8c3209a123d451427a120f54746f85d0ff2e4e19c141890aebeb486ba7ffa35dd096d365358a403ed1b476fb3ff0018321e142478a1e89ffb5fe3d6c774326a7652394bb89ace753466009507fcb5fb4b8d9e531c7fd3ff008e289d7f456ded8b301710953cbfdd886b1bfcc8fb2f96406de9f5458cb74ba58dbe2122904f5ee0fd23f6b2ac98ba86b21bb79564915269bd293a45707a57f96561f67fe327fc1e4f0cfa151246cd14a056f63229d2ee2dc1a7f3d3fe36cc8316c41cf03a7ef54d56b559d3707baf35ca8c5487ffd3020717627eecd13be5f5464a537c6a94398d63a771815b6ad14d36c2aed81d8d305aaa2b71ebbe2c4a261d5351b788456f3fa510aeca881bfe0f87a9ff000d878880c258a24d90e9351bd97fbcbb9893d6b2301f703903ba46388e8829248e4243c9c8ff0094d5ff00891c9726c0172b2250ab0520ec41a11f7645245b28f2a6a93cd742d1a57998ef52410a83aeff006be2ff002b2fc26465e4e06a7081b81c288f340f4ede62a7e1edbd376d96b97ca36d512c611ee53e2455151bc8db9f6e208ca886db55304b39ac95770a3e26dc1ff558705ff63913b2844c10848c03d3b904d1491b2af7c54ad33b4370afc8bc75a156028694f85d5fe7fecffd865d16b22d52e2c6c6ee431c0cb69766856ddc9f464aeffb990fc513ff00919135745c79e03563e94ba57bdb398c3731b161feeb9366a7f34727d9917289e00d70c862771c4bd6586e8704dc8df86eb2291fb4bff35a65423c27673632c531e6acef0df7eeb512639d4521d4694e9d12f147ecff00c5d97c6427b7f13873877a008d4348b82a3e027765fb51c8a7fe15d5b2128906c7a64d2418a6114da66a29557faa5d81f1c6d531fe1f122ffc27fc57968c80f3fa990a285bcd2dd7775a06140e08e0dee1d7f76fff0012c89c37c906086b39a5b2b9157709d3634f9738cecebfe52e4019439223b1ddcf70219de480810bff0079074e04f8237fbadbf97270993cd9d81c9fffd42f243c25abbf439a177ab829f41586e461485e854aef8a96c9d80ed809400e27db14a2b4e843191de286e00d96296678587f94be97db5dff0069b2424073f534659575e0ff00378d1aab3807d2d1ad8a8eebea5c9fc266ff0088e489be51835c4c4ff94ff78856d4e58e4f4c5bdac0de1f5740dff25393656dc3103d67fe99b3abea808e33845ff223897f54782ad7c18af6d5b56a81f5b6fb97fe69c8d2f830ee4ebcaf7d773df95b89649288c4542f0ff8255079664e9e2372e3e7801c95b5cb849a43105a981bd4753d0d415562dfe4e59293500c7c5c962591f88e34f8791dc6d56e0a51707364a678c8dfbefeed8d43f226847ec06e2dff0012c14955706d544d0b978c925c354d36daaabcbfd5c1ee48423cbf59491e50fba5551c31534db97f332f25c98084d34bbeb960f048cbea6d21f517929af872183266e08f11f545a32c48dc232e99ee53d39922962eca095a1fe64e43f76dfea36637e7b14baf0b8dba4b75a44cbf1c2a5941aaff003afc9d32d8ca33fa489b03143adf5c43f05d2974ff007e01f18ff5bf664c1c1bb2190a211bd5b5290d2eecd7708b5e7113d7d30df614ff00be1fe1ff007de58058fe72d8297cd6ac8ab7103168eb45916a0ab0fd86fda4917fdf6fff000f954b1b5ca3d42adb6a972adb4ab1cadf69641ca097da58ff00dd6fff00162e08e431e698e4ef45f3d3ef58c6ca6c2f36e56f28e51313dd3f69797ecf0ff80cc8b0596c50d7367716e47a8bf0f442dfbc8c8f04947c4bfeae44c1487fffd5049120520fed74cd0bbe5aa4a5623d3b61b43668003f7e04af60081c4d710abb7e3d3150d275a9edd312aaeb7130e87901b8e5bff6e104b54f0c25cc23e1d7a6f4fd19e332a56a43307afb70b959d3fe078658329ead074a07d265055171e5aba3fbfb5fab37668c345bff00cf26960ff828f0f140f4470e68f5f11b6d2f48937b6d45d07fc5c8241ff23202b4ff0064991e089e457f3528fd514c7cbda34b6f7ff595bc8648f895e309e5c81fe6e4070cb7140c4f3639351198a0a7a8cdf5ad46f618d7f76a8ab24d4d9096f857a7c5cf8fece277b3fc2c46c93c5c176820370370f248dc54d3ad07c47f9b0852e8a4819f82aba4ce3ecb100151fb5cbfbb7e0d894b83f0726828013c76049a1fdbfd91fb1f6300494290cc232240a2de527e2d9b8efc457e8fdbc3cb74aadbdc309a458fe37e4514bec033372f87bffb1c4ee2984a361486a6dea324ea55949078310cbec47d9ff85cd64b0d1e5193863311b111c9f8fe7a222b89dc836d71cffc96d9bee6fb5fec1b2bf0b1df2e0937c4e19f596292a3dddc0a8b8b65b8a75e20ac9ff0b9911e38f29717fc358e4c15b8f5a943169f704dd59c8f6b327da720803da49a1dd7fe7bc7993191fe21c1fee1c7e1ee54985cdbf2b8951984aa14cc9c6486503ecace07c127f92cafeb2659115d78a2991f24b2ea1b6928f0b712ff006a16af253e15217d54fe493edff3e42510d5200a1a42c144372090a3e063bba8f6fe78bfc9ca85c4d860af05fdddafc25fd5b77eb5f8811fecbedffb2f8d332232b161b04cbfffd6031d47153bd33436ef4ab48a8407ee303105498549a8a57b61661c15147204fb8c2bcdc26ea302697257ae142f0180241db02aa4450835eb80a14a5923435e4057c4d30a5a42d291e8ab48dff1582dff0010ae1e1250481cd9b7972c961b56ba625e5084739119245e5d636f538f2f8b2ec479ecebf201c5c90b7104834ab8a49c5a79eaee4feca9e2c397d0dc72c3c9039a5770f6f6f32c0b2fa60806320f214ebe0fd7ece0b4d28349c88e6cab226ed22d0fc15e343c3e7fb591b64021d8842792855ea25534e4acc7c7ecbc7f1e1e4c963b80ccb20f52265ddc6c58f2529cff006793237c2d8aacb84b78e14735e71060f1b1edcb9090ff00b1fdbc9310534bab817400bdb45bc8828e2e0fa772a3fe2b9d7e197fd4972894c5d49c79e2dad2e3a4accc5b4b9fd7602ad6930f4ae947fa9f626ff5a3c89c40f2714c1463d56f6d5cc5282c17668a50430f60df6972a11ae4c7888d9596fb499dc49ea4b61783a4a3fe6baf075ff8c99903250e5fe919095f3565ba961667594daca4ef796eb5b792bff2d76a7947f17f3c7861901e5cd9c85352ded993e9ea76a2263bade597c51303fb4d6e797fc93cb2c16b3b736ce94268ccb6732dcc1d8c441dfc1a193a7faabf1e44c014f08297496f244e50a509fb711ac6d5f1e126dcbfd5c8f8647263c2ff00ffd70714cb4e2c287c7342ef08688624a83b1dc6492a6cee0056fbf032a54550072eddf155ace2b403154c2cec6d668565b9d52dad14ff00badb9c928ff5a28d47fc4f2c1189e72e16896420d08ce48af43cb10afc77d7778dfcb6f0ac2bff000571cb0feec759cffd830e2ca7946305a350d161ff0079b480fe0f773bcbf7c49c23c1c71e911fe7fad3e1e43ce5fe922dfe9ebd8ffde5b7b3b5f030db203ff0527a988cd21cb861fd48a9d38ea672ff00396bf98fcc52502ea128af5081100ff8045c7c599ea57f2f8c74ff0074ccb49323e8debcd2196491896918d6bc7c5bf6f7cb79071081c5b297a024d3a2a9aaf00f53debf157091b24318785e38dc321579233520026b1b5517e85f838e42e992044a5a354a162edc5bf9881b3a9a53972e5819ad242fa4cc2aacb5414242853c69fecbf6b092a16f051007501594717402a79c44d263fceaf1affc3e1082ab3442432c4c540b9d8b9da8a9f60ff373fb6af930d76eb8b896194c687e0005032123fe0d331b2920b44f9a8cf7e974162b88a3609ba386e2411fcac7ecff00c1657c67faac7c4dfd438d7fd7d5d047789f5d8945019852651e0b7517267ff9ed149931901e6d72ae9cbfa6a0fa76997009b3bd485bfe59ef3f767e4b2ff76fff00099214587084235bea365554e4233d42912447fe00b2e020140b8f25d0df5bec92afa0e4fc45be28181fe651f1c792163fa49e25ef6bc24f5ec2436f29e9c5eaa7d9255f8245ff0021f2519772f0f72a2f982e633f56d5610ea362c52b4ff5a13c78ff00ad6ef0ff00a99602912e85ffd02c247d07639a2a77d6e4e492712d51d8fb62abb93d781dc7638a5c9271aa3fd18a80b969d69be2abc10e2b4c690d9507be34aea6d4270a1b4a0ebbe04aa5b5b4973770c10c6667958288ebc6b5fe66fd95c9c059a613342de9d716cb69a6c76ab4e30a70a0141b0ecbfcb99193675b0366d0d391241e9aedcb8afd046259247ae46b180a09640383822a0d7f676ff2b22424243c07a3ea722acc415a6c43fed1f8bf994640ecd8163b28919dea579536eabca9c9957f6b953960b674a719632712956e202b13b80c6b1cbb7f2fc2b264c302e2243095e61a58824709068c4305a725ff002fece4ac302a92dca2c6ec8eccb03d24ea5806038bfc3feea6c8ceda328dad456ea09d6a1d2407af200ffcdd949e1ee71812d1b681ba253de36ff8d5b0080292a66cea3690d3c1d7fa63e1ad297d5264de350478a1a7f4c1e19470ac904c3e1903713fefc50dff001218f090b4a2aa884940aa18fc416aa0fcd3e28ffe170d9452a492a4b184951881b0e8f4ff0057ecb532624921ffd12c4ad37fa7e59a277cb97d3120ee298a151c4551c4efe18a45a97c153cfefc29568e95e9518b154a8e1b0f91c5429537eb4c5936a050d4e255cb5af88c21059179212cceb8b24f2309954fd5a1a3519c83bf25f87e04e5fdee5f82affa4e26aaf87c9975d3dcfaa03c7fbaab72351d3efc079b44690f63ea7a0ad37fbd3c6813fca25a8dfc9f0e4c72f34148b5712f3201d81f88d06ec38f1fb5d392ff00c3fa780b20912024c8010b1023d46dc866057ec86fb35ca8b7053937993d51420b98c2f526bf12ff00c4b10bd165bf2e4fc79730582914a94a0f8bfe0f2410548888151390ceb10a13fb5f1c9e8f3e8abb1c9b145693eba487d1e323721eaf0f85b9fc43dfe1e3f137fbaf24d53e4b7547d3da42b7090a4d5dda124c9fecf81ff89ae532a71881d4c50eb670984c916a0aa46e90b472927dbd454555c8d0ea58103a158ad7a281958f8107e1ff00929c700f26255d1af00354aa7ed5294fa78b53137fd1670e2fe92f47988358dc0f10415ff86e39304adf7ac9bd11f6f81f10680ffc2e1d9050a7ea27c54ff93538fa50ff00ffd9", + input: EXIF_JPG_HEX, expectedOutput: [ "Found 28 tags.", "", @@ -114,7 +115,7 @@ TestRegister.addTests([ }, { name: "Extract EXIF: avatar jpeg", - input: "ffd8ffdb008400080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080058005803012200021101031101ffc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00f39d2237f3223f398e3765047cb8c95ee0f1d6b73c66037852c2786479049772073d7e652ca09ef9da1067bedef597e15b382ffcd6b89248e08d1a57208c95040c73c67381fad6f6a176ff00f08d491adbdb5bc12cd3b24580f85405b71cf392463230319ae09de334cf16ab71aa9f6397b2bb824d34690d641e6ba789d67de4ec55dc08db8e739ffc77a77ad6f14c7e4e8f3a12c156ed157e5c06468f7af18e0ae48fc4d72d2cc069ab2c4e1255941054004647b723fce2afbea4b35bc534c91ce63456944a5fe7cf1cfcdea2b4941b69f6379d36e4a48c270c08638e4e79c1a78cb49c138dfcae00ae96d239b5dba8ec2db4eb37915c6c2a879382704e7a7afa558d6f4fb7d1960b696dedbce89dbed3322ee5dc73b541ce7181d7dcfb55f3f4ea5fb7d795ad4e6e20de747f7940751b94e0823dfd7393f8557946f676ddb882492ddfd4d74497da4b3208e21bd54b380a4ab10383c9fef13dbd2b2afedada1b62f1caccce0328ddca8c904118f507d288b77d8709b6f556330f2d96ce3a015bda8d9a4766080b1b9c30dc39202038f6ebfad610daad8dd93d2ba0d5ee20480c250b398c6370230c55727f43c7b83454bdd58755be68a464a320310192cbcb7bf3c7d2ad79c3fe790ffbec5500c1ee03e554f650381cf4ab7e637aaffdf34e511ca26ef871e38f4c2b72ec90dcc7246c40e87820f1fed0157ee58c1e1f8e1701fcfb7bb73701b2782c17278e4e31f8d67787525bab3b6b5891371903296c839049233d8607a7f2a97c617d6443450cafbc41e4f979cedc480e4e3f88e1f3e84d6325cd3b1c938f355e5f3ff339b1103a0ceed8c89230b93cf20f6ff3d2b4edec74a78205b9bc811c4232584ae33d7b0c743eb546403fe11e90855199a2048ebf75bfcfe745a45e749045bbefe130173d87f3ade5b5cea95da7adb5fd0f45d3751d3f4ad16eff00b25650af84fb43a005c842c4a8c7ca33dbdfd79a5b1d60ae9aaef70ce59fe645c640c77eb8f5ed54b50b29345f0d258c36acf700abf9dbb2a176307e339c92c3f2ac981e5b8d26178623b3cdd8caa48f9b1d40fcff004af1e718d6bcaf7573c274a15ef34ee9b23d62cac6fa39aeac24115c451ab02bf2994606e040ee3afe159fae5d68973046d60eff00687b687cc528c01942fef0e48ee467d39ae834ad2ede7d3cdc4c678eecec4822519121dca1b771c0c67b8fc78ae28c6ff69103e4183cc420f452303f9d77e167bc2f7b1e9611ef0bdec5265c3b1381c9ad2d5a4f308da98071839cf1b4553995448e064904d68eaa85d62906d0b21200ce4f0060febfa57549ea8ed93f7a2674118f35493d4f738ef5a1e5c7ea2a8daa05ba0092464638f715b388ff00baff0097ff005aa66f514e5a973c2d7690de69ee085114d997cb3c84dc324e781c1c0fcbbd67f8b12d12ee21668c525432f98c319dc49c019ec49ebcd47a6ca122910a9632945dc075f99491fa51ae4cb75696770a71b435bb26dc7cc9b4023eaa53f106a52b4ccd46d56e432b29f0dedd8438953e6f6c356cf83a289b534bc755cc4b84c91f78a63fa1ac09a50da394c6312263fef8357bc3b7820bd87cc70a98663ce390b91fd696222dd29242c44252a334ba9deea69fdadaed858c7ff1eed3624562402157241f6e2ae8f045b2ea4f7104b2a83f398a33f2ff00fab9e94786d22bbf10ea17330c24312c28ad93b778dcdd47a103f3adbbb92ce0b416af6eec8b242d12a9daa02306c75f415f3739384a34a32b7f57ff0023e5a729539468c25cbdfe7aff0091c668ccb040efd337b2246a4fdd507a7f21f8572dacc022d55e751b7ed11173df2df2e7fc7f1aded5266b5d64c31102d64b93329c1ea71b81ff003deb06eaf61943b48c15a3b726204fdf62ca08c7d39fcabd3c2425ed1545d51ebe0e12f69ed57da4624aaf966e0f3cfeb52dd2954419184381f2f3d05432c81d9f039dd525e3670dcfcc7238ed815eb3bdd1ec6ba1108df7a32fca4fcd9f6ab3be7ff9eaf4e28c90db3908721bd39edf851bff00d95ffbed6a1b6c4e4c8d09f29b24001b8c724d47733a3e9f1c25b748269246c0e06768fcfe53fa540642c140e0f5a85f00c9c9232467f1ab51d4d1435279189d373dbcdc0ffbe6b5bc3da59d46e115c95b645dccfbb1db381ee6b24465f4c8c2ae59a7238ea785c0fd6bd074cb78b4ed36ce348b6489bdda403efb6d1819faf4ed58e2eafb38596ece6c6d6f654da8eecdfb4bcd1747b4bab97b88fcc91cccf1abee21b0011d4ff7455af0f78874bf107da229191368f944bfc5e983eb9ae07c4897579abb2b4437f92dd0e78cb1e4f6ea063f0ad34b77b6d2e196097c989275dcc0fcb8cf07df91d3fc6bc6960a125cf277933c196029b5ed24ef264fabe971b6a0f34d231637281610782bb179cfae4f35c36b9118278d55711053b4eece7393f875aeb2d01934fb58be4dd34b82fdf3c6093ebcd50f12e9d35a68c84aab2994124804ed2a0a9cf6aedc34dc26a127e477e12aba7523093f238f0c431ee2ac5c1dc839c76e9ec2aae3939e2accdf740230700f1f415eabdd1ed496a89d9898d12304b1183c74e9f9537ecf71fdc6ff00bee9f02949c646723af07d2aef3ea3fef81fe358b958c5cb976326509bd4c671c66a13cc9202d9249008e879a9a28fcc915482d8c74f4f4fd29b2c47cc28000ccc7a718e6b54eda1b276d0d9d374c59921921bdda613e7b0d9feace40e4fe031f515d6a5fdc5c4762218484077361b710c1704e3fc79fc2b8101ed8c76e18b1620b2a92703d0d7576d7d7b234652297ca8711ab20c053c33738ea1413ea33cd7257829ee79f8aa7cf66f52cebe5a59b0a479e20e7202600c7279e7e503afb7b55b8b4d17761299278d48995941e8c4f619e9c8ed9eb5951debb089dd415bd690c8ef92480aa38c7beeff0022b46db599ed34d82285329f69655ce0b1c8c8cfbe4e7a0e9dfb72ba524924724a9ce315189b6be1f96c7c356b7df6a19494c8230be8aa7f9f1f8573b7c50e9f3aa157064390e3214f039ad0bbd4ef648058cb18110060f32318071cf5efc05ebea69935846da7cb6f05d7cdbbcc65765f987ca4120fa8dbd339352e9fbe9a308c1a92933ce6f23733190a0505413b5703a75a7dc6d65520a9278f93d38c1ae8d3435d56e21820956dd6e6421372ee0ad8395c819eddbd6b2752d352c228e179775cabb2b2e38e081c1eff00e7d89f4a3513b23db8568c9a8f51212f13a606ed8a7273db231f5ea2adfdaffd95fcab3e26de09dc49200faf200a93ca7f43fe7f1a9924dea4ca2ba9bda07832e6f744fedb9e4f2ac62c8760a4b37254e077e78fc863ad564d08ac575a82c53f90a5b0cc46460f53ff00d6f41eb5e91e1eff009230bff5d07fe94d611ff9136f3fedb7f4acab4dc76ea7155c4ce327eb6fc4c4b1d19934d6d42e1dff0079033e32b9298c76c93ce39c63247d6a16d1ee12de44123652356711b10199c16230072428231ffeaaddff0099661ffb0537fe8694f8fef5cffd744ffd024acf99dd99fb69ddbfeb4665da5919e7b7d309002c6b3b4c80b1562776d23db38ff0a8a08becd10bcf3e5024b860d2956dc0a052ac08e33b891dfaf6ad2d0ffe461baffaf71ffb2d55b9ff009142dffebea6ff00da7426f99af41a9be7b7a7e25f8352fece85a2f3ae64dea920287a000aed6f4ce0023dbad56b6be83c889bcd966b52de5323aab051d53195279c9c71fe150c9d67ff00ae6bff00a35ea869bff2094ffaf8b7ff00d0452b68d87b34937e65775bb8c491492b8b4998491859182ab60a838fa8c671e9cd634d1bca249b73b4a8db999c92d9cf27fc6ba3bfff008f3b3ffae51ffe8c35889d6fbfdd6ffd0ab7a6fa9d9464dab95ac7f7bbe4567f300195c71d6ae66e7fb8ff0098ff001aaba37df9ff000ad7aaa9a4ac6951da563fffd9", + input: NO_EXIF_JPG_HEX, expectedOutput: "Found 0 tags.\n", recipeConfig: [ { @@ -140,7 +141,7 @@ TestRegister.addTests([ }, { name: "Remove EXIF: meerkat jpeg (has EXIF)", - input: "ffd8ffe12cd645786966000049492a000800000008000f01020004000000534f4e5910010200060000006e0000001a01050001000000740000001b010500010000007c0000002801030001000000020000003101020011000000840000003201020013000000960000006987040001000000aa000000300200004453432d483546000000010000004600000001000000506963746f6d696f20312e322e33312e3000323031303a30373a30342032333a33313a31330018009a82050001000000d00100009d82050001000000d80100002288030001000000030000002788030001000000c80000000090070004000000303232310390020013000000e00100000490020013000000f401000001920500010000000802000002920500010000001002000004920500010000001802000005920500010000002002000007920300010000000500000008920300010000000a0000000992030001000000100000000a920500010000002802000000a30700010000000300000001a30700010000000100000001a40300010000000000000002a40300010000000100000003a40300010000000100000006a40300010000000000000008a40300010000000000000009a4030001000000000000000aa40300010000000000000000000000010000007d000000250000000a000000323030383a30393a30312031333a32343a343600323030383a30393a30312031333a32343a34360043490d0048e801004b9a390040420f00030000000a0000000300000001000000480000000100000006000301030001000000060000001a010500010000007e0200001b010500010000008602000028010300010000000200000001020400010000008e0200000202040001000000402a00000000000048000000010000004800000001000000ffd8ffee000e41646f626500640000000001ffdb0084000604040405040605050609060506090b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010707070d0c0d18101018140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f00068bb671e5ec1500c895b5400786055e0605b5ea299129b545514c16ab82e2b6b80c516b82e295ca315b5c46050b9062825b0a2b8a82adf55b836ef70b133411b057900a852454571a357d11c62ebaa826f51b50f5af862032979ac5708eb0cad546da094f6ff8adbfe346c953ae8e43827c32feee5f47f47fa2b9e4890ee457c303b0b433dcc209a9c09b506d56d83701b9c3c2bc4be1bf59eb6ccb40ff00ddb1e9c8fec9f66cb211b15fe95c5cf5cf9ff3ff00a51412464b1d3e4f85812f68e7a83dd3018f107439316fe19feb6197fbd745752c442c8ed1988f10c3aa7b1ff23fe23950241a29d2eb4e3f44fe8ff728860797271490ee581d9ab92301541da4e24476fde63284bfb58d11a651d0fef546d556f84ed8217f49ff0035d16a3181c94ed4b346fbd67b71461fefc8bfaad7fe0732f04fbf91630f5c2bf8a1fee3fe3aff00ffd00a99c717af541b9c0abc75c8aaa0029810bc0c8b2545c50bc0df155d4c2ad8a57052b7551df0d2b46788756c095a2fe05069b9c6d0a2faa00d451538f35b0ad6be60d46c64f56df70769216dd1d7f95864a13312d5931c6628a672d85bf9821375e5f6105ea0adce8f25036dd5a13fb43db2e38c4b787fa4718669e2353f547f9fff0014904f1dca318a6a823692361423da9d8e5039b7e58472468f229dfe83b6d4b4d8a6d32491b51863a5cdb486a6523a98cff353f63f97098f1721bffba70f067384f873e5fce48dec4f1e5f687ed53a83e0464625cff1624d214daf097971ad7a65b128914472e2952a30128017dc017f685e3dae6021891d6a3bd7df264dfa87f9ceb357a6b143fad8ff00e23fe250a6637aa250804f1ad24a7ed53c464270120e9b248e4dcfd4b6deec5bd15aaf68db78b467dbfc9caa122369391a3d71c468ef044cc11d0c7b3c32a90ac3a6e3a8396bbac9a686685c7aa4a92b251892ae84c335363edfc460eb4f2e4984bb8fd2ff00ffd10a8338e2f5eaa06f8155141c0aa82806e70522da7b98106ec2be18045287975544601456b92114134abfa45a80f1d8f438d23896bdf4bd875c8af129b4b7527d9db088a0cd62add13bb6f87851c4b9ada50b5663538084095a7b169364b60f73688ba85b955fac06052e2dde9bfd93bc7fe5633c46b8a2767132659835f4cbf87f9934b24b6f4c7ab17ef21e95fda53e0c3f8fd9c8c4b660d40c9b7d331fc2a6e4b0fe188e6e5014a96beac12a4d1318e543c91d0d0823b82325747662636c95751d2bcc016df592b65aa00041aa28a249e0b3affc6f97090c9cfd32fe77f39c4962962de1ea8ff33fe252dbed3f54d16f84572a632778e4527830ecc8c3299c4c4d14ce10d4436e63fd8bae1c5f3996e1fd3bb3ff001f4a29ccf8c8077ff2ff00e0b2b323767fd37fc53ac198c7d19072ff004d14bae24961611dec7e993f62e00fddb7d236fbb2e05be3aa303eaf543f9fff0014a77514b1d07246e42a287b1c85efbb990d5e326add6cd2dbc8b3aa6e36643d194f5072709f0972270138d21af81b2bb5beb6158243fbc4f0af63f3c998806ba179ccf78f271ffa78fe3f9ebef204a0bb87e2b79802c3b0aff03954a025b1e6babd38006487d13ff62820cf6a76abdab1fb3dc1febff12caa3220d16ad26b27825b7d3fcd53d4214172b223036f7c940dd848b4ebe06bc72d98dafb975e2329f1c7e9c9eaff0039ffd2297d4d15c2a8a839c707af34179bf97a05df145b5ebde3123a62c6db617463a16dfdb07328b5392d4800b3127ae4e96d171431f004ee461000624a2e4e2c828294cac9dd0b68b415eb8d3605e84a76d8f7c04b1215912bf10c36c486a9f1d1bece56c805682f27b0ba5b9b37f4e551bf7523c1877192848c4d844f1898a298b2daea8a6eb4c516f7e809b8b0ea187ed345fccbfcd1e4e5112de3f57f35d66a34f28ef7b8fa727fbd9a56d12ca098978cabbbc1fc57c46439b769b5b67827e99a902c69e18097654af00b633d273f0d36f0afbfb6188079b0cbc5c3e9e69b58799ededa3fd0faec667d2a43488b1a98fc1a193b7fa87fd8e64c0edc32dc3a59e7a96ffbb9ff003bf9dfd66f56f2ec9a7c02f6ca517fa44dbc7709bb28fe5900e9feb65797098efce2db908ce3f9b947fb34ae2d45d216b690896ce5eb1b74affc6ad98129cb1ec3787f37fe25d4f1981a28196d2e2de3792dd45d5883592d9b7741f2ff008d866463cf190f2652200b8ef1fe6495f4e8c5f2b0d3642cc054db48431fa2b43970c065f4b6e1cf21f41ff3565f42f1c452e6231edc655208f87c457ba9f8b24227e929cf9f8fea1fd197e3fa29758cb2c32358330742498586ea6bd40f66eb9127ab6766e61be19fd32fa575c46622548ac4db53f81cae71120e36af48714abf84fd28195163a249fbcb673553dc1fe0c3230279170f96c5ffd32211af3dfa8e99c800f5d2e6888622d257af86202248dfabd08276c34d56a72bf13c7be00caad6a51fedf6e986d055a092dc13cba0ed8c9785106970bfbad80db2ba21452d96d98a56b4230025b5aa3fa7d6a063694c6f345d5ec638de45564963128f498390a7beddbdd79603ce8b8b1d46394b86f740a0661d7e9c69c85f50053c31a4b71318d8491b157520a3a9a104770460ded4ee374da2b9b3d68ac53b8b5d5c1fdcdcfd98e66f06a7d893fcafb2f969a9794ffdd3aad568b6b1cbfdc7fc750d3412099ad2ed3eada826df17c2b27f46c8f0dedca4d5a5d7981e0c9fe99012218e42ae0ab0eaa7ae45dd8208b0a8ab585926412c2dd636dc7d1844e8b8f9f4b0ca2a415749d4356d11dae347737362dfef4e9b2fc5f0f7a03d73371e5f8879fd4693260363d51466a0ba6ea369fa53455e11c86975647a2b81f677de371fb20fc2d9467c11ab8fd2d5927e20bfe2ff0075ff001e4aa1b978caba315a6c8e36653dc11fad7355931189b0e3d90a5796915c49eb4245adef50cbb4521f114fb0d96e0d4d6c51f615f6be63ba15b0d52ac07c244c390dfc6bff001219b2f16446c6dcec19f1cbd3947f9e965d5b34523440fc517ef2071dd0ee3fe072a27ab899f19c73a1d3e9ff007a8c82fe09d394e9bb0e32f1e95ff3df2b96c5d80d7f890e198b43dcdb888d0fef20907c2c3bff004619331121b3af9c1fffd42c58b91661d00ce40bd792dc3ca36af6ee31b6063688e72ccb55d80c06458d529143ea02c7a75c2cc2a3aab10577f1f0c1c94058ab116a30d8f7c46e83b23ade35896887639191400a8cacc877c8b30a203a8a75070aa3f4ed52e2d53d0957eb1624d4c0cc54a31fda89c7c51bff00abf0b7ed61e2da8ef171751a5865e7b4bf9c8b92c6ceea269e09c705f89e42a15d3dae117fe4f47f07f938401f0fc7d7ff0014e18cb9706d3f547f9c965eda5c5b4aa93af10e2a8e0d51c78ab0d98602087658b2c662e26d41c88854ee0e45b691a34b6f85e19e19f90078a3153bef41cc283f41c8d8e4e29d6e38cb865e93fd24c56f62bc45d375c0d132505a5f91f1c7e01ff9e2ff0088e59c40ed2e7d24e2eab42320e28295d40d677315b6b508709436f74a6a92276f887da4cb7ad486ff00ee9d760d5cf09e13c9d7bf50a0f4a06891bf95f9a9f913956402f61c2ee716632162424a115bc4afc92565237029be40d8dd8fe66f6215923892ebeb30bac170e384f4da3997f9655fd4dfb39918b383cdd4e6c70e2e286c7f9a83d4adbd190cc8b589fe223afd1b771fcd94e5c5c27fa25c59c6f7412ba940e87d489ba8e841fe0d987970b8c546ea28a5840947a908d9251f6e33e1ff0036fd9c8e2cc6068b13f620156e2df8a337a8aa795b4c375207da4dfecffaa73620c6412096c4c2d66f5177b69c7c60ff0029fe287235628f36fd2e6109fa85c25f57e3fa28d7b365857837c2fd509a8f620e4632a2edf51a08ff0001ff0035ffd501c82ab713b1ed9c7bd700d23a1a03d09ef8548d959d8a6c83e123a60456ca45a80f3ef86d695a368d14721f6b011690e9e307651d7a1c4162559632b1835ebd6b903cd905601ca003607be0b56dd0a05e7dc540ee7082c429cce480476e83109a55b396ecdcc5f530df5a0691fa7f68d7b7cb271049a1cd84c4787d5f4b38b2f2dffa2a8d5648ad965359b4f51ea2127a3a8a8f424f1e0dc73698b424c7d66bfa2e8252109de226946ebf2f744a97fd2ce905392c7c14b807fca27f8627b3203f88b991ed29d7d22d45fc8b1c11b369fa899108afa73a0e276ee41ff8d72acbd9408da5c5fd644b5b1c9b64884a6edae34e7f42e151a3ea6094196023a555beda7cd4e6bce1962347fd2ffc4b18e98fd5825fe6a67a5de6837b6bfa2ef58c56b21ac704edcc46c7f6ade71dbfe2b7cb61c321c3f8ff00364e36a32196d9070cd29d56c2ff00406fab4dfe93a6b9adb5d2f415f7ec7db25663b49c3b3050b6d4f4e423eb711656feee688f1a9f0607a1cb31e3c52e6ccea67de8c924f2f4a2b5b841dca80f8cb4986f9ca29fcc4b9a94b71e5d4b79214be75256b1acd191461b8de9b6f968d3438684b883664d5f10dc6ec6a42f0c9eb440153f6d3f64d7e5d8e6b251e13479380762afc9197d6b7358dbeda36e47f92c3f8e533c36a47721cd54996dbb7f7b036e36dfa7ed2e5512607763cb928ac2970af1c3fb557488fda560370bfccad994725ee9ab1411de5fb8b1bbb57d3ef1bd2b886a6da6f14fe53fea1ff85ccb842131bed273f4ba89c8708dcc5fffd62e2d1a76a8ce429ec02ee49455a6e7f562c51317062431fb382904a9ba2b0a8dab884ba4456403baee298dad2a293c4002a460b4220ab98771be42d2136d2b4bb1d42d1520d4238b56a9a595d8f4a3735dbd397752dfe4b71cb23107aeee364cb281dc7a3f9d14bf55d3356d3ee8c5a84124131fe71b37faac3e161feae40dc79b7639c642e25423579691c6a5a47215146e6a76184032200644888b2cdb4893cb3e54b6336af3ac7a83292ce7720569c540cdfe9b1471c7fa4e8b5396594ff45bb9f32f9635711a5b5d24f2ca0b2321dc53dbe9e99394c35460428db5f69d0235c6a13d225709f113c4ef415fa72066032e1279215ff343c9b15d0b54ba018311c56a7a1e950388c94667a20e33d54dfcc9a2ea704b1c4ad3d93539b0a7250687e1af7195e694251a2d98e3381b0a175a4e8f0dcc56d697ea7eb2bce2827d89a0dc123fa66a351a7e11c4370e59d4898ac91e256867d774b431bc5f59b13b3c47f7d111f8f1fa728c7a9ff383893d2c25fddcbfcc9b4961e57d4987a55d3e67ad6d64de073edfcb43fca73263c24d8d9d7f00068ffa54a2f3cb1e63d297d78e332c0bb928dce9feab0fb43fd60b96891fe20c8e107789ff0034a845e608e54f4eeada398aecd55e2e3e63194011e96b333c8b7789672c6b35922a8414922049047c8ee331e62fd32148901561296ac0fce22551beff00f6c7fc3653026268b4722b9f9831bb0f4e47f8a2957ec3fba9fd6b872e1a163e9654a6ea2570ea7d3b91b823e10c7dbf95b31b80c7972470f5085914cae493e8dd21fb7f64337f95fcad97e3c888488363693fffd7284042904743b67216f6055e40c2441d88d8e218ae50cac5fa8aef816955a930544aa9c15482a8d1180508e5e38a04ada32102aa37187609ab56866924251bbe0a5269d2451d0ab50f8644858c933b1f366b16500b39c26a3a69eb65783d4403fc83f6e3ff00627271c846c7d43fa4d13d3449b1e897f3a299e95a6e89ab5e473e8ef369d78ac19ac660668bad498e61461feac9993a7803306361c6cf39c62632a90fe7241f9afe5ed5db50bbbc1207b168d15054171c7ed514d396fbe6ca397864e098dc764abf2a3c9d2b6a4758b90b15880fc5c218d49216a029a7876cbf2512d512427df985a59d574afaae92448e18cad0024315535fc40ca274241b604d178f693e5dbd97524b60a23bb576352bc7663521c9fe5f0cb6796222c63024bd67c9fe49d52c619d6e6506adeb471a7d9236d8fcf304dccb90642229865d45a8cde7d8da69c036d31892db91a8404f6e9b29cb8802041602746de8769eb0b9e16b7c2dfda5ad01f0233512d0891e8ce5adc331eb8ee9a4a616b4922bf9ad660c391e04a3123ba9ecdf4e2745388da71feacdc0cd2c67e9bf8acb0bbbdb3547d36f44b048392db5c1ad40ea0378ff00ac32a8ea278feb1ff12d3b859a845e5ed5ff00777d6a6c2fcf475f86bee0fd96ccd8668cb741024c6afbcbdaad8b97b63f5c8177e49b4aa3dd7bfd197736a31212f59a3950f5046cebd0823bd33172e3bf7b1e6bad2fa3b626daf944ba7cc6aebfc8dfefc43dbdf23872f0ec79318cab6289d5343b9b51ea467eb36cc392b8a160a7715a75f9e5d9f4a63b8e4db49638499784a68c05165ea76ecd4ea3308e3ea10637ef7fffd00170010be9ee0e723c9eb22e347401b623a60660351875aa1dc1ef85079a2ad8c48c4d7e2191218485a8dc5ecccc5a9551d3084c634d5bcfcfed0fa723216ced13c68448ad80ecc4eedba31fde570246cac9cb6246d879312ca3f2fa48135b01a42924a0aa252a0fb9f0cced1c85f9b83ac04c7c93ed6344b5d7219ac6edaa049cd68487001ec46640209ddc3a23931df37dfcba2e976b63a6dba3adb0e1c2bc78af124763fb54cc939a31e6d51c464c2f43f336a53eb0d2cf115423821614353ef41b7f93951cd122f6e26df048dba3255f2ce9d7f787519a2add2303c81f85c0dc0651e1e3944e61946c724fadeede3bc48cafc007150bb8dbc680e571cbea4ca1b24b3f9322bbf3bbdcc6844660f57d4509512b7c14a12a5bc59466466c91aabab7127b452fd634ebbd22e85beab6efe937f73728483c7fc863f6a9fc8f98128189d9c3be13b8b0b224bdf4fd4b5956eedc9a54ecc3d88f1c0353d241bce28917095fbfea529ae450c732342dd40229f10e85586c1b2c12891b38e491cdd1eb37889c2455bc807db8651b8a7707ae60cf07866e3c981994c6c358b69a9159cc6294fd9b4b92684ffc572f6fa72dc7a9e859c660a8ea02c669e97b0345743666145947fc692ae6613637410121b8b6e1c918f38abf04bdb7f1fe5afbe62ce37b8e6d442eb2d4e7b54f459d82447f77de9e2847f2f8618e690aa2d90c9b51576161a9ab4d69fbaba5152a07eedfdbd9b2e204b97a65fcd6c23a87ffd12f0a562a035e39c8757aeb6a542c10d695c348b6d832fc34f6c78934ac901552f5de9915e2535914c6477aef849400a91491315420815f888eb4ef4c36106d381a3d8ddd4e9b732301d6299417fba3f8bfe49e08c78b93892d54a1b4e3b7f3a2b2f346d52de225a0631af5953e351f32bf67fd971c07198f30db8f538e7c8a0e12c45396d95f15f26eaa4c749d4e7d2af16ea2557e26bc4fdd9762cbc06dab2631314f44b4d42df51b48f50b7014c83e21d3891d41ccbe3bddc094083494eb1a569b79306912aeca049434a657395ac7648c794b4622408b346e2abca4228a2bd57e7951f26de328bd3f4bb1d3c3bc4feacb2ecd23b135c78875606dafaf14708c3f7c0d100ee3da995f8b4764f0a1efa695e213dbb8498305a3350353b577197e5c232e3162da2f18954f92c4f306abf57fab6a56c97f675afa7200e07cabd3fd8f1cc38e2cb8fe926bf9b3fde47fe291934f8663d12dfba4ba3f2f699342752d26692c08204a95f563527f6658dbe30bff000b96649ed790708ff54c7eb87f9dfc5175671189db6217ae9f21602ed63319eae94643ee2bb8ff0054e4b0608cb712e28ff3a2dd1c808a9734bf5bd12d804934d2a6702ac8a405703b7f92dfcb99392a3b5d844b4f62c31a78d665e480abf75e8790fd4c330f361af547938262985a6b933c4b697b0a5e47fb21fe1627fc87fd893fe27870e6de8b38e5bd8ae7b64995a5b0769507f796f200b711fb11d1d7dd7334c2d35dc95dc43ccf25346028e00f0fe65ff9a7318e3218108753756ee67b298c5311f1f1a71703c474e43be5f872744d90ff00ffd22949080c3af13be722367ae905d72dc91590d08eb838b7481b2a890b052db62854329008ec702045608d1d7929dfc3254b6b9762283e9c8952adf0ad1f951874a1debed95d8b5e6c8f40f3079c22751691cf7c8365596269683c0494e43fe0f2cf1a71ebfe99c3cfa7c279d459645656bac0ff0073fe5b16329eb7892c7137cfe1657ff8247c075388fd437fe8ff00c75c1390e3fa27c412db8fcbad3e798a691ae461bbdbdd71661f278cfeb4c94714642e12ff004cdd0d791f5453ef2ef95752d1ada5b6b9659a3958346f112ca187c86d5cc9c3c5f498b4cf52272ba416a86381dc90102ee4fbf8644c69b6d8ab6adb33716925249e26953bf615ca886c545d423112b4dfb9077552286bf2e995982da166bf86e61758e391e36d8c82818d7dc6f8c61ba540daac5a618880de838969522aadef4d8e6c0c4986db3839cf522d0713233016f3c91b9e9139afdc0f5ff639872cd387316e1d425cb6475a4fae5acc2e2dca995450f6e4bdd595b6653e193c7aa89626241468371707d4d1cfd4f50a1693469cd60980ea6d98fd9ff8c5957e5f1c8f1633c12fe83120a5f1f9834c9a530ea103e9d76878bb50940dfe52f55c264794c710fe747eaff4a88e523af0a9eaba33381776a55b97fbb633ca3907b91d1b2fc5115e93c516331691dcc120e42542adfb5dc1fa47ed663e6d3f58b44a2bac2e6396758ae2e3eaf2f486edba57b2c8474ff5ff00e0b2cd366fe19158c935b9b69c03fa4613b7d9bf828c0ffad4fe399b38ed6dc3cd2abbb392302746aa56a9731ee0f71c8663ca1ba4c5ffd32755e124849fa33912f5cac5a2921a5006c48a505a721a0a537182f7485cfc8046a6ddf0a2ddb03b1a5705aaba384fb5be0a410985b798b5bb4b7582d2e7d0856b4e11c61b73ddf8f33f7e3640e7b34cb4f091b22cfc5d3ebfabcfbcda8dc313d47aac07dc0819031059470407f084b26b8f5d88798c87fcb62dface4a806e1103905f193171646e0c0ecca6847d2322931bd8bd0ff2dbcc37d717eb612cd2cecc6bcd8d4220ebbf535f7ccbd21919d5ecea35da611a94470a2bf3157d1b3b8643f0d682869bb6cb5cccc9005c7849e7d149a847468e345e43e295b76f6a023318c29bc1b577b5b8b93598991d507c4c766af811c57e8c81d99029859da2470807a7ed329345246c061ab412a66ee4b6be590bfa90d402ae05180a6cc1b3261c9a642d177ba368fa9ca52cd974fd40d196d6427eaf2d77fddb9de36ff272a911c5c279b8797466b8a3c921b97d5f4ab936f7b1392bfeea9766a78a3f47198d974913b869c59ce33ea1c4a91dd5bdf0e319f897e2e1bacaa4771dff00d92e5021c06c7376909e0cb1f3fe6a2e592d75702db593e8dd20e36fabd29d3a2dc01d47fc59993098c9b1da4eb32e3df7ff004c9330d6fcb77a501e15dd93ed432af8ff002b03954b1989b0784b8a41814e6daeb40d6e2e4b27e8fd400fde44c098be629ba8ff0085ff002732239a276973671225e452fd53cb92467948b40c2825520a381d0861f0b7fc4b232d303b844b12034cbbb9d32f543c9208a9c680fdc190ecc3dd72b8ca78f9221e93bb52df0b6bb926b623eaf29acb6bd0a13e0a7f61bc32dc7949e6ccc8479727ffd42466596d8bd7e2e8df46721d5eba97aa30b4471b9184f34c5561642943b138a0af662001db012a22d33fb7d38a533f2fdb2b34b2cd6d6d7aa365b7b8b892061fe50f4fed035ee725c60731c5f371b513aea61fe6f1a71cae789f43cb163c47ed27ab747fe4e93ff0b9299321b461feedc784a27fcacbfdc25afe62bcb79bd2163656cde1f5440dff000e09ca08efdbfd8b923003d652ff00396bf9a35fe4bc2e5235ff008ae1857f5263c16bf968777db2566f32f98aa07d79b7ff00253fe69c8f004fe5b1f77decaff2e757bfbad6592ee6965a46c56a144751eeaa0d733b45000934e1eb30c6205045f9cafa2b995a009536afeac887a1a8201269db2fc991c68c5848bfe6ecc92701c78d1791dc6d53405572156cea940f195ffd22a217350fc89e247ecd6871e101368998358462e2da43242c49915aad4db6d872f96428f4643cd2c9aebeb91cb2ccb20263aa46e18a923607c48a8cb4028e4c87cb7ac5f32c96b2ba7aa2929f5539ab03e15048a6473eabc281911c510e1ea6040b89a4d751924be8cc3711413c1d9412a41f14e5f60ffaa730476c69e7d785c137d77627a97966e50fa96cacea0d53f9d7e4cb9911c98f27d2449a8c1029aadf5b1f4afd1a4886deb05fde01efd9f2271516633486c7746c52fd66c1a2b722ff004f5a911ad4c90b1ebc01fb23c626ff0063970163f9cbc625ee49eef4d92255bcb462d086a2cab50c8e3f65875561fc8d9464c25a658eb70af61e63d4237da758e66fb6928e56d37b3a7ec31fe75c8c32ca277dd9433743f8feb265eb68baa4861914e95a89a73b5987285891d53b80ddb8ff00c0e665821b051f2280bfd2af2cc832a7c1d119bf79130f05906e3e59038fb9062fffd5298ade308c0f47e99c853d7deeb232d11680f4fd9c20a3aae34014d69e3812ab2042a38b57db10a5750f0e95c4a86a2241a9aedd30154645a85e29f858b01b8e5bfe3d72424438f934b8e7cc27565e74b95845bddc1f588c76722407db8ccb22fddc72d19cd6ee29ecf03e891822d6ff00c85a811f5bb0fa9b9fdb843c06bff3ccc917fc2e3c58cf31c3f8fe8a383550e47c46e4f2ef956715b2d66487c05c46b2affc1c457f15c1e144f2923f94271fae09df923ca93d96b1f5c8f5282784a32708096e60eff102071cbf4f88c4d92c33eb61963406e87d7ee4df6b7a9dbc287d08e2559ae29f0a12df0af4dcb53b6195924f46036018bc1e947f0dada9bb1521e595b82b536341b9f1ed938ee105d6f3d9bcbe92c724570e2bc1a80141debf65b89c05907094c7231a290013c36a96dff6bb7f2fd9c1114c8a5a4348222b2845b49c9f8b66e3bd003ff356106b74d222caf9d6e65588fab216288d21a00ecdc885eff463216082d792161447986559de2bc468d9588631b10cbf30763f76687269803c817591d4989a946331fecbfd3232defeee4606caf3d4ff0021b67fb8f5ff0062d950c1889e5c1272e12d364e44e392bcda9dd8a8bcb24bb03af052b27bf4cccc67247612e21fed9ff14c3369384583c4a1696da2debb5e69d34963729f6d88200f6778f7ff00918999d1c86bd40c3fdcb8421d42b5cc77f67ceee789a51320569e3e32dbcc0741281f0b7b306f5172d80eb7c4194a5e4c7f51b4b19a92db37a6d27dbb77af243e1520735fe56fb5fcd95ce01c79c41e497ccee10417aac427f7721ddd076a1fda4f6ca2371361ab96c51b67adea56038349f58b390746f8c11f4fdafa7e25ccd8c848586e8e521fffd62884b00a877e3df390b7ad28a9e389944a3ed0db05b1050cebc89a8a03bd30d36872ac4803826bdc61e881b96c5d56ab4a60b4f0af8837527aef8690aa0480120ed8d215adda22a796c722420a84f2c319a861bf8ed8d81cd953a34ba9d87d5e29253ff152337fc441c3c24f204fb831240e65eb3e44d256d34c7bd76324cb1105e5478e58f9f543cf8d77f6cc9d348efb174d9c478f9525f7d6732f976ee92f17bab9ac9213bf053422bff054cbe5f4a0736377b259da5cada24fe90e20c4c0f21e3e0c37e9804acec9aea837983b299191258fe2695457e0ad2878ff001c8d9b6c0104ecb13b7350a82a5665342caec7c7a32ef846ccb9a9492a8778e451342e94691762c79029cbb7c4a7638ad2cbb8ace082194d4490721242e7b720439f7a7ed64cb00776437d7e97f1aa6a9a726a36ea8384ab486f107f9130da4ff55f30f2cc035270f369f6bb07fa29249e598ee18c9a0de0b96039369f703d0bc51fea9f864f9a6552c008db775f2c5bff00c520e2f31eafa74a60b842eabb3c1382187b03f687df94c606276ff64c0e4947605151eb1e5bba9565134da56a03a4a3fe6aaf165f67ccd8e7007d3fe95946609df628a8f53b9b776749cd9cd5df50b65e56b283d3eb101aa0aff32e1c79632e5b16e9c48ebfe95ab8d634a7262d72c56091a9c752d3be28181fda684d7fe132ebb69240e63fd2b9bcb6973099f4eba4bdb6fd9303026be0637e9f21f1644e2894880291cf61716f234662a57edc26b1b57c78b6d5f96446120d863c0fffd72bb7bb8c2947143fcd9c8bd690b595cb32ab6c771869545e59540461d3a1c0cc056440103f51df15537953951571092c8348d0f4dbbb54b9bef3058e9cadfee86124b381ef1a014ff82cb630891bce31ff00672713267903421297fb94c7ea5f97168b59757d435393fdf76b6eb6ea7fd94d5387f723ae49fc383fdd3571ea0f28c61fd62a6baf7942d36b0f2d89abd24d42e6498ffc8b4e2983c487480ff929233ff629f0731faa75fd48b67cf5aac3fef058e9b62bdbd0b38f97fc13f3c31d4e41b0e187f52293a289faa5397f9ca727e6079e652ab1eaf325762b12c7181ff02ab88cf94ff14becfd4a745840e5f6c9ea3e5b69e4f2a7d6ee6633cf70cccf3b906bc7c4edcb7ea7326aa2eb881c7405283d92cba1c35dd7d3e649ef5deb8c86ca0bcf6e2d25861904919592688fc40024346d5500f8d3e1a656090d9cd27fac178123a17676e0dfcc40fb40d295a83837b6ca58f44f459872474f816848508dc69f4e125900b3d38feacb2280aca38bc6a2a4bc4db487af20c8324189288b9b759ccb0b9502f362e76a2a1aa9f1e5f695b2d1dcd375bb5797b736b398623fbb00710f1923dfe25cc0d4c883cb670f31225610d77aca5e8482ea088fa7bc722b706047f2b7507e9ca4e527c9878c09f50130aa35a8a58843a9c5fa4add471569c52e14760b3a54b7fcf446c98ca0f369998f4e5fd2ff008a42cda0797ef559b4dd4e3b77ff00963bff00dd9f92c9f61bfe17260c4f56a301d364ae4b2d6b4c2c9196109eaa8c2585bfe049189882c4714792eb6d5ecf68ee53ead216f88b7c56ec0f8803927cf271321cfd413e25f30ad25898e6375a44cd693b529c24aa31f0571f0b8ff25f2c8cef92f0750ad1f9df5081bea7afdaaca8363214e54ff5a33423fd68993fd5cb626f932190f22fffd0202c01a5363b31ce469ebc96a3e71cdc0b547ec9f6c2b4bf9c84988ee3b1380326e19f8068a4fa0e14014be3a7daa54e21495552b20ad28463485c5011b1a634ad53e120b570a0af88803e2dc74c8a944699a7cf7faa5b59db426e249dc208aa541a9fda23a28cb31c788d535e59f0c49ba7d037da7c7a7683058a11c2da3e145145d86f41e199d945507498e5c52252fbb2b35988536e7c13e82301dd9311f37c11c002ab16450637047206bdb6f7c8c8328961822416deaf32ace4142bd449fb4483e206544d378dd4657412b492025437114eabca95217bd695c883bb3ad94212e6628d192dc02ab93b80c6aae69ec007cb22c24173098db321955e783d38a1604072180ea3fcae996823ab510ad3dfc6b04ad13bc8b6af49850b3287028d41fb072bca080e26a06d610a9a8595d2543c5282770ca09feb98c780f30e089169ac2cdf711d3de26ff8d4e446289e492a0fa502a78ca69e1227f4c4e15010ff00a32ee2de250c3c636e3f86d80e028e052992e07c332bf03fefc40e3fe1860e0218f0a1238d2266312aa06356542c8a4fbaee9f864b88a88ab4f7114f088ee237650280ecf4f91d9a996c667b948b7fffd18fc75a7c5fecbe59c93d7aa20844c37e408fbbefc507c95a416d5055be2f0c4a624f550a45c8890d3c0e1648880807a557b62c1104afa678af6d8ed80207343815277a7df926c5d185a354febc894351d431ee3241059dfe4f45a51f372cb773b2ddc68c2c6db8b524908ebc94151c57fdf85732f46071dff17f0bafed132e0a1c9e95a9cba8fd6292c27d025b9355761f7e33bb70b1d56c83d23d4faaabce7fd3787148c7f396346afd9d874df2c8f2f344987f9a05c7a8c01a283f19a0ddc529d77151ff000dc7212671a61b1862f2a82160561ea3ee433545280f4ca0b921467a1b98bd71c4ab398b86e58d771b7d38c52796ca363ea1924e1cc382c108a54c7c450ffc178e4c31921a90064170c1a4480052d5f8cf36f4cb765d8ed96061ee4cbcb5f5b8e56fabf099b98f5c27c0dcf71f75373fb3961e4d19792cf30c9a2bcc56ea2b78a7aeef6e794bfecb81ff00892e6264e1bf375f28c4f321049a5da1b532dbeb4aae378ed9e19cb1f62e102ae44c635b90c0c63d0a8c6fab2d0346ce3b303f0ffc3d300df95b59b1e68c8a4d5006ac558ff6e94a7d3434c27887716dc7c5e6a914b72410d0c8a3c432b2fe2572c893dc8bef0a5726d7fdd8233e21a80ffc29c96dd507c902c34863d4a37f9153fc307a18bfffd9ffdb0084000a07070708070a08080a0f0a080a0f120d0a0a0d1214101012101014110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c010b0c0c15131522181822140e0e0e14140e0e0e0e14110c0c0c0c0c11110c0c0c0c0c0c110c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0cffc0001108009600c803011100021101031101ffdd00040019ffc401a20000000701010101010000000000000000040503020601000708090a0b0100020203010101010100000000000000010002030405060708090a0b1000020103030204020607030402060273010203110400052112314151061361227181143291a10715b14223c152d1e1331662f0247282f12543345392a2b26373c235442793a3b33617546474c3d2e2082683090a181984944546a4b456d355281af2e3f3c4d4e4f465758595a5b5c5d5e5f566768696a6b6c6d6e6f637475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f82939495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafa110002020102030505040506040803036d0100021103042112314105511361220671819132a1b1f014c1d1e1234215526272f1332434438216925325a263b2c20773d235e2448317549308090a18192636451a2764745537f2a3b3c32829d3e3f38494a4b4c4d4e4f465758595a5b5c5d5e5f5465666768696a6b6c6d6e6f6475767778797a7b7c7d7e7f738485868788898a8b8c8d8e8f839495969798999a9b9c9d9e9f92a3a4a5a6a7a8a9aaabacadaeafaffda000c03010002110311003f004146684bbe5c06452bc6056c0c50b80c8a57818ab6062b6dd3156c0c55b03155d4c55b51814ba9be155e6293d2694213129e2ce06c09fe6c68d5a3885d2c5dfc29deb8292568215846e6a8768643ff00269ffe65be4a9c412f0a5c27fba97f77fd0fe836cc8bf3f0c0e5a934b1d7738ada91bc881e23738d2daf8ee4484c2c281bec13d2a7f65bfc97c9445ecd393bff00e567f510ca849faa3fc2412d6ec7a83fb51e2458759286fc1fe7609ffbcfc7f1b92674a0762863340c3aa7b1ff008aff00e2190068d15c3a8e1f4cbe8ff70aa41ad5b67ea4d7635c3c3d1cd94481b7ef71285cc48aa641d8fef074d9be16db046fe92eb32c40e4d4352adbd6587a8fe78ffaa57fe032fc72ff004b2447d51fe963ff00a67ff1c7ffd0457340ef970eb81578c0ab80c0ab86055c3155c3156e98ab862adede38ab46441df156beb318c554daf003b0c56d522d4aead9bd487becf19fb2c3f95c64a32312c2711214514d6f16a89eb6947d2b95159b4e7a03eef6edfb6bfe7f065a6025bc7fd2348c9286d2f547fd512e916504a49f2743b1f91f039486d9c44e347e9923ff0047c5776b1c966ced791a52685f73211f69a223f6e9feebfe4c3c3c5cb9ff00bbfc7f31c6c790e33c124bcdbfc2187c43bd3b7b30c8872b8c5d289878bd695c9852556b45dc6280ba51f5a80b2ff7f11049effeb57fcac91ef70f3e2bd87fc92ffaa5ff0010a2643723d40b495451e9de9fcc3fcff932128821d7ca467bff0013514c22146ab5b9fa4a1f6ff2321135b16dc1a830d8fd0aae1594a1a346e080c3a6fdd4e58ec6586392363f892f572b4249565262929d7dbfe365c1d69d2d989fe6bfffd1457340ef978c0abc0c0ab87be34869a58d46e7052549ef1548a0ae48045aff00ad1a03c7ae0a45b4d70fe18136b4bccdd30808325a04c4f5c348b6cc4e16a4ee7010a0a609676e2d9a78145d4141eb72056685a9f17d83bc5fe5e19436b8b8f29caebe99ff00d2bc88568b80e71fc7174af704fecb8ff8dbec3e441678f289edf4cff98b5aa47f0c5bdb883232c8a4aba9aab29a107c4361bae4822d36fad5a6a748b5122def76115fa8f85fc16e57fe667fc432d044f9fa66e3984a1bc7d51fe6212e2daef4fb8114ea518eeac0fc2d4e8f1b8ffaeb2a9031e699463963b372b7d658c93370b8ff00968029c8f8caabfb5ff167fc1e44c8dd97084cc7d33fe1ff004f042caef1304b95e04fd9980f81beef87fe0726da3318fd5eb87faa2d99244a0aab545450f6c8db903342eadd11785c4aabb8d994f420f553928ca8b6ca2242946e2b6d38ba83789b665f9fec9ff5b2446ffd175392e12e2ff959f8ff006d5d3c6bb4f1ef0c82ac3b0aff005c818dec573e202a71feee6a00b43d3e2818fd9ee0ff00cd5ff13c84655b161833cb19dbe95b728a260ea47a374b40dd83ad3fe36e192977ff0035753465c51fa727fbb7ffd204d76a18003ae681df16feb0fd00df145bbd49c9a74c516e226e1b9dfdb145ad6868072249c349b57444e209ed8589577a328a64156fc34df1a6417292bdb638da297aad7718db1a753e2a374c832017a4d25b4cb3db3709146e7a823f9597f6972519107644a02428a2888af019ac944376a0996d3a861fb4d07f3a7f3c1933112de3f57f31c3cb888def7fe0cbff0055507c448098c51c6ed17fc6d1ff0032e41b316a2cf0cbd3916024d3c305b96ab1884c9fbdfb34dbc2bfe57b6102d8ceeb645dbeab1409fa3f534f56c1cfeec13529e0d6f2fecffc636ff6197c4ed52f53af965a3bfeef22ebcd31ed23facdbc9f5ad3e4fb132f55ff00265fe5ff005f213c7c3fd56722328fe6e5ff00a68848ee996330b1125b3f543d2bff001a3e62994a1b0fa1c0e2e128678258519e1027b406af0b6eca3e5ff1bae5b1c80864686e3e9ff5355b55fac822c9cb102a607218ff00b1ad0e583193c99e3c847d27fcc5b708510acc8536a48a6a3e1fe65e5dd0fc58403c8a7264e2e63fae85b7778ddad1983024fa646ea7c47faaff006b237d59e9320df1cbe993722fa6684551b6a7fc6a723216d39f0981afe143baaa7c2df1c2db83dc1fe0f8227a38efffd32e0a396fdba6684077a5511097af5f0c690511e96f538582d73c4d300654d2fc5f6be8c282be368aa6bd076c056954d251fbbe8302869e2256b5a1180166d1e417c40c09454f637b6caa5c2b074120f4d8390a7f6b6fd9ff002d39a62451a6819604d7f121d6ac3f8e2dcbaa29f2c695ca78fc4a68ca6aac0d0823a1046054624b0ea2424ac21bf07f773fd9491bfcba7f7537f97f624cb7eafe8e470b369f6db97fb8ff008e29ba3fa860b85f46ed76f8b657f9ff002be42af6fe261875263e99ff00a7433028c55810c3a83d703b1042f51fbb2aea2488f543d308953564c3198dd7595c5ee9acd369cc66b63fdf5949bededfcd99109fc9d565c12c7fd282bdc2da5d402f74d1c637349ed8f40e3f637de1947ec72f81f2bcb8c558fa18ca5c7bff0017fbbffab8838e52a55d188a7d971b329fe5a7fc4933065020d869e4b2782399bd44220b9ea0aed1b9f11fefa6c9e3cb4aba1d56615b5bea903622415a7cebff00135ccce32473e27271e489db20ff003d07342518c75f8a3f8e27f14ea3fe032bbeae3e48184abf9a888ee6395794abf6b6929d2b913b396353c71a90e252963f4f63f1c4ff0065bc7fe6975c9100b8b28bffd40812a4b0f0cd0bbeb7475435fbf1b6242af2790546c0624a1671f88127e78a57b052411f4e05a580256846d854ec898d44628a7639128a5c412a77c0c8298e40788c2a89b6ba9615f4987ab6b5afa4495e2dfefc8241f14327fa9f6ff6f089743ea8b465c319ff005959a0826432c72fc2bbb48568cbff00317127fd4443fbbff230d0fc7fbf71c4e78f69faa3fce42dc432c32059578f2155606aac3f991c7c2eb80821cd84c48582a6df00a9df22cd5fea676292452f21f655a84d7c3d4081bfd8e0d9a0ea200d1f44913eba4e16cf53aa32ed05d11f1c7fe4c95fef20ff0088659c40ec7fd3b4e6d3898e28ad951ade6483528c371a7a33835574ff005d7edc792ebeafa9c4c79a58f63c9b9feadb7089a353fcafcd7fd8b1c84aaf61c2ec2132458319a924481aaae41ea36df2076478dde1502a2cdebc6c229987194f44957f9264ff008dff00632e865ef706708ddc542ee231b9914551b7a75fa0d3f687f3ff00cdf95ce1c27fa0d247543861c4329e71b751efff001abe63cf1b4ac9911e3024f8e21b2483eda1f0ff009b3ec608643134843012c34527905358241f64d3768ffc8ff8c6d9940890505dea0824e6bbc128f881fe5ff9aa26c157b1e6d987208cbd5fddcbeb44340550056f85baa9dc7b303801a2e7e5d30fe12fffd50d5001a743db342ef69a0cbdf152a8c78ecbd0e05a595a57977c36b4a8a5140a8eb815d2283b0efd0e1085e14851ef91290a946e20740705ab6ca540e5dfa789c6d0b24627a7d03084af85e6f56336fcbeb00d1387daf9648593b7363202b7fa5905be927d102f5e3855cd64b351cd093feec400afd566fe6f45fd3ccd8e9cd7a9d592232bc7f4ac9bcb36352df5f658a9508554b01feb13ff001ae0fca447f13903552ee536f2e88958da5e7243bf0954713feb15ff009a3233d182363fe99075025b4e2829ccb68de8ca14a7530c80c909ed546fef22ff005a3cc430943628184fd588ff00988bb39b4d9e1fa8dc131dbbee90cadc8237f3da5d0ff935265b1e1229a32cb8b698e19a0af2dee74a3e8cdfbdb36358671eff00e57ecb7f938d91b168b315915ddaa91f588cb03f6258cd2a7c194f46c946302cbc592bbb696fbfef9478a80c313871f7ca29f14ac6974a589e35bb652455048845186e3e2a7c3be583146b6971329e7b1cbd494b728dbd48e943f693f64d7e5fb2d984451a2e31d8aa5548f5613543f694ef4ff21c6572c6aa7b825e1ff9e9136e36dfa7ed2640131e68e5c94d635943245fb5f12c67aab01b85fe647cb8cbaa6af92274c92dae2036970dc268f7824f15fe53ff0018cffc266408c6437fa9c8c3964457f31fffd60b545f7cd0bbe6f92d00a6f8a15938924376c696d632823c2b812e750540ee31b452e04d00037c55548631efd7236a8bb3b582e61558ee912ffb5b5c0f4d1b7f87d39f7566ff008adf2c1107facd53998f31e843de5b5e5acc52ee378a53d9fbff00aadf65ff00d8640d8e6ce244b929a866a2a02cec40551b9a9d8623734c8edbb21b26d234388cba84aa978c092dd4815a704033698a0203fa4eb32ce533fd06e6d5347bf08b14cb2bb82ca54ee29fe4f5eff672464180895386e2d63532dd4bf0060bb9d89ad057e9c89932a513e6ed0526102cc0106945af8f881c708920c1636aba7de44e91832da9a7223ed01d7e1af86466624516511289b0a7358d8c72a4105d29f5d794714c37341bf2236ff85cc0cb8a858fa5bfc6121538f12f49352b1528d1996d4ecd19fde4647fc371ff006595c32ff9cd12c313f41ff9273692df46bc61e9ff00a248fd6ddf785e9fcbfcbc4ff2365c29c5a1745053e93aad88f5550bc63af13ce9feac83ed2ffaea993b3d53e1dee1626a8b22f19a14969b1a8a38fa30188236626479174eb03a2c96aa1428a3c752411fea9f886552df63e94101046b1b7242429fbffeba5ff87cae248d8b5f26db90284fc2edf146ebf65bde33ff00124c33875fe14ac601d832fc13762360c7fc9fe47ca784c7faab5dca2c3d46a9fddcea7ed7d904ff0095fc8f96c64c6248363ea7ffd702010a4781cd0bbe2aad50cbe0462ae00825ba8c50a869251576c0ab8a18f6ebe38a2da2c7a8c3c95512467254e0a5269cf1ad0ab50d7052414541abdf5bc5f5770b75667adadc0f513fd81fb717fb06c9899e5f545aa5841dc7a25fd045595a58deceb269ed25a5c0209b69419631bffbaae168dfec66cbb144195869c9290152f525fe72d32f9aeae2e0306b564555151c871fb54434e59942745c6ab083f26686ed79fa4250a96a3951829452484f8550f1f0cb25bb006931f32da7d7ac8416043b54c862ad095535ff0086a6572e6d913b305b1d32e24bb5840093ab135229d773ea13fc9fcb9394c00c44492cdb43f2fde5aa4ab3383f17a8889d3e9f9e631f516db005241325cc9e645692500c3298d61aee1013dbfc94cb0d089620d1b651087137182e843febd4007c0ae609d3f177333a8c721ea08c90c6d03c777241203bfc278b123ba9fe7ff6589d3ca236947fa991c5c86079712db69ae2dc2b595c892371c96098f503ed717ff9ad72b19a50fa870ffb86b5b72ba5df9e17501b4bbec57e127dd7f61f326330774100a5371a65edb31684fd6235deabb4807894ff009a72cab60410865911d4d09dbed0ee0fcb31e714370dc243586e97d4b394d5d7f95bfdfd19edfe5638e75b1403dead79a74d07c4a7d6808a86142c01dc72a7fc4b2793098ee19a0db8c838b9a301412753feabff00366398f722adffd00d2d36e3d0e689de076cca2bb11d30320d2721f0f518a0ab45c1589afc43016245ac927909269503a61480d45272eb80864ad4e8c0e047373293f1d715545af71b6284dfcb2d12ea20331577042ad2a0fbff0093993808b71b3dd2657da7c3a94725adc36dcf98a1a3000f6cb41b71ea92cd72e1f4eb382dace25658471e35e345e24afecb7edf1cb8cc0e6c040963fa7ead772dfb492c6429f850b0a1a9f901f0ff0091903901eee267e191ee4dff00445b5d4e6ee58c99d483507e1603701957af1cae520c85a631ce52e156955028a06e36f1db2027ba98ec80974259fcc4d3229e062f53980bb48dfbba71629cbf99a35cb6721cbf9cd12e484bdb69ac6610dfc4dc4ff752a9a1a7fc54e7edf1ff007d49ff000998d28907671eeb98722dc84e70482e212695e8c3fc961fcd83c6e85b4c011712a724a374914c66b5008a7c43f695c6caf920411b3513dee5be9d5383aadc43fb514837dbf94f5cc6963e0de3c91c48ab6be8a4a476f27a6e7ecdbce4d2bff14cff00b3fecb2c865ef4892cb9fabc92d2e6229703a9145940ff0093770999077e682025b245c6aa4f28ebf0c9daa7f9bf9397f9594485ee3ea604376f77240be99660a87e0a6f4f18c8fe5c23248726719ed4554fd5af41920fddce057881f03fb7f92f93a07fa326443fffd10a010941db342ef5cea4853d31a5b71a8db0daaa2c741cbbd322b6b43028477c36a172321a2d36ef4eb85051df51b79ea6ca67603fdd72282df743fbcff9218816e39ce63f547fce82d9ecaee1425a23c17ac8bf1a8ff5997ec7fcf4e180c08e6d91cb19722a119a8d8d4642edb2a91567772d8ceb3a286e3bd0fdd96427c2c251e2d994c37515dc097708a73ea3a508ea32fbeae298d6c82beb2b49e40ccb566501e8694c84a56a364b868b60438512a30aad5cec057aa7fad912cf88abdad9db5af268dbd491fed3b126b82c3177d60ab0523f7a3651e23da990e3ae49a51b86774f52260b206a518d0353b57a65b3c6271dc35dc41f52d1a8defa5e8de42b756f5af0701c0f97fcdbc331c4270fa4fa7f9b93f7b044b16390f49ddb4d32ce443796123da114122d7d44527f62689ff78abfecb8659296d731c23fd5717ef21ff5520e11810578b67a8170a9c0f565a143feaf2f897fd46c71e312dc1e28ff003db04c72285d434f88716b220cbdd41a0603b7f92ffc9974aa2838ac584a5944ab55146eebd0d47fc45d731e78eb71f4b8c42261d424745b7b98d6e13f6437c249ff008ae41fdd4dff002730e3c9decc4ef62b8c42405ed59a451f6e1701674f665fb32a7f94b992636b4839103fc4bd40a3507fc497fe69ca0c29890a40cd0b196da429211f115fb2e3e5f6792fed65b8e49ba7ffd204ac6847f29cd1077a5b94d5415342305a405e1890396d8a17972011d8e05a5a1558541fa3254ad8dba0c89415cc5168c5803db7a1c8dee94d74dd535c461f5612dd20d943c6d2fdd2ff0078bff2332c139071f262c679fa53a4b68b50ff008ea68df5673d6e52448cfccf17497fe0e39309cb0fe2718c8c3e99712125f2bc124852c3525e5de19c02c3fe7a43ff0054b1108c85c4b6475247d4133d2b47bbd3a2786722449086468eaca08fa36cb217ca9ae59448da85d958d8d68a01a9f9e448a66929bdd8b156690d4d0d2a773f645720432541729c0349fbbaee01d8d7e5f6723c29507b98e58d8223b236c5c50135ff00294f2c44775533084b329407d261252a402a478d3e16cca22e2e3643d7ea5042a4d2191d1fb46db9fa01fb5fec731ce49479b4544f24442fa8c3209a123d451427a120f54746f85d0ff2e4e19c141890aebeb486ba7ffa35dd096d365358a403ed1b476fb3ff0018321e142478a1e89ffb5fe3d6c774326a7652394bb89ace753466009507fcb5fb4b8d9e531c7fd3ff008e289d7f456ded8b301710953cbfdd886b1bfcc8fb2f96406de9f5458cb74ba58dbe2122904f5ee0fd23f6b2ac98ba86b21bb79564915269bd293a45707a57f96561f67fe327fc1e4f0cfa151246cd14a056f63229d2ee2dc1a7f3d3fe36cc8316c41cf03a7ef54d56b559d3707baf35ca8c5487ffd3020717627eecd13be5f5464a537c6a94398d63a771815b6ad14d36c2aed81d8d305aaa2b71ebbe2c4a261d5351b788456f3fa510aeca881bfe0f87a9ff000d878880c258a24d90e9351bd97fbcbb9893d6b2301f703903ba46388e8829248e4243c9c8ff0094d5ff00891c9726c0172b2250ab0520ec41a11f7645245b28f2a6a93cd742d1a57998ef52410a83aeff006be2ff002b2fc26465e4e06a7081b81c288f340f4ede62a7e1edbd376d96b97ca36d512c611ee53e2455151bc8db9f6e208ca886db55304b39ac95770a3e26dc1ff558705ff63913b2844c10848c03d3b904d1491b2af7c54ad33b4370afc8bc75a156028694f85d5fe7fecffd865d16b22d52e2c6c6ee431c0cb69766856ddc9f464aeffb990fc513ff00919135745c79e03563e94ba57bdb398c3731b161feeb9366a7f34727d9917289e00d70c862771c4bd6586e8704dc8df86eb2291fb4bff35a65423c27673632c531e6acef0df7eeb512639d4521d4694e9d12f147ecff00c5d97c6427b7f13873877a008d4348b82a3e027765fb51c8a7fe15d5b2128906c7a64d2418a6114da66a29557faa5d81f1c6d531fe1f122ffc27fc57968c80f3fa990a285bcd2dd7775a06140e08e0dee1d7f76fff0012c89c37c906086b39a5b2b9157709d3634f9738cecebfe52e4019439223b1ddcf70219de480810bff0079074e04f8237fbadbf97270993cd9d81c9fffd42f243c25abbf439a177ab829f41586e461485e854aef8a96c9d80ed809400e27db14a2b4e843191de286e00d96296678587f94be97db5dff0069b2424073f534659575e0ff00378d1aab3807d2d1ad8a8eebea5c9fc266ff0088e489be51835c4c4ff94ff78856d4e58e4f4c5bdac0de1f5740dff25393656dc3103d67fe99b3abea808e33845ff223897f54782ad7c18af6d5b56a81f5b6fb97fe69c8d2f830ee4ebcaf7d773df95b89649288c4542f0ff8255079664e9e2372e3e7801c95b5cb849a43105a981bd4753d0d415562dfe4e59293500c7c5c962591f88e34f8791dc6d56e0a51707364a678c8dfbefeed8d43f226847ec06e2dff0012c14955706d544d0b978c925c354d36daaabcbfd5c1ee48423cbf59491e50fba5551c31534db97f332f25c98084d34bbeb960f048cbea6d21f517929af872183266e08f11f545a32c48dc232e99ee53d39922962eca095a1fe64e43f76dfea36637e7b14baf0b8dba4b75a44cbf1c2a5941aaff003afc9d32d8ca33fa489b03143adf5c43f05d2974ff007e01f18ff5bf664c1c1bb2190a211bd5b5290d2eecd7708b5e7113d7d30df614ff00be1fe1ff007de58058fe72d8297cd6ac8ab7103168eb45916a0ab0fd86fda4917fdf6fff000f954b1b5ca3d42adb6a972adb4ab1cadf69641ca097da58ff00dd6fff00162e08e431e698e4ef45f3d3ef58c6ca6c2f36e56f28e51313dd3f69797ecf0ff80cc8b0596c50d7367716e47a8bf0f442dfbc8c8f04947c4bfeae44c1487fffd5049120520fed74cd0bbe5aa4a5623d3b61b43668003f7e04af60081c4d710abb7e3d3150d275a9edd312aaeb7130e87901b8e5bff6e104b54f0c25cc23e1d7a6f4fd19e332a56a43307afb70b959d3fe078658329ead074a07d265055171e5aba3fbfb5fab37668c345bff00cf26960ff828f0f140f4470e68f5f11b6d2f48937b6d45d07fc5c8241ff23202b4ff0064991e089e457f3528fd514c7cbda34b6f7ff595bc8648f895e309e5c81fe6e4070cb7140c4f3639351198a0a7a8cdf5ad46f618d7f76a8ab24d4d9096f857a7c5cf8fece277b3fc2c46c93c5c176820370370f248dc54d3ad07c47f9b0852e8a4819f82aba4ce3ecb100151fb5cbfbb7e0d894b83f0726828013c76049a1fdbfd91fb1f6300494290cc232240a2de527e2d9b8efc457e8fdbc3cb74aadbdc309a458fe37e4514bec033372f87bffb1c4ee2984a361486a6dea324ea55949078310cbec47d9ff85cd64b0d1e5193863311b111c9f8fe7a222b89dc836d71cffc96d9bee6fb5fec1b2bf0b1df2e0937c4e19f596292a3dddc0a8b8b65b8a75e20ac9ff0b9911e38f29717fc358e4c15b8f5a943169f704dd59c8f6b327da720803da49a1dd7fe7bc7993191fe21c1fee1c7e1ee54985cdbf2b8951984aa14cc9c6486503ecace07c127f92cafeb2659115d78a2991f24b2ea1b6928f0b712ff006a16af253e15217d54fe493edff3e42510d5200a1a42c144372090a3e063bba8f6fe78bfc9ca85c4d860af05fdddafc25fd5b77eb5f8811fecbedffb2f8d332232b161b04cbfffd6031d47153bd33436ef4ab48a8407ee303105498549a8a57b61661c15147204fb8c2bcdc26ea302697257ae142f0180241db02aa4450835eb80a14a5923435e4057c4d30a5a42d291e8ab48dff1582dff0010ae1e1250481cd9b7972c961b56ba625e5084739119245e5d636f538f2f8b2ec479ecebf201c5c90b7104834ab8a49c5a79eaee4feca9e2c397d0dc72c3c9039a5770f6f6f32c0b2fa60806320f214ebe0fd7ece0b4d28349c88e6cab226ed22d0fc15e343c3e7fb591b64021d8842792855ea25534e4acc7c7ecbc7f1e1e4c963b80ccb20f52265ddc6c58f2529cff006793237c2d8aacb84b78e14735e71060f1b1edcb9090ff00b1fdbc9310534bab817400bdb45bc8828e2e0fa772a3fe2b9d7e197fd4972894c5d49c79e2dad2e3a4accc5b4b9fd7602ad6930f4ae947fa9f626ff5a3c89c40f2714c1463d56f6d5cc5282c17668a50430f60df6972a11ae4c7888d9596fb499dc49ea4b61783a4a3fe6baf075ff8c99903250e5fe919095f3565ba961667594daca4ef796eb5b792bff2d76a7947f17f3c7861901e5cd9c85352ded993e9ea76a2263bade597c51303fb4d6e797fc93cb2c16b3b736ce94268ccb6732dcc1d8c441dfc1a193a7faabf1e44c014f08297496f244e50a509fb711ac6d5f1e126dcbfd5c8f8647263c2ff00ffd70714cb4e2c287c7342ef08688624a83b1dc6492a6cee0056fbf032a54550072eddf155ace2b403154c2cec6d668565b9d52dad14ff00badb9c928ff5a28d47fc4f2c1189e72e16896420d08ce48af43cb10afc77d7778dfcb6f0ac2bff000571cb0feec759cffd830e2ca7946305a350d161ff0079b480fe0f773bcbf7c49c23c1c71e911fe7fad3e1e43ce5fe922dfe9ebd8ffde5b7b3b5f030db203ff0527a988cd21cb861fd48a9d38ea672ff00396bf98fcc52502ea128af5081100ff8045c7c599ea57f2f8c74ff0074ccb49323e8debcd2196491896918d6bc7c5bf6f7cb79071081c5b297a024d3a2a9aaf00f53debf157091b24318785e38dc321579233520026b1b5517e85f838e42e992044a5a354a162edc5bf9881b3a9a53972e5819ad242fa4cc2aacb5414242853c69fecbf6b092a16f051007501594717402a79c44d263fceaf1affc3e1082ab3442432c4c540b9d8b9da8a9f60ff373fb6af930d76eb8b896194c687e0005032123fe0d331b2920b44f9a8cf7e974162b88a3609ba386e2411fcac7ecff00c1657c67faac7c4dfd438d7fd7d5d047789f5d8945019852651e0b7517267ff9ed149931901e6d72ae9cbfa6a0fa76997009b3bd485bfe59ef3f767e4b2ff76fff00099214587084235bea365554e4233d42912447fe00b2e020140b8f25d0df5bec92afa0e4fc45be28181fe651f1c792163fa49e25ef6bc24f5ec2436f29e9c5eaa7d9255f8245ff0021f2519772f0f72a2f982e633f56d5610ea362c52b4ff5a13c78ff00ad6ef0ff00a99602912e85ffd02c247d07639a2a77d6e4e492712d51d8fb62abb93d781dc7638a5c9271aa3fd18a80b969d69be2abc10e2b4c690d9507be34aea6d4270a1b4a0ebbe04aa5b5b4973770c10c6667958288ebc6b5fe66fd95c9c059a613342de9d716cb69a6c76ab4e30a70a0141b0ecbfcb99193675b0366d0d391241e9aedcb8afd046259247ae46b180a09640383822a0d7f676ff2b22424243c07a3ea722acc415a6c43fed1f8bf994640ecd8163b28919dea579536eabca9c9957f6b953960b674a719632712956e202b13b80c6b1cbb7f2fc2b264c302e2243095e61a58824709068c4305a725ff002fece4ac302a92dca2c6ec8eccb03d24ea5806038bfc3feea6c8ceda328dad456ea09d6a1d2407af200ffcdd949e1ee71812d1b681ba253de36ff8d5b0080292a66cea3690d3c1d7fa63e1ad297d5264de350478a1a7f4c1e19470ac904c3e1903713fefc50dff001218f090b4a2aa884940aa18fc416aa0fcd3e28ffe170d9452a492a4b184951881b0e8f4ff0057ecb532624921ffd12c4ad37fa7e59a277cb97d3120ee298a151c4551c4efe18a45a97c153cfefc29568e95e9518b154a8e1b0f91c5429537eb4c5936a050d4e255cb5af88c21059179212cceb8b24f2309954fd5a1a3519c83bf25f87e04e5fdee5f82affa4e26aaf87c9975d3dcfaa03c7fbaab72351d3efc079b44690f63ea7a0ad37fbd3c6813fca25a8dfc9f0e4c72f34148b5712f3201d81f88d06ec38f1fb5d392ff00c3fa780b20912024c8010b1023d46dc866057ec86fb35ca8b7053937993d51420b98c2f526bf12ff00c4b10bd165bf2e4fc79730582914a94a0f8bfe0f2410548888151390ceb10a13fb5f1c9e8f3e8abb1c9b145693eba487d1e323721eaf0f85b9fc43dfe1e3f137fbaf24d53e4b7547d3da42b7090a4d5dda124c9fecf81ff89ae532a71881d4c50eb670984c916a0aa46e90b472927dbd454555c8d0ea58103a158ad7a281958f8107e1ff00929c700f26255d1af00354aa7ed5294fa78b53137fd1670e2fe92f47988358dc0f10415ff86e39304adf7ac9bd11f6f81f10680ffc2e1d9050a7ea27c54ff93538fa50ff00ffd9", + input: EXIF_JPG_HEX, expectedOutput: "Found 0 tags.\n", recipeConfig: [ { @@ -159,7 +160,7 @@ TestRegister.addTests([ }, { name: "Extract EXIF: avatar jpeg (has no EXIF)", - input: "ffd8ffdb008400080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080058005803012200021101031101ffc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00f39d2237f3223f398e3765047cb8c95ee0f1d6b73c66037852c2786479049772073d7e652ca09ef9da1067bedef597e15b382ffcd6b89248e08d1a57208c95040c73c67381fad6f6a176ff00f08d491adbdb5bc12cd3b24580f85405b71cf392463230319ae09de334cf16ab71aa9f6397b2bb824d34690d641e6ba789d67de4ec55dc08db8e739ffc77a77ad6f14c7e4e8f3a12c156ed157e5c06468f7af18e0ae48fc4d72d2cc069ab2c4e1255941054004647b723fce2afbea4b35bc534c91ce63456944a5fe7cf1cfcdea2b4941b69f6379d36e4a48c270c08638e4e79c1a78cb49c138dfcae00ae96d239b5dba8ec2db4eb37915c6c2a879382704e7a7afa558d6f4fb7d1960b696dedbce89dbed3322ee5dc73b541ce7181d7dcfb55f3f4ea5fb7d795ad4e6e20de747f7940751b94e0823dfd7393f8557946f676ddb882492ddfd4d74497da4b3208e21bd54b380a4ab10383c9fef13dbd2b2afedada1b62f1caccce0328ddca8c904118f507d288b77d8709b6f556330f2d96ce3a015bda8d9a4766080b1b9c30dc39202038f6ebfad610daad8dd93d2ba0d5ee20480c250b398c6370230c55727f43c7b83454bdd58755be68a464a320310192cbcb7bf3c7d2ad79c3fe790ffbec5500c1ee03e554f650381cf4ab7e637aaffdf34e511ca26ef871e38f4c2b72ec90dcc7246c40e87820f1fed0157ee58c1e1f8e1701fcfb7bb73701b2782c17278e4e31f8d67787525bab3b6b5891371903296c839049233d8607a7f2a97c617d6443450cafbc41e4f979cedc480e4e3f88e1f3e84d6325cd3b1c938f355e5f3ff339b1103a0ceed8c89230b93cf20f6ff3d2b4edec74a78205b9bc811c4232584ae33d7b0c743eb546403fe11e90855199a2048ebf75bfcfe745a45e749045bbefe130173d87f3ade5b5cea95da7adb5fd0f45d3751d3f4ad16eff00b25650af84fb43a005c842c4a8c7ca33dbdfd79a5b1d60ae9aaef70ce59fe645c640c77eb8f5ed54b50b29345f0d258c36acf700abf9dbb2a176307e339c92c3f2ac981e5b8d26178623b3cdd8caa48f9b1d40fcff004af1e718d6bcaf7573c274a15ef34ee9b23d62cac6fa39aeac24115c451ab02bf2994606e040ee3afe159fae5d68973046d60eff00687b687cc528c01942fef0e48ee467d39ae834ad2ede7d3cdc4c678eecec4822519121dca1b771c0c67b8fc78ae28c6ff69103e4183cc420f452303f9d77e167bc2f7b1e9611ef0bdec5265c3b1381c9ad2d5a4f308da98071839cf1b4553995448e064904d68eaa85d62906d0b21200ce4f0060febfa57549ea8ed93f7a2674118f35493d4f738ef5a1e5c7ea2a8daa05ba0092464638f715b388ff00baff0097ff005aa66f514e5a973c2d7690de69ee085114d997cb3c84dc324e781c1c0fcbbd67f8b12d12ee21668c525432f98c319dc49c019ec49ebcd47a6ca122910a9632945dc075f99491fa51ae4cb75696770a71b435bb26dc7cc9b4023eaa53f106a52b4ccd46d56e432b29f0dedd8438953e6f6c356cf83a289b534bc755cc4b84c91f78a63fa1ac09a50da394c6312263fef8357bc3b7820bd87cc70a98663ce390b91fd696222dd29242c44252a334ba9deea69fdadaed858c7ff1eed3624562402157241f6e2ae8f045b2ea4f7104b2a83f398a33f2ff00fab9e94786d22bbf10ea17330c24312c28ad93b778dcdd47a103f3adbbb92ce0b416af6eec8b242d12a9daa02306c75f415f3739384a34a32b7f57ff0023e5a729539468c25cbdfe7aff0091c668ccb040efd337b2246a4fdd507a7f21f8572dacc022d55e751b7ed11173df2df2e7fc7f1aded5266b5d64c31102d64b93329c1ea71b81ff003deb06eaf61943b48c15a3b726204fdf62ca08c7d39fcabd3c2425ed1545d51ebe0e12f69ed57da4624aaf966e0f3cfeb52dd2954419184381f2f3d05432c81d9f039dd525e3670dcfcc7238ed815eb3bdd1ec6ba1108df7a32fca4fcd9f6ab3be7ff9eaf4e28c90db3908721bd39edf851bff00d95ffbed6a1b6c4e4c8d09f29b24001b8c724d47733a3e9f1c25b748269246c0e06768fcfe53fa540642c140e0f5a85f00c9c9232467f1ab51d4d1435279189d373dbcdc0ffbe6b5bc3da59d46e115c95b645dccfbb1db381ee6b24465f4c8c2ae59a7238ea785c0fd6bd074cb78b4ed36ce348b6489bdda403efb6d1819faf4ed58e2eafb38596ece6c6d6f654da8eecdfb4bcd1747b4bab97b88fcc91cccf1abee21b0011d4ff7455af0f78874bf107da229191368f944bfc5e983eb9ae07c4897579abb2b4437f92dd0e78cb1e4f6ea063f0ad34b77b6d2e196097c989275dcc0fcb8cf07df91d3fc6bc6960a125cf277933c196029b5ed24ef264fabe971b6a0f34d231637281610782bb179cfae4f35c36b9118278d55711053b4eece7393f875aeb2d01934fb58be4dd34b82fdf3c6093ebcd50f12e9d35a68c84aab2994124804ed2a0a9cf6aedc34dc26a127e477e12aba7523093f238f0c431ee2ac5c1dc839c76e9ec2aae3939e2accdf740230700f1f415eabdd1ed496a89d9898d12304b1183c74e9f9537ecf71fdc6ff00bee9f02949c646723af07d2aef3ea3fef81fe358b958c5cb976326509bd4c671c66a13cc9202d9249008e879a9a28fcc915482d8c74f4f4fd29b2c47cc28000ccc7a718e6b54eda1b276d0d9d374c59921921bdda613e7b0d9feace40e4fe031f515d6a5fdc5c4762218484077361b710c1704e3fc79fc2b8101ed8c76e18b1620b2a92703d0d7576d7d7b234652297ca8711ab20c053c33738ea1413ea33cd7257829ee79f8aa7cf66f52cebe5a59b0a479e20e7202600c7279e7e503afb7b55b8b4d17761299278d48995941e8c4f619e9c8ed9eb5951debb089dd415bd690c8ef92480aa38c7beeff0022b46db599ed34d82285329f69655ce0b1c8c8cfbe4e7a0e9dfb72ba524924724a9ce315189b6be1f96c7c356b7df6a19494c8230be8aa7f9f1f8573b7c50e9f3aa157064390e3214f039ad0bbd4ef648058cb18110060f32318071cf5efc05ebea69935846da7cb6f05d7cdbbcc65765f987ca4120fa8dbd339352e9fbe9a308c1a92933ce6f23733190a0505413b5703a75a7dc6d65520a9278f93d38c1ae8d3435d56e21820956dd6e6421372ee0ad8395c819eddbd6b2752d352c228e179775cabb2b2e38e081c1eff00e7d89f4a3513b23db8568c9a8f51212f13a606ed8a7273db231f5ea2adfdaffd95fcab3e26de09dc49200faf200a93ca7f43fe7f1a9924dea4ca2ba9bda07832e6f744fedb9e4f2ac62c8760a4b37254e077e78fc863ad564d08ac575a82c53f90a5b0cc46460f53ff00d6f41eb5e91e1eff009230bff5d07fe94d611ff9136f3fedb7f4acab4dc76ea7155c4ce327eb6fc4c4b1d19934d6d42e1dff0079033e32b9298c76c93ce39c63247d6a16d1ee12de44123652356711b10199c16230072428231ffeaaddff0099661ffb0537fe8694f8fef5cffd744ffd024acf99dd99fb69ddbfeb4665da5919e7b7d309002c6b3b4c80b1562776d23db38ff0a8a08becd10bcf3e5024b860d2956dc0a052ac08e33b891dfaf6ad2d0ffe461baffaf71ffb2d55b9ff009142dffebea6ff00da7426f99af41a9be7b7a7e25f8352fece85a2f3ae64dea920287a000aed6f4ce0023dbad56b6be83c889bcd966b52de5323aab051d53195279c9c71fe150c9d67ff00ae6bff00a35ea869bff2094ffaf8b7ff00d0452b68d87b34937e65775bb8c491492b8b4998491859182ab60a838fa8c671e9cd634d1bca249b73b4a8db999c92d9cf27fc6ba3bfff008f3b3ffae51ffe8c35889d6fbfdd6ffd0ab7a6fa9d9464dab95ac7f7bbe4567f300195c71d6ae66e7fb8ff0098ff001aaba37df9ff000ad7aaa9a4ac6951da563fffd9", + input: NO_EXIF_JPG_HEX, expectedOutput: "Found 0 tags.\n", recipeConfig: [ { @@ -193,7 +194,7 @@ TestRegister.addTests([ }, { name: "Extract LSB", - input: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000449494441547801cc9703782b5914c783b56ddbb659db6e9f6ddbb66dd45e6fddc6aecd24cff67b99397b6ebe9d6216d99bcceebefb7dffbaf9ff0e7347e4e491eeddbbf7f5bcbcbc41b9b9b943376cd8f00ef9194afcfb67094ac0d3ed85870d1b764755555592c562616a6a6a18ad560b28b6a0a0203b3d3d7d4e494989fed75f7fdd45fe5e10e38c8c8c0f2a2b2b7737343468ebeaea8a516aabd50a441c00278d46c392cf2a95eaf475d75d7767525252505656565f67332296c9644330d2cbc48c2f3e005f656565ed08c410656666c653bb63e4ef9acd66ce9c0a8027164b430d20aea8a8d84e4c5c05c02c1ebce9a69b6e27af49d5e5f5f5f56a4700b5b5b5ac0300ae1cad3ffdf4d3321a0809365bc93f007068cea9b8b8584e35197abd7e8e5019c032983103aba8ca306fdebc07dadada2c02f4c0a15b6eb9e50ea746313535f5ade6e6e63a57008870170c14397b9e7cf2c97bc838d20294969636e30eb0a1181ce9de2217ce2d087089060037e139b1587ce7fefdfbfd30fa3ef4e9771140a1501cc3ffbb91deea2a05b8991640a9541ec5ffbb5e2800497272f20f7880afad5bb73273e7ce05bea64c99922ee49de07a9d4ed760341a812fbc9030696969c0574a4a8a11ffef5a979d5fbaffe61be604bf3dc698b9d966cade0add555ffa13ab91c96cbb76ed62e7cf9fdf43b367cf3ef7c5175f78ba9cfac5fe2f6cd62e88828a65f13c25c0595d09542b95cceeddbb212020007c7d7d7bc8c7c7e7b2bbbbfbf34ebbc7bcf3e0a33ba25eb992d8f70330ace8df692e9b1703478b7300dadaec00782784799be7815b9c1b676e070a0a0a2a78f7dd77ef7573737b468a871a60b6e733513ba35e818d612fc111b50cce5768a15f983fcc9c311d4a3233e1427d3dfc9c98c8e6e4e4c07d89f7c1dbd96fc3a8ef47c1f6eddb61c78e1dd0b76fdf8b090909c67efdfa31616161b154e6833e7ef4c96d112f1fe5008e6995f688372f5902512121d0a152c1711cb7cc8d1b01b71d4c2a9b64875893b70648461213138fa1794dfffefd01c54645458da102581df8c26a62ce07e0646b6981530a851d60f5ead5c4b48770f7d77b7b7bfb1180e8e8e82db43764c986d017cbfe0ee05c6d2d5cd268ec003366cce00390516c0c0f0f5f4c007af7ee5d4dfa800640bc2ef8c5744719384300366d62478d1a05a40fba03e0430b8bb5070240141717b792aa0433dd9f76db11f98a8d0fd05d6c6b2b54cae56c76763631e503407c7cbc2130303018cd777dfdf5d78f53df8a17fa3cdb7f7bc4cba7ba03301879bbc904c770024e3637c37eec7834204d4622be826fbd2c07803f5b2e72f584bdf1c0fd13be7e32fe54b9e92417f9653437e3fb40c39e3db067c10216f73eb36edd3a06cb6037479155dcfef9e79f3f2cd87361555e5ec4a5c64633bf0cdc22ea2ecc8265e7ce9dfe22a1cfe4a143ef32ab54532e363434f10038e30e9cffdfd650545424c8404bc0c4c4c47664cd1a83c7274ec41fdeb62d0f58192501a3c04c5e5e9e8d1cf30084683c77e1e9adc80000000049454e44ae426082", + input: PNG_HEX, expectedOutput: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000208000000000000000000008000000000000000000000000248000000200240000000208908000000200240000000200821000000200240000000061249000000240000000000209b69000001a49b00000000a204a1200001a49b00000009800414000001a49b0000000035db6c00000094924000000086dffc20000df6dec8000001e10014a0000df6dec800002564924b00000df6dec80000009a6db20000007edb4124804177fffba0002fffff69249044e0924bc4002fffff6924905fb2db6d04002fffff692490416d2490040001bfffcc92030dbffffdc00037fffffdb6d302c6db6d700037fffffdb6d327eb6db6148037fffffdb6d30db4000014800dffffeb6d9aefffffff640", recipeConfig: [ { @@ -212,7 +213,7 @@ TestRegister.addTests([ }, { name: "View Bit Plane", - input: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000449494441547801cc9703782b5914c783b56ddbb659db6e9f6ddbb66dd45e6fddc6aecd24cff67b99397b6ebe9d6216d99bcceebefb7dffbaf9ff0e7347e4e491eeddbbf7f5bcbcbc41b9b9b943376cd8f00ef9194afcfb67094ac0d3ed85870d1b764755555592c562616a6a6a18ad560b28b6a0a0203b3d3d7d4e494989fed75f7fdd45fe5e10e38c8c8c0f2a2b2b7737343468ebeaea8a516aabd50a441c00278d46c392cf2a95eaf475d75d7767525252505656565f67332296c9644330d2cbc48c2f3e005f656565ed08c410656666c653bb63e4ef9acd66ce9c0a8027164b430d20aea8a8d84e4c5c05c02c1ebce9a69b6e27af49d5e5f5f5f56a4700b5b5b5ac0300ae1cad3ffdf4d3321a0809365bc93f007068cea9b8b8584e35197abd7e8e5019c032983103aba8ca306fdebc07dadada2c02f4c0a15b6eb9e50ea746313535f5ade6e6e63a57008870170c14397b9e7cf2c97bc838d20294969636e30eb0a1181ce9de2217ce2d087089060037e139b1587ce7fefdfbfd30fa3ef4e9771140a1501cc3ffbb91deea2a05b8991640a9541ec5ffbb5e2800497272f20f7880afad5bb73273e7ce05bea64c99922ee49de07a9d4ed760341a812fbc9030696969c0574a4a8a11ffef5a979d5fbaffe61be604bf3dc698b9d966cade0add555ffa13ab91c96cbb76ed62e7cf9fdf43b367cf3ef7c5175f78ba9cfac5fe2f6cd62e88828a65f13c25c0595d09542b95cceeddbb212020007c7d7d7bc8c7c7e7b2bbbbfbf34ebbc7bcf3e0a33ba25eb992d8f70330ace8df692e9b1703478b7300dadaec00782784799be7815b9c1b676e070a0a0a2a78f7dd77ef7573737b468a871a60b6e733513ba35e818d612fc111b50cce5768a15f983fcc9c311d4a3233e1427d3dfc9c98c8e6e4e4c07d89f7c1dbd96fc3a8ef47c1f6eddb61c78e1dd0b76fdf8b090909c67efdfa31616161b154e6833e7ef4c96d112f1fe5008e6995f688372f5902512121d0a152c1711cb7cc8d1b01b71d4c2a9b64875893b70648461213138fa1794dfffefd01c54645458da102581df8c26a62ce07e0646b6981530a851d60f5ead5c4b48770f7d77b7b7bfb1180e8e8e82db43764c986d017cbfe0ee05c6d2d5cd268ec003366cce00390516c0c0f0f5f4c007af7ee5d4dfa800640bc2ef8c5744719384300366d62478d1a05a40fba03e0430b8bb5070240141717b792aa0433dd9f76db11f98a8d0fd05d6c6b2b54cae56c76763631e503407c7cbc2130303018cd777dfdf5d78f53df8a17fa3cdb7f7bc4cba7ba03301879bbc904c770024e3637c37eec7834204d4622be826fbd2c07803f5b2e72f584bdf1c0fd13be7e32fe54b9e92417f9653437e3fb40c39e3db067c10216f73eb36edd3a06cb6037479155dcfef9e79f3f2cd87361555e5ec4a5c64633bf0cdc22ea2ecc8265e7ce9dfe22a1cfe4a143ef32ab54532e363434f10038e30e9cffdfd650545424c8404bc0c4c4c47664cd1a83c7274ec41fdeb62d0f58192501a3c04c5e5e9e8d1cf30084683c77e1e9adc80000000049454e44ae426082", + input: PNG_HEX, expectedOutput: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000140494441547801c5c1416ea3400000c1ee11ffff726fe6808410186ce26c95fde0432a154f0cdea4b2aa505151519954ee1a5c50995454aea8ac54ae2c5ca8982a3ea132551c199c507942e58ec1898adf50f1cae084ca15952b2a152a47067f40a5e2c8e00f54a81c199ca8b85271a542a5e2c8e005159527542ace0c5ea8a8f844c54ae5ccc217555c197c41c55d83ff6cf0052a772ddca052b1a752b1a772d7c2432a4f2c3c50f1d4c20b2a1593ca918a4965afe2cac29b2a562a93ca56c55d0b2754b62a269555c554b15251a9b8637040e5884ac54a654ba5a2624be5cce040c5918a55c55ec5a4a232a9549c197c48655239523155bc3278a862af624be5ccc2072aaea854a8549c5978834a85ca5ec5918a57ec076f50a958a9546ca94c1557ec071754a68a2d958a270637544c2a2abf69e1a68a95ca54b152a978d73f2e08bd57b6f839a00000000049454e44ae426082", recipeConfig: [ { @@ -231,8 +232,8 @@ TestRegister.addTests([ }, { name: "Randomize Colour Palette", - "input": "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000674494441547801c5970394244b1686bf44b9aaddd5fdfcc6330f63af6ddbdea3b56ddbb66ddbdeb16dcf5497d219b137f3d44363ba7b70cede73be74c6fd6f4454e45ffcbfc398ecdef7bef7bd35c562f1c59669de0fc32818467a590ec7bca635bab38fe27823b0278aa29f3cf0810ffc12a02e4680f9fdef7fff1903d5eaa766cd98412e9f2793c91204216118c83e052509b3d96c4aaeb3775d07152b1a8d3a478f1ee5452f7a5101f0384fd88b172f666c6cd8b0215f2e973fb576f56a40e37901be248ce34888514a9192542edcfebcb7a7977a7d844e70e4c891d2a402e401c6c6631ffbd82b92864dd3948ac3b4f1e4bc13c91008a6a0097c1fa7dd927d20421d9acd16beef1fdbba75eb8f5ef9ca577eee6286c010867ef5ab5f1dbfd7bdee858c2569d7cb5ec4488206b55a8d76bb8de7ba64b2198af9025ddddd5c71e5951cd8bf9f37bef18d4f9121fc0f705aa80bc1797b80f1a11392ea034968c8be561be1e4a913d425719ab054a6af7f003b63532a1629e4f3140a058a42d25b3367ce6c02870467aa1eb09938a2fffef7bf6f035e8661d85ac3cd37dfcc82053726e39c56ef380e511c89400bd34ab001b06c9beeee9e00f0264f3eb900f7e52f7ff9e7819f0995bffe6bddcf77ef3f8c8a0fa20123c1209d1771ace47a9cce0b3b63093656363f6a782f4680271c13ce093dcf7ae09d9ef8f47bf77c05a5c964f2686c1a4d9f43474e72e7bbaf65c5da9b3876ec0c9ff8c84fe8abf4b1eff4a118d04c234c260e25381d012756cfee5b15eb1c37ad5c4dbe7b8062ff20f778f0bd78c7c7dfc4fd1e716f8add7dcc98338365775a8c952bb260c6d58f03cc4b1030fa996ac57a96e318acbecb1a9efdba17f28ce73e8585cb1612470aa7ede17b3e9e1771e59503f8a14339977d1490bb1c028c27ace85f6d59e41dd764efcebdd07668b59c74127a92d8f7935531220803dc769b4ac10243171ebf727035605caa804c7fd1783268c2c0e2f73ffb2b5aa9643de82ccb091191ec93c9b86de35e72392bfd290e96cc2701994b1590b550cbb58a29e6234e9d70d9b3f3202a124191240f2479140a8a53c7ce51cae4b06d489eb78c782590bd6401b6a517a838c0204c1bffcd0fff045aa7e31f45b1a0e43466e3bf77808e8845905221b188b81c3d600611bb6215a1421fad7cf6eed8cba986471448a2385d9ef9f7e6bdd4ced688635f0404c46180a8b0a633076c260fe587d131db30e606848045fff09558a6c5f68367f0ddb6ac05a769b49a682d4f784e2a00342d37da04e84bed81e0137f6f3ef7f499c6df5b5ebc1b2b878a5c4c4333dc57c1360d8a390b4bce5bf5b3683343aee70ae7ecb9e696afad77df080497e2880032af7ff3dbeef8d0873dfcb5f3e6cfbb5bc182fffee8ad74570cd0a41f2ad334049346bdc1cd0f78335e0c070f1e3efbef7ffefddd4f7afc63de0f041723c0f8f297bf3c7be1c245df5db850be429d38f09faf523bb20ed3ca25d96fb366a929f1c915079877f797a6823ac6c6dbb973e7ddc45ffc13d0d31d02e3339ff9ccbc952b57ee4a92bb9e475daa6b341d8ce23544dac269d5709da6d0c2711ab49373d7c7ee992bcfd68526c97be2b6f2c2dfa598b58031dd1ec8feec673fdb70bffbdd6fc1b9da48faf93520add8346d4c3bc7b9037fe3e8a6efe33b67b0ed3cc3f3ef4b75eebdc1b2d17188d6f1adcea9afb7873ffce10fe1ddee76b72ec09b8e80ee75ebd68d2c59b2444cc8e9d10ef8162b264252e418345a451d5472065a20d96986aa83ac5fbf8eb7bef56dd701871813f6231ef1083ac177bffb5de3ddef7ef74ab1e2a9058b22459a7f5c244e2915031d630aa374269705952ed9625058b66cd9bc57bdea5547c69a145b928e3aaf56ab6b1301a9ed56112332a67d3d3da831494c6db26bcf1e868786e8aa54c4fd1e1e25a0d56c33343c4cb9524e2ddb8c19331e08fc4150934d42bb542a2defefef97065ae947a53e524f7a6394fd9663418112525714b362c50a962f5f2e7b418ed7ac59239577e3b5db744b01f97c7e39909d6a25cc4af5cb054e9d394bac54cae12347a94895e57209cbb268b7da341a0dec6c8eb3e76af84198625a26ade45ebd91bae96a7520494c75a88a14b614c84c25c0ce66b3c3406a322ccba4bfaf174f8e1bcdc6a83f1c32395314506fd4d37b1dbf28490b527d05dbce10851100b95c2e0fd853fd0a06befded6f7fbfb7b7f78e69825b67fe6d8f1a13bda9c71fca308dfacfa8b46ec9ff8c59c0a9c90454846b8501c1e6f285166ac27e6164b2217085431d9506973702a1cd98f81f11b2640d65786ac70000000049454e44ae426082", - expectedOutput: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000007ed494441547801c5c17b5c0d8602c0f15f9de3d16425a113999296348f3c0b75ea4e2b5be7a05bd46a32c99b5496477266d494ac97508a0e494848c2525e87bc95ccb31145915e3abacb38f7b6cfdde7d3a74faafff6fdaa59c81254fc8384b42179b40501455ee84476617b920eeee33e6742d7c994d685d15c9ac31ff85f5c4386b13ada4b0268a2597c8dc7fa72da23e423ccfca67221fa32f29dfe1c59b08ef4c4459c7a5acc1e130396d5aee2f8d8092c105ee7f9a91a6e6db6a6c4d3893e96b318aa1b41b7aa0822cd156c1aa5c39b2e0f698b7097d36b5af2caec499cc29dd409bd389b578ea66f10569394fc229b89f7fd2f890bbdcbbbeb83c8511b8acbc67b6cad39c7c691f7e81ceb829eb12deb6de740247f912e1c465b84d285c368c92150c68f338e31784e11c3924e522281d50a0156fdf84bf27a1fa2c4de7cb3d79dbdd3ab916f90a2b4ec45e3e6159cb54fc6c8741fa3b48a703e654e0f872ada2230f216cb348cebd030ae43c3b80e0de33aca2a2c30cc37a5d7c89714780a11de84dda24914ae28a5617b209f0f4e22bba03bfd973930a1df22ece73ea1dbe30d8c9ee48455e925a2d39dd861fa968e1088c41219ad1873b89e5137bf66a465029b46f461aaebf79cad7c4e68f0262aabba503ec09123e3b7a319e6cbdefe12385e485d5d0fe4d21e7c2bb047d1e94b3a429d8fb0d64de39cff1172f213581aea8f32eb2ebaf23bc85f6be2e1b5859af4a5680c9d4df046299551c9ec58ed49935d3f9bf04a2d8b8e1288c41219ad383ebe3f771475dc30f88490e1f7e82c8c62f34007be8e53e026b5c4c3a11b03ae6f657abf4944e8fe4efef3293c689c8d87961e11db9da91beb4847084462898c76e48499b243438fead0183e645660133886d3ffaa65acc0971b0113c9add4a3583b1c9f05b5a46c352447bb2f5a867de908753ac03f478bb26b9f52e4f88642e712b47cb7b122f4097ee5d5788cc8e2e8e20a4c94cf5962fa03e9257339635d4e47a9d30195dade841c9273d5408731bdcbf139b983d8de57393d2f908c992ed49b6c6474a101f1c11928dc8ef066ed753a4a483b740f34703fd38c82ada58c7c358f17c77ee2c98aa7acf9598df57ebfd0b93a8dfc3333c82aafc0e1e518968f49e7495e2e6a411fe8ba5e417bd469c79463eef8c54f63d76173a24f9f40b955c989dcb7f867bee7b33c29fd97b8e09c771de5ae5a9c4bd7d15747cae8ea30065ebc4d47086987b6cd34eef4aca56be65bfcc3c6312fab37bb2ec5303c64177d621c18eb25e24ef71ea41e0c216250000d9e525ef7d065d0d628ca3a4da73d02915822a30d1a29c398ebf12be1a5f3d1093a42df9709bc4a6e60d07721945c3d84a47b118a803c0483aff02e3a9eb74356b2283688ec05f6bcf94d8ff6a8d38ebb353ac4fe618ac53d57ee5cbd8874f26d2e9d8ec3eebc2b8ee163f1591bc3a0e25282b639d14bc305a7c652f20b37a06bb8878e50a71d8eff598d4cef2056dd8cd896da8537aebe6cd3b4e3c1706b2a53f5315d1b448d5a363a669fa2f2d442392198f8fe539816ad4e47084462898c36dc2cb4e2d6dc2f181b5241cf47f1147c178db67b19911e4fd1ba3c9e9f728e7241ef393766ca091a974145891ca5d88751920cf21555b44720124b64b44112f135a9053739693e0a3dd3f1684b5c392f4a24cefb027aef0663be3190c64867ba769acc90f43ed8c4a450239b43f5aa069e7656d11e753e62ffd52c94b646f49b7b1fcb3001d6dfbe6375d5778cebfd16cbc453b8669dc66e71144b8dc55cb7fb8a4b71fa1cb55d4279843e36cb2d18aa32e2135b7f027cbc688b402496c868c1cd620259ba4370b9aacec0a06c1cbfe8c2b08614a2b5df5353e14db0db441efa2e4623f92835c92bf18df56464919440d52c56b113b7ec4d686fd1e6b31d6b5813b6946335c51ce86b426b0422b144460be10633a9bff56ff236dee7878bc94c0e7d48a3d10d82baf664f45e3f7627a868541c47f9bb883d665ff15a56c5a36c2f54f16e6cb8a0497d4d29c2a365ecdf2ec2eb81132b0627a0fa7322ad11d28a5986a94c038cc2d7121da5e026ffa380a4862c0c0fc552231f87fcad90facf0229f23ac9dcc2482aee66919462c1a188857caf914813a3f0f1c03e9e8913c8ea398bd6a85d7bd85fc5fff9a4ace19c7e236689d964e858e26d9946c172335ab2d9ff827a83e1bc5fe8c78cf70dbc59684373f1ebeaf009fe940d3eb67cf54087dfb65c2379ea3cfc2ebfa725350b59828a66242bed51793b53f5a29ea84e3d89f2ddc4a4158598e9c969ce35ad8cf9f9fdb8bf3a86dcd35389720ce66fa22d2202a507099b338078fd18cc3ba961305f972901beb424108925329a99b5e021eb96e570f4543051b955ec769dca3c074b164b8d78f4e3532eb9f720b1fb5224a5d6ccd73d4892e609726a63095ee9c39e705b94cf26e3f3a18eb2ea7378561af0f3950f6cb1abe151cc455e5dba474b02915822a319ffd9c188cec8499a2a20c4269ebbb9ae7c1b684556c40786767bc6fdd05b4c1c6a49491739f2dc13d8efb62661531acbc6ebb1ece57ee6ab7499257067e7f2e92cb1d267709f517c73db8d068fde3cb1bc474beab4b0d376274df68d9b89dedd3b0ccc48648fc93374970e42651c878be1af8cd83986cd7602940557386babe0855a19b5ef42e86df788b3227b4e2c7362f3a248a47f1612e1349f26e71f3ca6356a16b20415cd445d7984225d4c695d1887334d386f664f9c7d3ff282dc68f2a7cf019a180d5cc4df7e2f8ee56fc278179a1cb00e67e26fa798e2f48034873f280ed1447cd98596d42c64092afe41eafcc3fe0b9c67148a38c1a5620000000049454e44ae426082", + "input": PNG_HEX, + expectedOutput: "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000004f3494441547801c5c10b50cf0700c0f16fbfff8f0ae5f157ed9f1e446358ab28b3913f29b3f89f65deab9859c624cafbf557b6eb3662799c8a285c541479ed3c125d2d2cba52e45d4da8bc66b99d1ebbff6ddd75ddeff7efef75fb7c8c5cb5b10dbc869ccbd1ac4f0c67dfc55cba1f9ec32dd303bc0e854aadd1f20ace5f29e1c9346b4c3982aada03b3285b540f4b099f664ca5720321a34c582466b2f38f3e1842a1526bb4e811efe64a56403a465dc270a998cb517b47e62f7842870b6aaabc5b519627a253784e606a8e25470fbbe358a0c2fd692f9c9668b8bda084e77d5f2247448f790f42a9b9da915d415a6020508a3e49e207e8ec7961cb9594545657e5e26e0fdaf9df5014998a141119f16eae24b4db84f7d775bc8e3e3e9e24f12fabaccf282210292232ce6a5e12dab58e37656be7cf8893916498d72345404681d7365ae217b18b969495261019998f8569145204e47c3e99b7a58f8f278fa76e478a808c522f23de165b3b7f3aee9c8e14011956e9b6841c29419f5d8bfd6889ad9d3fc1c9c654be08428a808cfc9a0c02e7d711973a823751569ac0c79dd72347408fb9ee3d102f4c616d9c82579596dd8df1b5c58caf2d26625d2fe488b420b16c129e3d7825534ccbb01a3881f0803354adba49c5853ce488bc037ba66b48c93586e20298885e02ff338177c0a1ed600c256200973699b0f130cd9dafcd20c87a3bcd9d29d90b1462081103c4d444d1bee2139aab9b7c87ec50479adbd47f13a0c610227a94af8a6565ce118ce72dc1618d3b4ded6f678465840dd905bd519f3e455305e67eb4f1db8ed94fdeb444448f0dbb94740bcec029db9fa636fc99cbf176a708b9e44198af3573469b323cb992469694b031bd133b2a955cb2a8461f0119a3b6f810fcac81619ea1c42cbf43a3711393d8727b1ee37ad6a263b1388cc8a872264cc8a7d1c97116d407ede1ab9c44ac3de610e5f32372142ab5468b84d091d984d79a90147e8dfb8322e8bcf71cdf370ce07ae6158606ee479c164c8794ddf88f76664c5d3d96579ee171db85d9917524b996102e2e65d882753c4c28e690714f9e3ffa1b2902122a0e6571a3c8864657b304ee2e4d6579e1038e0879cc0c716765c67ec2ee1d63cbaa9154db0760ffcc8e0fd7f643d3ba9c31ce69fc3c68124507bae060eb8379dc45e4884850aa4730ca2e97e68a572ca178055c7ff411cb56c4002bf86ef6717c53f94f3c3a4ff72590d6fa09ef134ae0a983ec1efc2b720424fc55b8107dbea8fe81134ecee8687c4d68ae62de45bc636ad099782b126b8f39c81190b0f292127d5295cb98f2b415aa2a055dcb2fb035b081a686f48ee5f4d37ee80c9d91498855007204240cc9ea89efeabec871ec5443c381b1980c9a4f456d1233a38d68ce667c2ee7c2927019e1ce8bb84ce48848f832d10bb1f50dd6540d03d268d4677d39ed1d52514407d3b6d8830327dc49b0984574507b3a3b0573fb5806f762afa37379790e7783ab0849ee0f66fd91a350a9355a24d4bb754239ca02df597598d52dc5c2bb339503cde95213cff3a089240d7f48fd522f9c943eec1db088e53b0412631ea193dec188e4b3a7d9d6eb535a62e4aa8d6da005bfe4d9125de082dbcd6f69ca6ecc66c2166ca329eb198ee4bf5780a5ba3b861030c05cd732eea4acc3c42106671f0d52ac6738727064325b8ff5c752dd1d4329546a8d1603bc2c51f2bbf3356eae2c64b379374c964561b5f53c36d65e14fd3683c7f7179232d686bdf9777915ff00ec08ae8ecb66a3370000000049454e44ae426082", recipeConfig: [ { op: "From Hex", diff --git a/tests/operations/tests/Magic.mjs b/tests/operations/tests/Magic.mjs index 28950f4e..3ae143d2 100644 --- a/tests/operations/tests/Magic.mjs +++ b/tests/operations/tests/Magic.mjs @@ -7,7 +7,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; - +import { JPG_RAW } from "../samples/Images.mjs"; TestRegister.addTests([ { @@ -22,9 +22,9 @@ TestRegister.addTests([ ], }, { - name: "Magic: hex", + name: "Magic: hex, correct rank", input: "41 42 43 44 45", - expectedMatch: /"#recipe=From_Hex\('Space'\)"/, + expectedMatch: /Properties[^#]+?#recipe=From_Hex\('Space'\)"/, recipeConfig: [ { op: "Magic", @@ -33,8 +33,8 @@ TestRegister.addTests([ ], }, { - name: "Magic: jpeg", - input: "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48\x00\x48\x00\x00\xff\xdb\x00\x43\x00\x03\x02\x02\x03\x02\x02\x03\x03\x03\x03\x04\x03\x03\x04\x05\x08\x05\x05\x04\x04\x05\x0a\x07\x07\x06\x08\x0c\x0a\x0c\x0c\x0b\x0a\x0b\x0b\x0d\x0e\x12\x10\x0d\x0e\x11\x0e\x0b\x0b\x10\x16\x10\x11\x13\x14\x15\x15\x15\x0c\x0f\x17\x18\x16\x14\x18\x12\x14\x15\x14\xff\xdb\x00\x43\x01\x03\x04\x04\x05\x04\x05\x09\x05\x05\x09\x14\x0d\x0b\x0d\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\xff\xc2\x00\x11\x08\x00\x32\x00\x32\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1c\x00\x00\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x07\x04\x05\x00\x02\x03\x01\x08\xff\xc4\x00\x1a\x01\x00\x03\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x05\x06\x03\x02\x01\x07\xff\xda\x00\x0c\x03\x01\x00\x02\x10\x03\x10\x00\x00\x01\xe7\x14\xd4\x6e\x92\x6e\xe0\x67\xd3\x01\x2e\xe2\x61\x94\xcc\xb8\xa2\x6a\x9e\xa0\x8a\x71\xfa\xde\xdc\x52\xd3\xd5\x89\x16\xe1\xbd\x57\x6b\x4c\xc9\xc9\x02\xad\xcd\x3f\x3d\xe3\x0e\xfc\xcd\x61\x95\xe9\x08\xa8\x74\x05\x4e\xc3\x14\x07\x5d\x62\xc5\x22\x57\xb8\x0f\xbd\x49\xd9\x50\xd2\x6b\x46\x3c\xe3\x8f\xa1\xd5\x83\x2d\x27\xa5\xbd\xf3\x24\x99\x82\x11\xf5\xd5\xf3\xf0\x05\x8f\x34\xbc\x16\xa5\x83\x00\x74\xaa\x86\x66\xb4\x8e\xf2\x89\x13\x88\xd9\xe2\x16\x56\xe5\xb3\x4a\x8c\xc9\xc9\x61\xa1\x95\xa5\x1d\x7e\xb8\xa8\x67\x65\xf3\xbd\xa4\xa7\xff\xc4\x00\x21\x10\x00\x02\x03\x00\x02\x02\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x04\x01\x02\x05\x00\x06\x11\x12\x13\x14\x16\x21\x24\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\xd9\xa5\x49\x5a\x1d\x6a\x39\xf8\xfa\xd5\x03\x98\xe6\x61\x44\x16\xa2\xc9\x82\xb4\xbc\x97\xae\x9e\xe4\x63\xec\x33\xd6\x24\x4b\x29\xa4\x98\xad\x5c\x4a\x68\xae\x4e\x5e\x41\x3c\x3f\xc8\x20\x0c\x4b\xc8\xd4\x42\x34\xb8\x7c\x2f\x3a\xd1\xea\x3a\x36\x19\xf4\x4d\x42\xd9\x41\xe9\x02\xc5\x8d\xbc\xd1\x45\xeb\xf5\x12\xcc\xb3\x9b\xc0\x8b\x17\x23\x99\x8e\xad\x9a\x67\xb7\x46\x65\x35\xd6\xa5\x9c\x81\xf8\x8b\x5e\x9f\x2e\x83\x4c\x35\xcd\xb3\x83\x45\x1c\xe1\xd9\x85\x35\xf3\x1c\xd2\x73\xad\x3a\x1a\xbd\x67\x87\xed\x89\x96\x96\x79\xb6\x11\x45\x9c\x9e\xb3\x03\x9d\x0c\x77\x06\xf2\xb8\x9b\x9f\x0b\x5a\x42\xaa\x4b\x58\xa4\xf6\x14\x45\xf4\x3b\x1d\x2a\x4c\x6c\xe5\x82\xba\x7d\x8f\xf9\x91\xcf\xa5\x46\xa6\xbf\xeb\x12\x0d\x7f\x1f\xff\xc4\x00\x2f\x11\x00\x01\x04\x01\x02\x03\x06\x04\x07\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x04\x11\x12\x31\x05\x13\x21\x14\x22\x41\x51\xa1\xf0\x32\x42\x71\x81\x23\x24\x52\x53\x61\x91\xf1\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x01\xbf\x0e\x98\xc3\xc0\xfb\xa1\x19\x71\xca\xa8\x5b\x5d\xed\x73\xd3\x38\xe3\x98\xf7\x35\xad\x1a\x73\xfc\xa7\xcf\xda\x7b\xce\xf1\x4d\xb0\x21\x69\x0d\x0b\x4b\xcf\xce\x54\x5f\x98\xac\x1b\x28\xdf\x1f\xd6\x56\x98\x23\x9a\x37\x39\xbd\x4e\xde\xfd\x17\x16\xae\xd7\x5a\xdf\xa1\xea\x9d\x0c\x6d\x6e\x85\x2b\x66\x2d\x0d\x8c\x74\x5c\x2a\x06\x13\x87\x0c\xe1\x3d\xa0\x38\x85\x74\x4d\x5a\x00\xe8\xc6\xdf\x4f\xa2\xb1\x62\x6b\x04\x03\xd7\xc9\x43\x34\x92\x3f\x4b\xdd\x9c\xa6\x70\xfa\xad\xf9\x7b\xde\x6a\xd5\xc8\xe0\x7e\x83\xb8\x50\xdb\x9f\x99\xad\x87\x01\x3a\xce\xb7\x17\x13\xba\x3a\x2d\xf0\xf1\x8d\xb4\xfa\xff\x00\xaa\x0a\xd6\x2a\x1e\x7e\x94\x6a\x56\xbc\xe6\xcf\x19\xeb\xef\xd5\x5d\x12\x4b\x16\x23\x2a\xd5\x52\x23\x2e\x27\x38\x5c\x3e\x28\xa5\x92\x31\x27\xc3\xe2\xb1\x18\xe8\x1a\x14\x1c\x4a\x0a\xf0\xb7\x4e\xe0\x6c\xac\xf1\x37\xd8\xee\xe3\xba\x9c\x49\x87\x9b\x0e\xe3\x65\xda\x6c\xb2\x42\xf2\xed\xf7\x54\xa4\x80\xc4\xd9\x2c\x63\x27\xcf\x65\xc4\xed\x40\xf7\x35\x91\xbb\xa8\x59\x72\xbf\x15\x53\x8e\x46\xfe\xfe\xcb\x46\x32\x15\x2c\xb4\x38\x65\x5c\x8f\x97\x28\x78\xf1\xea\xa4\xa3\xda\x86\xac\xe1\x4b\xc3\xa1\x90\x08\x88\xc1\xf3\x43\x81\xd2\xfd\xc3\xe8\x9d\xf1\x39\x40\x01\x99\x80\xf9\x85\x60\x72\xec\x38\x33\xa7\x54\xd3\xf8\x79\x55\x09\x70\x76\xa5\x6f\x67\x95\xce\x93\xf5\x15\xff\xc4\x00\x2f\x11\x00\x01\x03\x02\x03\x06\x05\x03\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x04\x21\x11\x13\x31\x05\x12\x22\x41\x51\x61\x71\xa1\xb1\xc1\xf0\x23\x32\xd1\x33\x81\x91\xe1\xf1\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x01\xd9\x04\xef\x90\x2c\x3d\x4e\x1e\xca\xb2\x67\xc2\xc0\x19\x70\xa4\x95\xc6\x1e\x23\x74\xd9\xef\x8b\xee\x70\xbe\x9a\x76\xfc\x2a\x9a\x82\xe9\x4e\x04\x80\xb3\x09\xb3\x8e\x3e\x3e\x48\x6d\x9d\xdb\x64\xb7\xf8\x51\xc2\xd8\x2b\xfe\x96\x83\x1f\x45\x0b\xf8\xae\xab\x33\x62\x95\xed\x6d\xef\xeb\xa7\x9d\x94\x59\xd2\xcb\x8b\xec\x42\x73\x23\x67\x2f\x9c\x96\xc9\xa5\x8a\x79\x1c\x65\x18\xf0\xd9\x09\x48\x18\x0f\x45\x43\x4d\x9b\x2b\xa4\x71\xd7\x45\x2e\xfc\x2e\x31\xcc\x6c\x54\xad\x8a\x30\x66\x2d\xd1\x06\xc4\x00\x99\xfa\x15\x56\x59\x39\x73\xe0\x1c\x3e\xea\x16\xcf\x01\xce\x88\x1b\xe9\xd1\x3f\x67\x4a\xf7\x17\x11\xaa\x86\x4d\xe3\xbc\x3a\xa9\xaa\x29\x6a\x1c\x23\x79\xfd\xd5\x7d\x29\x7c\x6e\x11\x1c\x07\x44\xfa\x82\xfd\xd1\x26\x16\xeb\xa2\x64\x9c\x43\x28\x6e\xe2\xa1\x9c\xc4\xe9\x1b\x25\xc0\xbf\x6d\x7c\xb5\x42\x68\xb0\xfb\xbd\x11\x95\xad\xa7\xc8\xe6\xa9\xa9\x44\xd8\x1c\x78\x8f\x92\xa7\x7e\x55\x66\x4c\xda\x1d\x7a\x76\xf9\xe2\xa4\xa3\x8a\x46\x6e\x39\xbf\x31\x54\xf1\x06\xcd\x23\x59\x89\x23\x9f\x8f\xf7\x8e\x2a\xbd\x8d\x8f\x8d\xd6\xd2\xc8\xe4\x63\xa9\x55\x55\x70\xc8\x04\xad\x07\xba\xa6\xaa\x19\x8d\x7b\x6c\xb6\xa3\x9b\x23\x98\xe0\xdf\x9e\xfa\xaa\x08\xc1\xa7\x11\xbd\x45\x3c\x9b\x29\xfb\xae\x18\xa3\x2b\xaa\x5f\xbe\xe3\xa9\xd3\xb7\xfa\x8e\xcd\x18\xd9\x3b\x90\xef\xf9\x54\xc4\x87\x38\x8e\x40\xa9\x1e\xf7\x81\xbc\x71\xb7\xb2\xd9\xd2\xbc\xd8\xb9\x48\xf7\x1a\x9b\x9e\xbe\xaa\x8f\xf5\x23\xf1\xf7\x47\x55\xff\xc4\x00\x2f\x10\x00\x02\x01\x03\x02\x03\x07\x02\x07\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x00\x04\x11\x12\x21\x13\x22\x31\x23\x32\x41\x51\x61\x71\x91\x33\xf0\x05\x15\x42\x52\x72\x81\xb1\xa1\xff\xda\x00\x08\x01\x01\x00\x06\x3f\x02\x4d\x71\xf2\xc8\x74\x97\x23\x97\xd0\x1f\x9a\x4b\x62\x0e\x95\x50\x4c\x63\x65\xd2\x69\xa5\xe0\x17\x94\x12\xe3\x9b\x53\x1f\x21\x4b\x24\x7a\x56\xed\x54\x1d\x12\xf4\xff\x00\x95\x1c\x57\x3c\x27\x98\x13\x92\x17\x6c\xe6\x99\x63\x0a\x90\xb0\xea\xa3\x07\x39\xde\x9d\xbf\x36\xbb\x19\x39\xc6\x05\x42\x67\x71\x3c\x93\x91\xac\x28\xdb\x3a\xaa\x07\xe1\x2c\x4c\xd9\x8f\x5f\x4e\xa3\x1b\x8a\x33\x63\xe8\xe7\x58\xf4\xf3\xf8\xa8\x73\x20\x3a\xfa\x11\xb8\xac\xb3\xa9\x45\xc9\x5e\x7d\xab\x07\x94\xe0\xb0\x22\x97\x55\xc2\x83\x8d\xc6\xa1\x56\xb6\x82\xec\xdb\x88\x70\x57\x4c\x7f\x53\x02\xb8\xd7\x40\xf6\x03\x66\x3d\xd6\xf5\xac\x22\x95\x4e\xb8\x5e\x95\xa9\x53\x97\x57\xd3\x45\xf5\xa6\x78\xad\x9c\xc5\xfb\x54\xe9\xfe\xfd\x29\xa0\x96\xe9\x4d\xc4\x6b\xd3\xc4\x7b\xd0\x4f\xdb\xb6\xf4\x62\x90\x88\xe5\x83\x1d\x5b\x1c\xc3\xd6\x83\x7e\x22\xdc\x18\x50\x03\x11\x55\xc3\xb1\xf3\x7f\xb1\x53\x76\x41\xb3\xe6\xdd\x3c\x32\x2a\x49\xa6\xb7\x6b\xce\x1a\xe1\x44\x60\x64\x93\xef\x5d\x94\x26\xd2\x72\x46\x1c\x91\x81\xbf\xd8\xa5\x62\x07\x1e\xe0\xe0\xe8\x18\xd7\x81\x9a\xe8\xc3\xd3\x02\x96\x6e\x49\x84\x8e\x18\x37\x9f\xf7\x49\xca\xca\x9a\x87\x67\xe0\x7d\xea\xde\xe4\x8d\x06\x16\xd5\x86\x3d\xdf\x03\x51\x49\x12\x34\x90\xe7\x02\x42\xa7\x07\xcf\x7a\x71\x15\xbb\x5c\x5a\xa0\x05\x94\x0c\x8c\xef\xb9\xfb\xf0\xa2\xef\x6c\xd2\x28\xe5\x17\x19\xc2\xc4\xd8\xe9\x83\xd7\x3b\x6e\x28\xf6\xac\x3d\xa8\x8b\xbb\x6e\xcc\x6e\x22\xea\x99\xf3\xa7\x9a\x2b\x45\x8d\x8a\xe5\x4a\xae\x9c\x7c\x55\xd6\x26\x26\x44\x8b\x05\x41\xca\x82\x4f\xfb\xb0\xa9\x97\xaa\x89\x0c\x40\x8d\xb4\x8f\xbc\xd4\xb1\xc2\x99\xfd\x32\x06\x3f\x18\xab\xbb\x9b\x7d\x1c\x69\x4e\xa7\x8c\xf7\x4e\xfb\xd1\xc4\x7b\x7b\x1a\x80\x1d\xc7\x1b\xa1\xfe\x55\x74\xac\x03\x29\x2a\x30\x7f\x98\xa6\x68\xa2\x48\xd8\xb9\xc9\x45\xc7\xeb\xa9\x38\x5d\x96\x48\xee\x6d\xe1\x50\xba\xa8\x57\x6d\x1a\x98\x0d\xcf\x66\xb5\x70\x06\xc3\x82\xdf\xe5\x77\xdb\xe6\xbf\xff\xc4\x00\x22\x10\x01\x00\x02\x02\x02\x03\x00\x03\x01\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xf0\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x21\x10\x32\xcf\xff\x00\x55\x6d\x07\xd7\x39\x55\x4c\x4f\x10\x53\x39\x7d\x17\x25\x21\xb4\x98\xf1\x0e\xb7\xde\x3e\x30\xd6\x2b\xcd\xeb\x1f\x75\x91\x1d\x35\x56\x4e\xce\x9c\x8a\x38\xb5\xaa\x29\xa9\xa2\xf0\x19\x37\xe0\xef\x5a\xc4\x09\x6c\x1f\x40\xf9\x13\xf7\x26\x8e\x52\xf0\x50\x51\xb9\x8b\xc0\xb0\x23\xe9\x2f\xda\xdc\x6f\x1d\x93\x08\x40\xa5\xdc\xf5\x94\xb2\x20\x4b\x48\xee\x3b\xc1\x3a\x59\x1a\x13\x5c\xfa\xe3\x1c\xd5\x99\x0a\x1c\x9a\xc2\xb0\x09\x24\xdd\x77\xee\x30\x2c\xeb\x99\x13\x50\x0e\x89\xdc\x34\x67\x1f\x94\xb8\xf6\x4e\xb2\x5e\x0d\x8c\x21\xf0\x0f\xb5\x8e\x6c\xa2\x01\x86\x9e\xd8\x24\xc4\x93\x28\xd0\xa3\x9a\x7f\x78\x4d\x28\xc6\x04\xd6\x21\xd1\x28\x94\x1c\xcf\xd1\x33\xcd\x63\x8b\x38\x94\xea\xce\x0a\x88\x2c\xde\xae\x12\x19\x8c\x3c\x38\x17\x61\xeb\x23\x79\x0d\x51\x5c\x40\xfa\xb8\x72\x01\xe3\x03\x0b\xee\x78\x79\x3c\x60\x5b\xb8\xe4\x38\xb7\xbd\x18\x20\x57\x3c\x3c\x4c\xa8\x62\xd5\xeb\x97\x00\x63\xc0\x83\xd1\xdd\xa8\x5b\xd7\xdc\x74\x8c\xc8\x4f\x0a\x9b\x89\x3f\xe7\x2b\xbc\x16\x68\x95\x23\x86\xce\x67\x22\x49\x35\xad\xc1\xf7\x5f\xe3\x2a\x6b\xe4\x21\x26\x44\xc1\xa1\x5e\x9c\xa6\x12\x75\x08\x32\xad\xfb\xe2\x54\x02\xdd\x3a\xc8\x0c\x7c\x9e\x25\xe5\x1b\x3e\x62\xb8\x63\x6a\x26\x6d\x04\x7e\x26\x74\x61\xae\x21\x26\xfb\xa2\x3b\x76\x99\xeb\x0a\xb8\x2d\x22\xad\x2e\x77\xfd\xcd\x46\x8c\xa9\x59\x47\x71\x36\x73\x18\x9b\x39\xd7\x56\x08\x63\x91\xb0\x4a\xe3\x17\x08\x72\x26\x98\xc1\x6b\xe0\x89\x88\x12\x98\x99\x5d\x87\x2e\xdc\x64\xf7\xad\x05\x6f\x6f\x36\xbf\x9c\x4b\x0e\x0c\xf6\xc4\x8f\xe8\xcf\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x89\x4a\x5d\xe3\xb4\xf3\x74\xe6\x50\xee\x11\x27\xec\x65\x8f\xfc\x21\x26\x5f\xff\xc4\x00\x23\x11\x01\x00\x02\x02\x02\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\x91\xa1\xb1\xc1\xd1\xf0\xff\xda\x00\x08\x01\x03\x01\x01\x3f\x10\x69\xa6\x38\x70\x4d\x4f\x85\x62\x78\xd6\x40\x85\xbf\x37\xff\x00\x7f\x98\x74\x08\x6d\x78\x9d\xa4\xd4\x9c\x71\x3f\x78\xb9\x0e\x8e\xdb\xda\xcd\xc9\xb8\x0f\x9c\x59\x47\x22\xce\x2b\x5b\x9e\xb9\xe6\xfc\x61\x66\x9d\x91\x11\x3a\x67\xc6\xb4\x78\xf3\x8b\x25\xfb\x1c\x04\xb8\xd8\x95\x60\xbf\x47\xcd\x6b\x13\xa0\x74\x44\x1a\x0a\xaa\x46\x4b\x32\x48\x69\xc7\x11\x1e\xa7\x7b\xf9\x91\xc1\x43\x4d\xf9\x9e\xfe\x71\xf1\x4b\x70\x7f\x7a\xc4\x00\xa0\xb2\x77\x32\xfe\x0f\x8f\x38\x0c\x26\x17\x9f\x39\x11\xc2\x33\x74\x22\x12\x6d\x99\xd1\xad\xae\x2d\x92\x28\x07\x6f\x07\x6b\xf2\xd7\x46\x18\x56\x89\x6d\x9e\xa5\xb8\xfd\x7a\xc1\x79\x02\x64\xb1\x31\xc8\xc1\x1d\x46\xfe\x63\x08\x5a\x57\x05\x5d\x84\xce\xef\x67\x67\xa3\xca\x0d\xd4\x24\xcc\x5d\xfa\xe9\x86\x9c\x2b\x91\x2e\xbb\xbc\x14\x35\x5d\x9a\x01\x2a\xbd\xc3\x9f\x9a\x9c\xa6\x10\x0c\x8b\x69\xb7\xd3\x06\xb7\xba\xee\x00\x9c\xd8\xd9\xd3\x14\x03\xef\xd3\x38\xdd\x42\xb2\x93\xc1\xc1\xd4\xee\x28\xfc\x61\xee\x70\x9e\xcf\x9c\xae\x44\xa4\x98\xb8\x5d\x9c\x4c\x4e\x98\xe7\x00\xd3\x9a\xde\xbe\xb0\xa2\x44\x04\x09\x69\x0b\x36\x6e\xe6\x65\x83\x58\x26\x9e\x64\xca\xdf\x2d\x57\x8f\xb9\x6f\x24\x6c\x04\xa2\x93\x84\xfd\xf8\xd4\x60\x9a\x8c\x38\x43\x14\x49\xe0\xc7\x60\x40\x02\x25\x0b\x71\xea\x12\x64\x24\xe6\xf0\xa4\x59\x61\x51\xc5\xf7\xf6\x79\x19\xc2\x03\x58\xc2\x81\x3b\x01\x38\xe4\x88\x3d\x44\x6f\x1b\x98\xc9\x92\x92\x7a\x3b\xf4\xd1\x8c\x8a\xc0\x2b\xf1\xee\xa7\x8f\xee\x18\xa2\x0d\x31\x76\x0c\x47\xf2\x69\x36\xe4\x0e\x88\x0d\x1d\x93\x5e\xa7\x7c\xc4\x39\x04\x91\x7f\xe7\x59\xb3\xe3\xf8\x61\x29\x23\x21\xdd\xf3\x84\x1a\x1c\x0a\x3f\x18\x88\x6d\x85\x3c\x9c\x56\x4a\xe9\xa3\x77\xd6\x10\x36\xe1\xfd\x64\xbf\xe8\xe7\xff\xc4\x00\x24\x11\x01\x01\x00\x02\x02\x02\x01\x04\x03\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x31\x00\x41\x51\x61\x71\x81\x91\xb1\xc1\xa1\xd1\xf1\xe1\xff\xda\x00\x08\x01\x02\x01\x01\x3f\x10\xd7\xa7\x57\x3d\x84\x75\x41\x50\xae\x6b\xe7\x8e\x43\x43\xe5\x3b\xff\x00\x9f\x7e\x68\xbc\x16\x48\xbe\xe6\xaf\x67\x7d\x78\xe2\x89\x90\xa0\x53\x16\x3a\x80\x1b\x59\xc2\xdd\x06\x5b\x21\x0b\xa2\x02\xa1\x8c\xef\x1d\x6f\xcb\x98\x8a\x0b\x93\x8c\x3d\x9c\xb5\xdb\x0d\xda\xc2\x20\xe0\xc7\x03\x46\x8d\x02\xdc\x88\xef\x76\xbf\x4c\x57\x9e\xd8\x3c\xf5\x44\xbe\xa7\xfb\xc0\x0b\x48\x65\xf0\xfe\x19\x6c\x4c\x75\xc1\x70\xe0\x22\x42\x6e\x47\x53\xbf\x1d\xf8\x40\x99\xb1\x95\x73\x83\xcf\xdd\xc1\x98\x0e\x39\x17\xcc\x83\xa6\xbb\x9a\x67\xee\xf8\xe0\x44\x00\xeb\xfd\x73\x0a\x4d\xa9\x17\x2b\x69\xd7\xdf\x63\x21\x78\x88\xe4\x17\x1b\x2e\x3a\xa6\x97\xb3\x13\xbe\x04\x46\x2d\xe8\xf1\x83\x67\xae\xf1\xee\xa3\xb2\x0b\x64\xcf\xbf\xae\x2f\xc7\x1a\xb3\x19\x60\xe1\x73\x82\x4d\x1d\x84\xcf\x28\x89\x91\x03\x95\x14\xf8\x83\x77\xf7\xc8\x99\xea\x57\x33\x2e\x74\x10\xf8\x38\x62\x58\xe9\xeb\x52\x75\x8a\x43\xe3\x61\xc7\xce\xa2\x40\x58\xac\x2b\xe2\xc2\x98\xa9\x9a\x50\xbb\xca\xb0\x4c\x56\x9a\x8d\x77\x93\x4c\xa7\x10\x14\x6c\xec\xf6\x91\xd4\x4e\xf3\x31\xc6\x1d\xc2\xdd\xc2\x76\xa4\xea\x77\xae\xf8\xb7\xd2\x04\xc0\xa0\xa1\xe5\xb7\x5b\xc7\x7c\x70\x7f\x3e\x60\x54\xef\x48\xb9\xcd\x7d\xe6\x9e\xf5\xc3\x46\x51\x2b\xac\x1c\x86\x72\x4d\xfd\x08\x71\x1c\xed\x00\xe5\x62\xaa\xe7\xa3\xda\xa9\x3a\xe6\x63\xa2\xc9\x66\x6b\x0f\xe9\xf7\xcb\x80\x6b\x83\x80\x98\x3a\xb1\x82\x36\x9a\x67\x14\xa4\x25\x13\x2e\x58\xe0\xd0\xd6\x2f\x56\x50\xa2\xd3\xee\x1f\xd7\x03\x71\xcc\x66\x78\x1a\xec\xcc\x62\xf5\x71\xc9\x6f\x24\x75\x07\x66\x8c\x7e\x3e\xb7\x84\x88\xc3\x7c\xa9\x02\x47\x02\xb7\xe4\x9b\x78\x02\xe1\x11\x2f\x4a\xfe\x9d\x7d\x39\x8c\x7b\xef\x60\xb1\xbd\x4e\xf1\x1b\xa3\x7c\xa8\xa9\x24\x14\xab\x37\x8c\x46\x44\x42\xa6\x6b\xcb\xd4\xce\x3c\x75\x2b\xf9\x6b\xef\xc4\x0a\x28\x1e\xcc\x3a\xf1\xc5\x67\x46\x15\x59\x72\x97\x5c\x96\xe4\xb2\x56\x4f\x1c\x39\x56\x31\x97\x19\x9f\x8c\x71\xa9\xaf\xf9\xc3\x98\x20\xe7\xff\xc4\x00\x1f\x10\x01\x01\x01\x01\x01\x01\x00\x02\x03\x01\x00\x00\x00\x00\x00\x00\x01\x11\x21\x00\x31\x41\x51\x61\x71\x81\xd1\x91\xff\xda\x00\x08\x01\x01\x00\x01\x3f\x10\xca\x95\xf8\x23\xa1\xff\x00\xa4\x51\xaa\x3a\xfa\xba\x8a\x07\x12\x09\xa8\x42\x89\x66\x0b\x78\x98\x94\xbb\x7a\x81\x41\xf3\x68\x54\xa4\x3f\x3f\x99\xc1\xac\x14\x9f\xe5\xc9\xa2\x63\xd4\x20\x1b\x60\x03\x7e\x78\x61\xc5\x9d\xc9\x6c\xce\x48\x04\x84\xb7\x5f\x9a\x7d\x70\x8f\xbd\x3f\xd3\x67\x03\x79\x27\x33\x40\x32\x80\x81\x2e\x33\xcb\xb5\xa4\xcd\x43\x4a\x92\x3e\x10\x97\xe1\xaa\xf3\x20\x83\x66\x0b\x16\x9a\x80\x3d\xec\x0c\x91\xb3\x44\xe8\x5b\x0b\x8d\x1f\x15\xe0\x07\xc3\x51\x49\x28\x68\x37\x84\xfc\xfd\x79\x70\x08\x93\xb5\x3c\x31\x4b\xf5\x4c\xf5\xe7\x5a\x4a\x54\x8a\x27\xc4\x7e\x72\x15\xef\x43\x85\x70\x3f\x25\x2a\x81\x64\x77\x7f\xa5\x88\xd3\x25\xd2\x8a\x07\x81\xcf\xe8\x65\xa6\xd2\x16\x0a\x8e\x3f\x5f\x97\x84\xd5\x81\x42\x90\x9f\x1c\xac\x10\x3c\x87\x7a\x81\xe8\x2e\x58\x00\x97\xc1\xbb\x76\xf0\x0e\xf9\x41\x10\x80\x53\x24\x8d\xf8\x8f\x36\x34\x8d\x9c\x21\x6b\x6e\x7d\xde\x42\x2f\x58\x58\x0d\x08\x88\x44\x6b\xc5\x38\x44\x28\x0a\x56\xb5\x1d\xdb\x2a\xe0\x71\x40\xe6\xd7\x40\x8d\xc4\xa0\x02\xe2\x8a\xa0\xf9\x1b\x8f\x96\x33\x41\x0a\x26\xbc\x2a\xfb\x8e\x25\x08\xf0\xbf\xb3\xed\xca\x89\x8f\x41\xa8\x18\xda\x07\xd8\x1a\x88\xe6\x60\x11\x2f\xd3\x5b\x9f\xbd\xe6\x98\x60\x8c\xc5\x3e\x18\x03\x63\x3d\x87\x04\x50\x82\x8a\xc5\x70\x53\x01\x29\x9e\x1d\xec\xd3\x64\x68\xc0\x80\x91\x5f\xc0\xe0\x04\xab\x86\x18\x84\x04\x92\xfa\x1a\x8f\xa4\xe9\xbb\x42\xa6\xa8\xfe\xd0\x1a\x15\x21\x73\x6e\xd0\x53\x3c\x60\x00\x28\x86\x5a\xf3\x95\xfb\x8c\x82\xf8\x33\xce\x7e\xee\x61\xdf\x91\x84\x0f\x45\xf4\xbe\x5e\x97\xcc\x8b\x06\xca\xc1\x34\xa5\x65\xe9\x16\xd6\x05\xda\x00\xc4\x11\x49\x27\x0c\x3a\xaa\x84\x8a\x5a\x11\x70\x81\xf5\x84\xe5\x4c\x1d\x0d\x86\x1e\x12\x8b\x82\x3e\x1c\xe9\xe7\x22\x03\x5b\x0e\x59\x08\x31\x4e\x73\x89\x22\x5d\x2d\x66\xdf\xc7\x01\x35\x22\x85\x04\x7d\x13\x27\xe3\x88\x8b\x69\x72\x89\x62\x7e\xb8\xcf\x34\xdf\x40\x00\xa0\x28\x5f\x05\x38\x49\x00\x4b\xf4\xa5\xc5\xd5\x7f\x95\x7a\x26\x52\x46\x28\x4b\x69\x1b\xf5\x3f\x79\xdc\x04\x5a\x04\x8e\x7e\xb9\xad\x75\x05\x5f\xf6\xef\xff\xd9", + name: "Magic: jpeg render", + input: JPG_RAW, expectedMatch: /Render_Image\('Raw'\)/, recipeConfig: [ { @@ -45,79 +45,112 @@ TestRegister.addTests([ }, { name: "Magic: mojibake", - input: "d091d18bd100d182d180d0b0d10020d0bad0bed180d0b8d187d0bdd0b5d0b2d0b0d10020d0bbd0b8d100d0b020d0bfd180d18bd0b3d0b0d0b5d18220d187d0b5d180d0b5d0b720d0bbd0b5d0bdd0b8d0b2d183d18e20d100d0bed0b1d0b0d0bad1832e", + input: "\xd0\x91\xd1\x8b\xd1\0\xd1\x82\xd1\x80\xd0\xb0\xd1\0\x20\xd0\xba\xd0\xbe\xd1\x80\xd0\xb8\xd1\x87\xd0\xbd\xd0\xb5\xd0\xb2\xd0\xb0\xd1\0\x20\xd0\xbb\xd0\xb8\xd1\0\xd0\xb0\x20\xd0\xbf\xd1\x80\xd1\x8b\xd0\xb3\xd0\xb0\xd0\xb5\xd1\x82\x20\xd1\x87\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb7\x20\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb2\xd1\x83\xd1\x8e\x20\xd1\0\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd1\x83\x2e", expectedMatch: /Быртрар коричневар лира прыгает через ленивую робаку./, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Magic Chain of Base64", - input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09", - expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)/, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Magic Chain of Hex to Hexdump to Base64", - input: "MDAwMDAwMDAgIDM3IDM0IDIwIDM2IDM1IDIwIDM3IDMzIDIwIDM3IDM0IDIwIDMyIDMwIDIwIDM3ICB8NzQgNjUgNzMgNzQgMjAgN3wKMDAwMDAwMTAgIDMzIDIwIDM3IDM0IDIwIDM3IDMyIDIwIDM2IDM5IDIwIDM2IDY1IDIwIDM2IDM3ICB8MyA3NCA3MiA2OSA2ZSA2N3w=", - expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Hexdump\(\)\nFrom_Hex\('Space'\)/, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Magic Chain of Charcode to Octal to Base32", - input: "GY3SANRUEA2DAIBWGYQDMNJAGQYCANRXEA3DGIBUGAQDMNZAGY2CANBQEA3DEIBWGAQDIMBAGY3SANRTEA2DAIBWG4QDMNBAGQYCANRXEA3DEIBUGAQDMNRAG4YSANBQEA3DMIBRGQ2SANBQEA3DMIBWG4======", - expectedMatch: /From_Base32\('A-Z2-7=',false\)\nFrom_Octal\('Space'\)\nFrom_Hex\('Space'\)/, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Magic Chain of Base64 Output Check", - input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09", - expectedMatch: /test string/, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Magic Chain of Decimal to Base32 to Base32", - input: "I5CVSVCNJFBFER2BLFJUCTKKKJDVKUKEINGUUV2FIFNFIRKJIJJEORJSKNAU2SSSI5MVCRCDJVFFKRKBLFKECTSKIFDUKWKUIFEUEUSHIFNFCPJ5HU6Q====", - expectedMatch: /test string/, - recipeConfig: [ - { - op: "Magic", - args: [3, true, false] - } - ], - }, - { - name: "Raw Inflate Result Text", - input: "\x4d\x52\xb1\x6e\xdc\x30\x0c\xdd\xf3\x15\x44\x80\x6e\xae\x91\x02\x4d\x80\x8e\x4d\x9a\x21\x53\x8b\xa6\x43\x56\x5a\xe2\x9d\x84\x93\x25\x43\x94\xed\xf8\xef\xf3\xe8\x6b\x0e\xb7\x1c\xce\xd4\x7b\x8f\x8f\x7c\x7c\xda\x06\xa9\x4f\x41\x0e\x14\x95\x98\x34\x8e\x53\x92\x8e\x62\x6e\x73\x6c\x71\x11\x5a\x65\x20\x9e\x26\x3a\x94\x4a\x8e\x6b\xdd\x62\x3e\x52\x99\x1b\x71\x4a\x34\x72\xce\x52\xa9\x1c\xe8\xd6\x99\xd0\x2d\x95\x49\x2a\xb7\x58\xb2\xd2\x1a\x5b\x88\x19\xa2\x26\x31\xd4\xb2\xaa\xd4\x9e\xfe\x05\x51\xb9\x86\xc5\xec\xd2\xec\xe5\x7f\x6b\x92\xec\x8a\xb7\x1e\x29\x9e\x84\xde\x7e\xff\x25\x34\x7e\x64\x95\x87\xef\x1d\x8d\xa5\x0a\xb9\x62\xc0\x77\x43\xd6\x6d\x32\x91\x33\xf6\xe7\xf3\x6b\x47\xbf\x9e\x5f\x89\xb3\xa7\xc7\x54\xd6\x43\xd4\xd0\x91\xab\x82\x4e\x10\x1c\x62\xe6\xba\xed\xaf\x41\xde\xfd\x3c\x4e\x8a\x57\x88\x55\x51\x35\x15\x7b\xf1\x72\x5d\xc1\x60\x9e\x1b\x03\xc6\xc9\xcd\xe9\xac\x13\x58\x31\xc3\x8e\x76\x41\xdc\x49\xe7\x11\x42\x2f\x7f\x96\x87\xbd\xf6\xd6\xdf\xdf\xfd\xa0\x89\xab\x02\x0c\x66\xe0\x7c\x34\x1a\xfe\x54\x76\x0d\xeb\xfa\x1c\x11\x2c\x23\x8c\xb3\x0b\xfb\x64\xfd\xcd\x0d\xb6\x43\xad\x94\x64\x69\x78\xd1\x78\xcc\xe2\x51\x00\x85\x07\x2c\x67\x28\x2d\x50\x13\x17\x72\x84\xa3\x9d\x9d\x4b\xfe\x7a\x5d\xe1\xb4\x69\x53\xe3\x20\x9c\x38\x99\x69\xd9\x87\xc0\xa2\x2f\xab\x5b\x79\x3b\xe7\x63\x41\x06\x5e\xcc\x1f\x18\x5e\x20\x61\xe5\x0b\xd0\xbc\xa8\x25\xc0\xe9\x58\x2a\x5e\x46\xed\xe9\xa5\x41\x40\x81\xc9\x4e\x70\x22\xbe\xbb\x58\xed\x68\x98\x63\xc2\x6d\xc0\x18\x72\xad\x32\x4a\x6e\x38\x94\x8d\x10\x6e\x2d\xc0\xd2\x60\x09\x7c\xfa\x34\x4f\x2d\x48\xac\xf4\xed\xee\x0b\x3e\x72\x59\xf6\xab\xa0\x16\x47\x1c\xc9\x82\x65\xa9\xe0\x17\xb6\x36\xc1\x46\xfb\x0f", - expectedMatch: /#recipe=Raw_Inflate(.|\n)+CyberChef is a simple, intuitive web app for carrying out all manner of /, recipeConfig: [ { op: "Magic", args: [1, true, false] } + ], + }, + { + name: "Magic: extensive language support, Yiddish", + input: "די שנעל ברוין פאָקס דזשאַמפּס איבער די פויל הונט.", + expectedMatch: /Yiddish/, + recipeConfig: [ + { + op: "Magic", + args: [1, false, true] + } + ], + }, + { + name: "Magic Chain: Base64", + input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09", + expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)/, + recipeConfig: [ + { + op: "Magic", + args: [3, false, false] + } + ], + }, + { + name: "Magic Chain: Hex -> Hexdump -> Base64", + input: "MDAwMDAwMDAgIDM3IDM0IDIwIDM2IDM1IDIwIDM3IDMzIDIwIDM3IDM0IDIwIDMyIDMwIDIwIDM3ICB8NzQgNjUgNzMgNzQgMjAgN3wKMDAwMDAwMTAgIDMzIDIwIDM3IDM0IDIwIDM3IDMyIDIwIDM2IDM5IDIwIDM2IDY1IDIwIDM2IDM3ICB8MyA3NCA3MiA2OSA2ZSA2N3w=", + expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Hexdump\(\)\nFrom_Hex\('Space'\)/, + recipeConfig: [ + { + op: "Magic", + args: [3, false, false] + } + ], + }, + { + name: "Magic Chain: Charcode -> Octal -> Base32", + input: "GY3SANRUEA2DAIBWGYQDMNJAGQYCANRXEA3DGIBUGAQDMNZAGY2CANBQEA3DEIBWGAQDIMBAGY3SANRTEA2DAIBWG4QDMNBAGQYCANRXEA3DEIBUGAQDMNRAG4YSANBQEA3DMIBRGQ2SANBQEA3DMIBWG4======", + expectedMatch: /From_Base32\('A-Z2-7=',false\)\nFrom_Octal\('Space'\)\nFrom_Hex\('Space'\)/, + recipeConfig: [ + { + op: "Magic", + args: [3, false, false] + } + ], + }, + { + name: "Magic Chain: Base64 output", + input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09", + expectedMatch: /test string/, + recipeConfig: [ + { + op: "Magic", + args: [3, false, false] + } + ], + }, + { + name: "Magic Chain: Decimal -> Base32 -> Base32", + input: "I5CVSVCNJFBFER2BLFJUCTKKKJDVKUKEINGUUV2FIFNFIRKJIJJEORJSKNAU2SSSI5MVCRCDJVFFKRKBLFKECTSKIFDUKWKUIFEUEUSHIFNFCPJ5HU6Q====", + expectedMatch: /test string/, + recipeConfig: [ + { + op: "Magic", + args: [3, false, false] + } + ], + }, + { + name: "Magic: Raw Inflate", + input: "\x4d\x52\xb1\x6e\xdc\x30\x0c\xdd\xf3\x15\x44\x80\x6e\xae\x91\x02\x4d\x80\x8e\x4d\x9a\x21\x53\x8b\xa6\x43\x56\x5a\xe2\x9d\x84\x93\x25\x43\x94\xed\xf8\xef\xf3\xe8\x6b\x0e\xb7\x1c\xce\xd4\x7b\x8f\x8f\x7c\x7c\xda\x06\xa9\x4f\x41\x0e\x14\x95\x98\x34\x8e\x53\x92\x8e\x62\x6e\x73\x6c\x71\x11\x5a\x65\x20\x9e\x26\x3a\x94\x4a\x8e\x6b\xdd\x62\x3e\x52\x99\x1b\x71\x4a\x34\x72\xce\x52\xa9\x1c\xe8\xd6\x99\xd0\x2d\x95\x49\x2a\xb7\x58\xb2\xd2\x1a\x5b\x88\x19\xa2\x26\x31\xd4\xb2\xaa\xd4\x9e\xfe\x05\x51\xb9\x86\xc5\xec\xd2\xec\xe5\x7f\x6b\x92\xec\x8a\xb7\x1e\x29\x9e\x84\xde\x7e\xff\x25\x34\x7e\x64\x95\x87\xef\x1d\x8d\xa5\x0a\xb9\x62\xc0\x77\x43\xd6\x6d\x32\x91\x33\xf6\xe7\xf3\x6b\x47\xbf\x9e\x5f\x89\xb3\xa7\xc7\x54\xd6\x43\xd4\xd0\x91\xab\x82\x4e\x10\x1c\x62\xe6\xba\xed\xaf\x41\xde\xfd\x3c\x4e\x8a\x57\x88\x55\x51\x35\x15\x7b\xf1\x72\x5d\xc1\x60\x9e\x1b\x03\xc6\xc9\xcd\xe9\xac\x13\x58\x31\xc3\x8e\x76\x41\xdc\x49\xe7\x11\x42\x2f\x7f\x96\x87\xbd\xf6\xd6\xdf\xdf\xfd\xa0\x89\xab\x02\x0c\x66\xe0\x7c\x34\x1a\xfe\x54\x76\x0d\xeb\xfa\x1c\x11\x2c\x23\x8c\xb3\x0b\xfb\x64\xfd\xcd\x0d\xb6\x43\xad\x94\x64\x69\x78\xd1\x78\xcc\xe2\x51\x00\x85\x07\x2c\x67\x28\x2d\x50\x13\x17\x72\x84\xa3\x9d\x9d\x4b\xfe\x7a\x5d\xe1\xb4\x69\x53\xe3\x20\x9c\x38\x99\x69\xd9\x87\xc0\xa2\x2f\xab\x5b\x79\x3b\xe7\x63\x41\x06\x5e\xcc\x1f\x18\x5e\x20\x61\xe5\x0b\xd0\xbc\xa8\x25\xc0\xe9\x58\x2a\x5e\x46\xed\xe9\xa5\x41\x40\x81\xc9\x4e\x70\x22\xbe\xbb\x58\xed\x68\x98\x63\xc2\x6d\xc0\x18\x72\xad\x32\x4a\x6e\x38\x94\x8d\x10\x6e\x2d\xc0\xd2\x60\x09\x7c\xfa\x34\x4f\x2d\x48\xac\xf4\xed\xee\x0b\x3e\x72\x59\xf6\xab\xa0\x16\x47\x1c\xc9\x82\x65\xa9\xe0\x17\xb6\x36\xc1\x46\xfb\x0f", + expectedMatch: /#recipe=Raw_Inflate(.|\n)+CyberChef is a simple, intuitive web app for carrying out all manner of /, + recipeConfig: [ + { + op: "Magic", + args: [1, false, false] + } + ] + }, + { + name: "Magic: Defang IP Address, valid", + input: "192.168.0.1", + expectedMatch: /Properties[^#]+?#recipe=Defang_IP_Addresses\(\)"/, + recipeConfig: [ + { + op: "Magic", + args: [1, false, false] + } + ] + }, + { + name: "Magic: Defang IP Address, invalid", + input: "192.168.0.1.0", + unexpectedMatch: /Defang_IP_Addresses/, + recipeConfig: [ + { + op: "Magic", + args: [1, false, false] + } ] } ]);