From a3040a3b71dc6509a8da4bc51113e0472b8f2046 Mon Sep 17 00:00:00 2001 From: tjjfvi Date: Sat, 8 Apr 2023 16:13:17 -0400 Subject: [PATCH] add hex codec --- codecs/bench/hex.bench.ts | 36 + codecs/fixtures/hex.rs | 29 + codecs/hex.ts | 49 + codecs/mod.ts | 1 + codecs/test/__snapshots__/hex.test.ts.snap | 8876 ++++++++++++++++++++ codecs/test/hex.test.ts | 47 + common/mod.ts | 2 +- fixtures.rs | 3 + 8 files changed, 9042 insertions(+), 1 deletion(-) create mode 100644 codecs/bench/hex.bench.ts create mode 100644 codecs/fixtures/hex.rs create mode 100644 codecs/hex.ts create mode 100644 codecs/test/__snapshots__/hex.test.ts.snap create mode 100644 codecs/test/hex.test.ts diff --git a/codecs/bench/hex.bench.ts b/codecs/bench/hex.bench.ts new file mode 100644 index 0000000..5a704ee --- /dev/null +++ b/codecs/bench/hex.bench.ts @@ -0,0 +1,36 @@ +import * as $ from "../../mod.ts" +import { decodeHex, encodeHex } from "../../mod.ts" +import { benchCodec } from "../../test-util.ts" + +const words = await Deno.readFile("words.txt") +const cargoLock = await Deno.readFile("Cargo.lock") +const cases = [ + new Uint8Array(), + new Uint8Array(128), + words, + cargoLock, + new Uint8Array(Array(1000).fill([...words]).flat()), +] + +Deno.bench(" ", () => {}) + +for (const data of cases) { + const encoded = encodeHex(data) + decodeHex(encoded) + Deno.bench(`encode ${data.length} bytes`, () => { + encodeHex(data) + }) + Deno.bench(`decode ${data.length} bytes`, () => { + decodeHex(encoded) + }) +} + +const $unsizedHex = $.hex($.uint8Array) +for (const data of cases) { + benchCodec(`$unsizedHex ${data.length} bytes`, $unsizedHex, encodeHex(data)) +} + +for (const data of cases) { + const $sizedHex = $.hex($.sizedUint8Array(data.length)) + benchCodec(`$sizedHex ${data.length} bytes`, $sizedHex, encodeHex(data)) +} diff --git a/codecs/fixtures/hex.rs b/codecs/fixtures/hex.rs new file mode 100644 index 0000000..9320632 --- /dev/null +++ b/codecs/fixtures/hex.rs @@ -0,0 +1,29 @@ +crate::fixtures!( + >::new(), + vec![0, 1, 2, 3, 4, 5u8], + vec![0xde, 0xad, 0xbe, 0xef_u8], + crate::CARGO_LOCK, + [0u8], + [1u8], + [255u8], + [ + 0xdd, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, + 0x0c, 0xc0, 0x00, 0xcc_u8, + ], + [ + 0xdd, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcc, 0xcc, 0x00_u8, + ], + [ + 0xdd, 0xdd, 0xdd, 0xdd, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, + 0x00, 0x0c, 0xc0, 0x00_u8, + ], + [ + 0xdd, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcc, 0xcc, 0x00_u8, + ], + [ + 0xdd, 0x00, 0x00, 0xdd, 0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, + 0x0c, 0xc0, 0x00, 0xcc_u8, + ], +); diff --git a/codecs/hex.ts b/codecs/hex.ts new file mode 100644 index 0000000..f610d72 --- /dev/null +++ b/codecs/hex.ts @@ -0,0 +1,49 @@ +import { Codec, metadata, ScaleAssertError, withMetadata } from "../mod.ts" +import { transform } from "./transform.ts" + +const encodeLookup = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0")) +const decodeLookup = Array.from({ length: 128 }, (_, i) => parseInt(String.fromCharCode(i), 16) | 0) + +export function encodeHex(bytes: Uint8Array): string { + let str = "" + for (let i = 0; i < bytes.length; i++) { + str += encodeLookup[bytes[i]!] + } + return str +} + +export function encodeHexPrefixed(bytes: Uint8Array) { + let str = "0x" + for (let i = 0; i < bytes.length; i++) { + str += encodeLookup[bytes[i]!] + } + return str +} + +export function decodeHex(hex: string): Uint8Array { + if (hex.startsWith("0x")) hex = hex.slice(2) + if (hex.length % 2 === 1) hex = "0" + hex + const array = new Uint8Array(hex.length >> 1) + for (let i = 0; i < array.length; i++) { + array[i] = (decodeLookup[hex.charCodeAt(i << 1)!]! << 4) | decodeLookup[hex.charCodeAt(i << 1 | 1)!]! + } + return array +} + +const hexRegex = /^(?:0x)?[\da-f]*$/i +export function hex($inner: Codec): Codec { + return withMetadata( + metadata("$.hex", hex, $inner), + transform({ + $base: $inner, + encode: decodeHex, + decode: encodeHex, + assert(assert) { + assert.typeof(this, "string") + if (!hexRegex.test(assert.value as string)) { + throw new ScaleAssertError(this, assert.value, `${assert.path}: invalid hex`) + } + }, + }), + ) +} diff --git a/codecs/mod.ts b/codecs/mod.ts index bf641fb..448ea90 100644 --- a/codecs/mod.ts +++ b/codecs/mod.ts @@ -7,6 +7,7 @@ export * from "./compact.ts" export * from "./constant.ts" export * from "./deferred.ts" export * from "./float.ts" +export * from "./hex.ts" export * from "./instance.ts" export * from "./int.ts" export * from "./iterable.ts" diff --git a/codecs/test/__snapshots__/hex.test.ts.snap b/codecs/test/__snapshots__/hex.test.ts.snap new file mode 100644 index 0000000..93a175d --- /dev/null +++ b/codecs/test/__snapshots__/hex.test.ts.snap @@ -0,0 +1,8876 @@ +export const snapshot = {}; + +snapshot[`\$.hex(\$.uint8Array) "" 1`] = `00`; + +snapshot[`\$.hex(\$.uint8Array) "000102030405" 1`] = ` +18 +00 +01 +02 +03 +04 +05 +`; + +snapshot[`\$.hex(\$.uint8Array) "deadbeef" 1`] = ` +10 +de +ad +be +ef +`; + +snapshot[`\$.hex(\$.uint8Array) "2320546869732066696c65206973206175746f6d61746963616c6c79204067656e65726174656420627920436172676f2e0a23204974206973206e6f7420696e74656e64656420666f72206d616e75616c2065646974696e672e0a76657273696f6e203d20330a0a5b5b7061636b6167655d5d0a6e616d65203d20226172726179766563220a76657273696f6e203d2022302e372e32220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202238646135326436366337303731653265336661326131653563366430383866656334376235393330333262323534663565393830646538656135343435346436220a0a5b5b7061636b6167655d5d0a6e616d65203d2022626974766563220a76657273696f6e203d2022312e302e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202231626332383332633234323339623031343164353637346262393137346639643638613862356233663237353333313139323763313732636134366637653963220a646570656e64656e63696573203d205b0a202266756e7479222c0a202272616469756d222c0a2022746170222c0a202277797a222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022627974652d736c6963652d63617374220a76657273696f6e203d2022312e322e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202238376335666464303136363039356531643436336663366363303161613863653534376164373761346538346434326562363736326230383465323830363765220a0a5b5b7061636b6167655d5d0a6e616d65203d2022627974656f72646572220a76657273696f6e203d2022312e342e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202231346331383963353364303938393435343939636466613765636336333536376366333838366233333332623331326135623435383564386433613661363130220a0a5b5b7061636b6167655d5d0a6e616d65203d20226366672d6966220a76657273696f6e203d2022312e302e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202262616631646534333339373631353838626330363139653363626330313230656535383265626237346235336234656662663739313137626432646134306664220a0a5b5b7061636b6167655d5d0a6e616d65203d20226372756e636879220a76657273696f6e203d2022302e322e32220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202237613831646165303738636561393561303134613333393239316365633433396432663233326562653835346139643637326237393663366166616661396237220a0a5b5b7061636b6167655d5d0a6e616d65203d2022656974686572220a76657273696f6e203d2022312e362e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265373864346631636334616533336262666331353765643564356135656633626332393232373330336435393538363164656232333866636563346539343537220a0a5b5b7061636b6167655d5d0a6e616d65203d202266697865642d68617368220a76657273696f6e203d2022302e372e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202263666366306564376665353261313761303338353465633534613966373664366438343530386431633065363662633137393333303163373366633834393363220a646570656e64656e63696573203d205b0a2022627974656f72646572222c0a202272616e64222c0a202272757374632d686578222c0a20227374617469635f617373657274696f6e73222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202266756e7479220a76657273696f6e203d2022322e302e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265366435613332383135616533663333333032643935666463623263653137383632663863363533363364636664323933363034383062613130303166633963220a0a5b5b7061636b6167655d5d0a6e616d65203d202267657472616e646f6d220a76657273696f6e203d2022302e322e36220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202239626537306339383935316338336238643266386636306437303635666136643531343638373330393434353261313030386461386332663165343230356164220a646570656e64656e63696573203d205b0a20226366672d6966222c0a20226c696263222c0a202277617369222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022686578220a76657273696f6e203d2022302e342e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202237663234323534616139613534623563383538656165653266356263636462343661616630653438366135393565643566643866383662613535323332613730220a0a5b5b7061636b6167655d5d0a6e616d65203d2022696d706c2d636f646563220a76657273696f6e203d2022302e362e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202262613661323730303339363236363135363137663366333664313566633832373034316466336237386334333964613263616466613437343535613737663266220a646570656e64656e63696573203d205b0a20227061726974792d7363616c652d636f646563222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022696d706c2d74726169742d666f722d7475706c6573220a76657273696f6e203d2022302e322e32220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202231316437613966363333306237316665613537393231633962363163343765653665383466373264333934373534656666363136336165363765373339356562220a646570656e64656e63696573203d205b0a202270726f632d6d6163726f32222c0a202271756f7465222c0a202273796e222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202269746572746f6f6c73220a76657273696f6e203d2022302e31302e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202261396139643139666131653739623632313566663239623964363838306237303631343766313665396231646262316534653539343762356230326263356533220a646570656e64656e63696573203d205b0a2022656974686572222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d20226c696263220a76657273696f6e203d2022302e322e313236220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202233343964356135393163643238623439653164313033373437313631376133326464636461353733316239393431393030383038356637326435613533383336220a0a5b5b7061636b6167655d5d0a6e616d65203d20227061726974792d7363616c652d636f646563220a76657273696f6e203d2022332e312e35220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202239313832653461373163616530383932363761623033653637633939333638646237636438373762616635306639333165356436643462373165313935616330220a646570656e64656e63696573203d205b0a20226172726179766563222c0a2022626974766563222c0a2022627974652d736c6963652d63617374222c0a2022696d706c2d74726169742d666f722d7475706c6573222c0a20227061726974792d7363616c652d636f6465632d646572697665222c0a20227365726465222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d20227061726974792d7363616c652d636f6465632d646572697665220a76657273696f6e203d2022332e312e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202239323939333338393639613364326634393164363566313430623030646465633437303835383430326638383861663938653836343266623565383936356364220a646570656e64656e63696573203d205b0a202270726f632d6d6163726f2d6372617465222c0a202270726f632d6d6163726f32222c0a202271756f7465222c0a202273796e222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d20227070762d6c6974653836220a76657273696f6e203d2022302e322e3136220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265623966396536653233336535633461333535353961363137626634306134656334343764623265383463323062353561366638333136376237653537383732220a0a5b5b7061636b6167655d5d0a6e616d65203d20227072696d69746976652d7479706573220a76657273696f6e203d2022302e31312e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265323837323039383862666632373564663166353162313731653162326131386333306431393463346432623631646566646163656364363235613564393461220a646570656e64656e63696573203d205b0a202266697865642d68617368222c0a2022696d706c2d636f646563222c0a202275696e74222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202270726f632d6d6163726f2d6372617465220a76657273696f6e203d2022312e312e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265313764343763653931346266346465343430333332323530623065646432336365343863303035663539666162333964333333353836366231313466313161220a646570656e64656e63696573203d205b0a2022746869736572726f72222c0a2022746f6d6c222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202270726f632d6d6163726f32220a76657273696f6e203d2022312e302e3336220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202263373334326435383833666263636165316363333761323335336230396338376339623066336166643733663566623962626136383761316637333362303239220a646570656e64656e63696573203d205b0a2022756e69636f64652d786964222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202271756f7465220a76657273696f6e203d2022312e302e3137220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202236333264303262666637663837346133366633336561386262343136636434383462393063633636633131393462316131313130643036376137303133663538220a646570656e64656e63696573203d205b0a202270726f632d6d6163726f32222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202272616469756d220a76657273696f6e203d2022302e372e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202264633333666632643439373364353138643832336436316161323339303134383331653532316337356461353865336466343834306433663437373439643039220a0a5b5b7061636b6167655d5d0a6e616d65203d202272616e64220a76657273696f6e203d2022302e382e35220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202233346166386431613065323539323462633562376334336330373963393432333339643866306138623537633339303439626566353831623436333237343034220a646570656e64656e63696573203d205b0a20226c696263222c0a202272616e645f636861636861222c0a202272616e645f636f7265222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202272616e645f636861636861220a76657273696f6e203d2022302e332e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265366331306136336130666133323235326265343964323165373730396434643462616638643233316332646263653165616138313431623962313237643838220a646570656e64656e63696573203d205b0a20227070762d6c6974653836222c0a202272616e645f636f7265222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202272616e645f636f7265220a76657273696f6e203d2022302e362e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202264333466313430386635353239343435333739306334386232663165626262316335623462373536336562316634313862636663666462623036656262346537220a646570656e64656e63696573203d205b0a202267657472616e646f6d222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202272757374632d686578220a76657273696f6e203d2022322e312e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202233653735663661353332643066643966376631333134346633393262366164353661333236393662666364396337386637393766313662626236663037326436220a0a5b5b7061636b6167655d5d0a6e616d65203d20227363616c655f6669787475726573220a76657273696f6e203d2022302e312e30220a646570656e64656e63696573203d205b0a2022626974766563222c0a202269746572746f6f6c73222c0a20227061726974792d7363616c652d636f646563222c0a20227072696d69746976652d7479706573222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d20227365726465220a76657273696f6e203d2022312e302e313336220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202263653331653234623031653165353234646639366631633266646430353434303566386437333736323439613531313038383666623462363538343834373839220a0a5b5b7061636b6167655d5d0a6e616d65203d20227374617469635f617373657274696f6e73220a76657273696f6e203d2022312e312e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202261326562393334396236343434623332363837326531343065623163663565376335323231353464363965376130666662306662383163303662333735343366220a0a5b5b7061636b6167655d5d0a6e616d65203d202273796e220a76657273696f6e203d2022312e302e3839220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202265613239376265323230643532333938646363303763653135613230396663653433366433363137333561633164623730306361623362366364666239663534220a646570656e64656e63696573203d205b0a202270726f632d6d6163726f32222c0a202271756f7465222c0a2022756e69636f64652d786964222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022746170220a76657273696f6e203d2022312e302e31220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202235353933376531373939313835623132383633643434376634323539376564363964393932383638366238643838613164663137333736613039376438333639220a0a5b5b7061636b6167655d5d0a6e616d65203d2022746869736572726f72220a76657273696f6e203d2022312e302e3330220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202238353462616265353265346466313635333730366239386663666330353834333031303033396234303638373539333061373065346439363434653563343137220a646570656e64656e63696573203d205b0a2022746869736572726f722d696d706c222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022746869736572726f722d696d706c220a76657273696f6e203d2022312e302e3330220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202261613332666433663632376633363766653136663839336532353937616533633035303230663862626132363636613465366561373364333737653537313462220a646570656e64656e63696573203d205b0a202270726f632d6d6163726f32222c0a202271756f7465222c0a202273796e222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022746f6d6c220a76657273696f6e203d2022302e352e38220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202261333131343239373038323637333364663832343165663335646330343065663938633637396162313464376333653534643832373039396233616365636161220a646570656e64656e63696573203d205b0a20227365726465222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d202275696e74220a76657273696f6e203d2022302e392e33220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202231326630336166376363663031646436313163633435306130643130646263396237343537373064303936343733653266616630636136653264363664316530220a646570656e64656e63696573203d205b0a2022627974656f72646572222c0a20226372756e636879222c0a2022686578222c0a20227374617469635f617373657274696f6e73222c0a5d0a0a5b5b7061636b6167655d5d0a6e616d65203d2022756e69636f64652d786964220a76657273696f6e203d2022302e322e32220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202238636362383264363166383061363633656665316637383761353162313662356135316533333134643661633336356230383633396635323338376233336633220a0a5b5b7061636b6167655d5d0a6e616d65203d202277617369220a76657273696f6e203d2022302e31302e322b776173692d736e617073686f742d7072657669657731220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202266643666626439613739383239646431616430636332303632376266316564363036373536613766373765646666376236366237303634663963623332376336220a0a5b5b7061636b6167655d5d0a6e616d65203d202277797a220a76657273696f6e203d2022302e352e30220a736f75726365203d202272656769737472792b68747470733a2f2f6769746875622e636f6d2f727573742d6c616e672f6372617465732e696f2d696e646578220a636865636b73756d203d202233306233313539346632396432373033366333383362353362353965643334373638373464353138663065666231353162323761346332373531343133393065220a646570656e64656e63696573203d205b0a2022746170222c0a5d0a" 1`] = ` +3d +88 +23 +20 +54 +68 +69 +73 +20 +66 +69 +6c +65 +20 +69 +73 +20 +61 +75 +74 +6f +6d +61 +74 +69 +63 +61 +6c +6c +79 +20 +40 +67 +65 +6e +65 +72 +61 +74 +65 +64 +20 +62 +79 +20 +43 +61 +72 +67 +6f +2e +0a +23 +20 +49 +74 +20 +69 +73 +20 +6e +6f +74 +20 +69 +6e +74 +65 +6e +64 +65 +64 +20 +66 +6f +72 +20 +6d +61 +6e +75 +61 +6c +20 +65 +64 +69 +74 +69 +6e +67 +2e +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +33 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +61 +72 +72 +61 +79 +76 +65 +63 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +37 +2e +32 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +38 +64 +61 +35 +32 +64 +36 +36 +63 +37 +30 +37 +31 +65 +32 +65 +33 +66 +61 +32 +61 +31 +65 +35 +63 +36 +64 +30 +38 +38 +66 +65 +63 +34 +37 +62 +35 +39 +33 +30 +33 +32 +62 +32 +35 +34 +66 +35 +65 +39 +38 +30 +64 +65 +38 +65 +61 +35 +34 +34 +35 +34 +64 +36 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +62 +69 +74 +76 +65 +63 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +31 +62 +63 +32 +38 +33 +32 +63 +32 +34 +32 +33 +39 +62 +30 +31 +34 +31 +64 +35 +36 +37 +34 +62 +62 +39 +31 +37 +34 +66 +39 +64 +36 +38 +61 +38 +62 +35 +62 +33 +66 +32 +37 +35 +33 +33 +31 +31 +39 +32 +37 +63 +31 +37 +32 +63 +61 +34 +36 +66 +37 +65 +39 +63 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +66 +75 +6e +74 +79 +22 +2c +0a +20 +22 +72 +61 +64 +69 +75 +6d +22 +2c +0a +20 +22 +74 +61 +70 +22 +2c +0a +20 +22 +77 +79 +7a +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +62 +79 +74 +65 +2d +73 +6c +69 +63 +65 +2d +63 +61 +73 +74 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +32 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +38 +37 +63 +35 +66 +64 +64 +30 +31 +36 +36 +30 +39 +35 +65 +31 +64 +34 +36 +33 +66 +63 +36 +63 +63 +30 +31 +61 +61 +38 +63 +65 +35 +34 +37 +61 +64 +37 +37 +61 +34 +65 +38 +34 +64 +34 +32 +65 +62 +36 +37 +36 +32 +62 +30 +38 +34 +65 +32 +38 +30 +36 +37 +65 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +62 +79 +74 +65 +6f +72 +64 +65 +72 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +34 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +31 +34 +63 +31 +38 +39 +63 +35 +33 +64 +30 +39 +38 +39 +34 +35 +34 +39 +39 +63 +64 +66 +61 +37 +65 +63 +63 +36 +33 +35 +36 +37 +63 +66 +33 +38 +38 +36 +62 +33 +33 +33 +32 +62 +33 +31 +32 +61 +35 +62 +34 +35 +38 +35 +64 +38 +64 +33 +61 +36 +61 +36 +31 +30 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +63 +66 +67 +2d +69 +66 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +62 +61 +66 +31 +64 +65 +34 +33 +33 +39 +37 +36 +31 +35 +38 +38 +62 +63 +30 +36 +31 +39 +65 +33 +63 +62 +63 +30 +31 +32 +30 +65 +65 +35 +38 +32 +65 +62 +62 +37 +34 +62 +35 +33 +62 +34 +65 +66 +62 +66 +37 +39 +31 +31 +37 +62 +64 +32 +64 +61 +34 +30 +66 +64 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +63 +72 +75 +6e +63 +68 +79 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +32 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +37 +61 +38 +31 +64 +61 +65 +30 +37 +38 +63 +65 +61 +39 +35 +61 +30 +31 +34 +61 +33 +33 +39 +32 +39 +31 +63 +65 +63 +34 +33 +39 +64 +32 +66 +32 +33 +32 +65 +62 +65 +38 +35 +34 +61 +39 +64 +36 +37 +32 +62 +37 +39 +36 +63 +36 +61 +66 +61 +66 +61 +39 +62 +37 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +65 +69 +74 +68 +65 +72 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +36 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +37 +38 +64 +34 +66 +31 +63 +63 +34 +61 +65 +33 +33 +62 +62 +66 +63 +31 +35 +37 +65 +64 +35 +64 +35 +61 +35 +65 +66 +33 +62 +63 +32 +39 +32 +32 +37 +33 +30 +33 +64 +35 +39 +35 +38 +36 +31 +64 +65 +62 +32 +33 +38 +66 +63 +65 +63 +34 +65 +39 +34 +35 +37 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +66 +69 +78 +65 +64 +2d +68 +61 +73 +68 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +37 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +63 +66 +63 +66 +30 +65 +64 +37 +66 +65 +35 +32 +61 +31 +37 +61 +30 +33 +38 +35 +34 +65 +63 +35 +34 +61 +39 +66 +37 +36 +64 +36 +64 +38 +34 +35 +30 +38 +64 +31 +63 +30 +65 +36 +36 +62 +63 +31 +37 +39 +33 +33 +30 +31 +63 +37 +33 +66 +63 +38 +34 +39 +33 +63 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +62 +79 +74 +65 +6f +72 +64 +65 +72 +22 +2c +0a +20 +22 +72 +61 +6e +64 +22 +2c +0a +20 +22 +72 +75 +73 +74 +63 +2d +68 +65 +78 +22 +2c +0a +20 +22 +73 +74 +61 +74 +69 +63 +5f +61 +73 +73 +65 +72 +74 +69 +6f +6e +73 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +66 +75 +6e +74 +79 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +32 +2e +30 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +36 +64 +35 +61 +33 +32 +38 +31 +35 +61 +65 +33 +66 +33 +33 +33 +30 +32 +64 +39 +35 +66 +64 +63 +62 +32 +63 +65 +31 +37 +38 +36 +32 +66 +38 +63 +36 +35 +33 +36 +33 +64 +63 +66 +64 +32 +39 +33 +36 +30 +34 +38 +30 +62 +61 +31 +30 +30 +31 +66 +63 +39 +63 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +67 +65 +74 +72 +61 +6e +64 +6f +6d +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +36 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +39 +62 +65 +37 +30 +63 +39 +38 +39 +35 +31 +63 +38 +33 +62 +38 +64 +32 +66 +38 +66 +36 +30 +64 +37 +30 +36 +35 +66 +61 +36 +64 +35 +31 +34 +36 +38 +37 +33 +30 +39 +34 +34 +35 +32 +61 +31 +30 +30 +38 +64 +61 +38 +63 +32 +66 +31 +65 +34 +32 +30 +35 +61 +64 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +63 +66 +67 +2d +69 +66 +22 +2c +0a +20 +22 +6c +69 +62 +63 +22 +2c +0a +20 +22 +77 +61 +73 +69 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +68 +65 +78 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +34 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +37 +66 +32 +34 +32 +35 +34 +61 +61 +39 +61 +35 +34 +62 +35 +63 +38 +35 +38 +65 +61 +65 +65 +32 +66 +35 +62 +63 +63 +64 +62 +34 +36 +61 +61 +66 +30 +65 +34 +38 +36 +61 +35 +39 +35 +65 +64 +35 +66 +64 +38 +66 +38 +36 +62 +61 +35 +35 +32 +33 +32 +61 +37 +30 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +69 +6d +70 +6c +2d +63 +6f +64 +65 +63 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +36 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +62 +61 +36 +61 +32 +37 +30 +30 +33 +39 +36 +32 +36 +36 +31 +35 +36 +31 +37 +66 +33 +66 +33 +36 +64 +31 +35 +66 +63 +38 +32 +37 +30 +34 +31 +64 +66 +33 +62 +37 +38 +63 +34 +33 +39 +64 +61 +32 +63 +61 +64 +66 +61 +34 +37 +34 +35 +35 +61 +37 +37 +66 +32 +66 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +61 +72 +69 +74 +79 +2d +73 +63 +61 +6c +65 +2d +63 +6f +64 +65 +63 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +69 +6d +70 +6c +2d +74 +72 +61 +69 +74 +2d +66 +6f +72 +2d +74 +75 +70 +6c +65 +73 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +32 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +31 +31 +64 +37 +61 +39 +66 +36 +33 +33 +30 +62 +37 +31 +66 +65 +61 +35 +37 +39 +32 +31 +63 +39 +62 +36 +31 +63 +34 +37 +65 +65 +36 +65 +38 +34 +66 +37 +32 +64 +33 +39 +34 +37 +35 +34 +65 +66 +66 +36 +31 +36 +33 +61 +65 +36 +37 +65 +37 +33 +39 +35 +65 +62 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +2c +0a +20 +22 +71 +75 +6f +74 +65 +22 +2c +0a +20 +22 +73 +79 +6e +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +69 +74 +65 +72 +74 +6f +6f +6c +73 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +31 +30 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +61 +39 +61 +39 +64 +31 +39 +66 +61 +31 +65 +37 +39 +62 +36 +32 +31 +35 +66 +66 +32 +39 +62 +39 +64 +36 +38 +38 +30 +62 +37 +30 +36 +31 +34 +37 +66 +31 +36 +65 +39 +62 +31 +64 +62 +62 +31 +65 +34 +65 +35 +39 +34 +37 +62 +35 +62 +30 +32 +62 +63 +35 +65 +33 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +65 +69 +74 +68 +65 +72 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +6c +69 +62 +63 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +31 +32 +36 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +33 +34 +39 +64 +35 +61 +35 +39 +31 +63 +64 +32 +38 +62 +34 +39 +65 +31 +64 +31 +30 +33 +37 +34 +37 +31 +36 +31 +37 +61 +33 +32 +64 +64 +63 +64 +61 +35 +37 +33 +31 +62 +39 +39 +34 +31 +39 +30 +30 +38 +30 +38 +35 +66 +37 +32 +64 +35 +61 +35 +33 +38 +33 +36 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +61 +72 +69 +74 +79 +2d +73 +63 +61 +6c +65 +2d +63 +6f +64 +65 +63 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +33 +2e +31 +2e +35 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +39 +31 +38 +32 +65 +34 +61 +37 +31 +63 +61 +65 +30 +38 +39 +32 +36 +37 +61 +62 +30 +33 +65 +36 +37 +63 +39 +39 +33 +36 +38 +64 +62 +37 +63 +64 +38 +37 +37 +62 +61 +66 +35 +30 +66 +39 +33 +31 +65 +35 +64 +36 +64 +34 +62 +37 +31 +65 +31 +39 +35 +61 +63 +30 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +61 +72 +72 +61 +79 +76 +65 +63 +22 +2c +0a +20 +22 +62 +69 +74 +76 +65 +63 +22 +2c +0a +20 +22 +62 +79 +74 +65 +2d +73 +6c +69 +63 +65 +2d +63 +61 +73 +74 +22 +2c +0a +20 +22 +69 +6d +70 +6c +2d +74 +72 +61 +69 +74 +2d +66 +6f +72 +2d +74 +75 +70 +6c +65 +73 +22 +2c +0a +20 +22 +70 +61 +72 +69 +74 +79 +2d +73 +63 +61 +6c +65 +2d +63 +6f +64 +65 +63 +2d +64 +65 +72 +69 +76 +65 +22 +2c +0a +20 +22 +73 +65 +72 +64 +65 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +61 +72 +69 +74 +79 +2d +73 +63 +61 +6c +65 +2d +63 +6f +64 +65 +63 +2d +64 +65 +72 +69 +76 +65 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +33 +2e +31 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +39 +32 +39 +39 +33 +33 +38 +39 +36 +39 +61 +33 +64 +32 +66 +34 +39 +31 +64 +36 +35 +66 +31 +34 +30 +62 +30 +30 +64 +64 +65 +63 +34 +37 +30 +38 +35 +38 +34 +30 +32 +66 +38 +38 +38 +61 +66 +39 +38 +65 +38 +36 +34 +32 +66 +62 +35 +65 +38 +39 +36 +35 +63 +64 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +2d +63 +72 +61 +74 +65 +22 +2c +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +2c +0a +20 +22 +71 +75 +6f +74 +65 +22 +2c +0a +20 +22 +73 +79 +6e +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +70 +76 +2d +6c +69 +74 +65 +38 +36 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +31 +36 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +62 +39 +66 +39 +65 +36 +65 +32 +33 +33 +65 +35 +63 +34 +61 +33 +35 +35 +35 +39 +61 +36 +31 +37 +62 +66 +34 +30 +61 +34 +65 +63 +34 +34 +37 +64 +62 +32 +65 +38 +34 +63 +32 +30 +62 +35 +35 +61 +36 +66 +38 +33 +31 +36 +37 +62 +37 +65 +35 +37 +38 +37 +32 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +72 +69 +6d +69 +74 +69 +76 +65 +2d +74 +79 +70 +65 +73 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +31 +31 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +32 +38 +37 +32 +30 +39 +38 +38 +62 +66 +66 +32 +37 +35 +64 +66 +31 +66 +35 +31 +62 +31 +37 +31 +65 +31 +62 +32 +61 +31 +38 +63 +33 +30 +64 +31 +39 +34 +63 +34 +64 +32 +62 +36 +31 +64 +65 +66 +64 +61 +63 +65 +63 +64 +36 +32 +35 +61 +35 +64 +39 +34 +61 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +66 +69 +78 +65 +64 +2d +68 +61 +73 +68 +22 +2c +0a +20 +22 +69 +6d +70 +6c +2d +63 +6f +64 +65 +63 +22 +2c +0a +20 +22 +75 +69 +6e +74 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +2d +63 +72 +61 +74 +65 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +31 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +31 +37 +64 +34 +37 +63 +65 +39 +31 +34 +62 +66 +34 +64 +65 +34 +34 +30 +33 +33 +32 +32 +35 +30 +62 +30 +65 +64 +64 +32 +33 +63 +65 +34 +38 +63 +30 +30 +35 +66 +35 +39 +66 +61 +62 +33 +39 +64 +33 +33 +33 +35 +38 +36 +36 +62 +31 +31 +34 +66 +31 +31 +61 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +74 +68 +69 +73 +65 +72 +72 +6f +72 +22 +2c +0a +20 +22 +74 +6f +6d +6c +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +33 +36 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +63 +37 +33 +34 +32 +64 +35 +38 +38 +33 +66 +62 +63 +63 +61 +65 +31 +63 +63 +33 +37 +61 +32 +33 +35 +33 +62 +30 +39 +63 +38 +37 +63 +39 +62 +30 +66 +33 +61 +66 +64 +37 +33 +66 +35 +66 +62 +39 +62 +62 +61 +36 +38 +37 +61 +31 +66 +37 +33 +33 +62 +30 +32 +39 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +75 +6e +69 +63 +6f +64 +65 +2d +78 +69 +64 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +71 +75 +6f +74 +65 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +31 +37 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +36 +33 +32 +64 +30 +32 +62 +66 +66 +37 +66 +38 +37 +34 +61 +33 +36 +66 +33 +33 +65 +61 +38 +62 +62 +34 +31 +36 +63 +64 +34 +38 +34 +62 +39 +30 +63 +63 +36 +36 +63 +31 +31 +39 +34 +62 +31 +61 +31 +31 +31 +30 +64 +30 +36 +37 +61 +37 +30 +31 +33 +66 +35 +38 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +72 +61 +64 +69 +75 +6d +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +37 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +64 +63 +33 +33 +66 +66 +32 +64 +34 +39 +37 +33 +64 +35 +31 +38 +64 +38 +32 +33 +64 +36 +31 +61 +61 +32 +33 +39 +30 +31 +34 +38 +33 +31 +65 +35 +32 +31 +63 +37 +35 +64 +61 +35 +38 +65 +33 +64 +66 +34 +38 +34 +30 +64 +33 +66 +34 +37 +37 +34 +39 +64 +30 +39 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +72 +61 +6e +64 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +38 +2e +35 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +33 +34 +61 +66 +38 +64 +31 +61 +30 +65 +32 +35 +39 +32 +34 +62 +63 +35 +62 +37 +63 +34 +33 +63 +30 +37 +39 +63 +39 +34 +32 +33 +33 +39 +64 +38 +66 +30 +61 +38 +62 +35 +37 +63 +33 +39 +30 +34 +39 +62 +65 +66 +35 +38 +31 +62 +34 +36 +33 +32 +37 +34 +30 +34 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +6c +69 +62 +63 +22 +2c +0a +20 +22 +72 +61 +6e +64 +5f +63 +68 +61 +63 +68 +61 +22 +2c +0a +20 +22 +72 +61 +6e +64 +5f +63 +6f +72 +65 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +72 +61 +6e +64 +5f +63 +68 +61 +63 +68 +61 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +33 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +36 +63 +31 +30 +61 +36 +33 +61 +30 +66 +61 +33 +32 +32 +35 +32 +62 +65 +34 +39 +64 +32 +31 +65 +37 +37 +30 +39 +64 +34 +64 +34 +62 +61 +66 +38 +64 +32 +33 +31 +63 +32 +64 +62 +63 +65 +31 +65 +61 +61 +38 +31 +34 +31 +62 +39 +62 +31 +32 +37 +64 +38 +38 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +70 +76 +2d +6c +69 +74 +65 +38 +36 +22 +2c +0a +20 +22 +72 +61 +6e +64 +5f +63 +6f +72 +65 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +72 +61 +6e +64 +5f +63 +6f +72 +65 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +36 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +64 +33 +34 +66 +31 +34 +30 +38 +66 +35 +35 +32 +39 +34 +34 +35 +33 +37 +39 +30 +63 +34 +38 +62 +32 +66 +31 +65 +62 +62 +62 +31 +63 +35 +62 +34 +62 +37 +35 +36 +33 +65 +62 +31 +66 +34 +31 +38 +62 +63 +66 +63 +66 +64 +62 +62 +30 +36 +65 +62 +62 +34 +65 +37 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +67 +65 +74 +72 +61 +6e +64 +6f +6d +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +72 +75 +73 +74 +63 +2d +68 +65 +78 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +32 +2e +31 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +33 +65 +37 +35 +66 +36 +61 +35 +33 +32 +64 +30 +66 +64 +39 +66 +37 +66 +31 +33 +31 +34 +34 +66 +33 +39 +32 +62 +36 +61 +64 +35 +36 +61 +33 +32 +36 +39 +36 +62 +66 +63 +64 +39 +63 +37 +38 +66 +37 +39 +37 +66 +31 +36 +62 +62 +62 +36 +66 +30 +37 +32 +64 +36 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +73 +63 +61 +6c +65 +5f +66 +69 +78 +74 +75 +72 +65 +73 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +31 +2e +30 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +62 +69 +74 +76 +65 +63 +22 +2c +0a +20 +22 +69 +74 +65 +72 +74 +6f +6f +6c +73 +22 +2c +0a +20 +22 +70 +61 +72 +69 +74 +79 +2d +73 +63 +61 +6c +65 +2d +63 +6f +64 +65 +63 +22 +2c +0a +20 +22 +70 +72 +69 +6d +69 +74 +69 +76 +65 +2d +74 +79 +70 +65 +73 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +73 +65 +72 +64 +65 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +31 +33 +36 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +63 +65 +33 +31 +65 +32 +34 +62 +30 +31 +65 +31 +65 +35 +32 +34 +64 +66 +39 +36 +66 +31 +63 +32 +66 +64 +64 +30 +35 +34 +34 +30 +35 +66 +38 +64 +37 +33 +37 +36 +32 +34 +39 +61 +35 +31 +31 +30 +38 +38 +36 +66 +62 +34 +62 +36 +35 +38 +34 +38 +34 +37 +38 +39 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +73 +74 +61 +74 +69 +63 +5f +61 +73 +73 +65 +72 +74 +69 +6f +6e +73 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +31 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +61 +32 +65 +62 +39 +33 +34 +39 +62 +36 +34 +34 +34 +62 +33 +32 +36 +38 +37 +32 +65 +31 +34 +30 +65 +62 +31 +63 +66 +35 +65 +37 +63 +35 +32 +32 +31 +35 +34 +64 +36 +39 +65 +37 +61 +30 +66 +66 +62 +30 +66 +62 +38 +31 +63 +30 +36 +62 +33 +37 +35 +34 +33 +66 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +73 +79 +6e +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +38 +39 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +65 +61 +32 +39 +37 +62 +65 +32 +32 +30 +64 +35 +32 +33 +39 +38 +64 +63 +63 +30 +37 +63 +65 +31 +35 +61 +32 +30 +39 +66 +63 +65 +34 +33 +36 +64 +33 +36 +31 +37 +33 +35 +61 +63 +31 +64 +62 +37 +30 +30 +63 +61 +62 +33 +62 +36 +63 +64 +66 +62 +39 +66 +35 +34 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +2c +0a +20 +22 +71 +75 +6f +74 +65 +22 +2c +0a +20 +22 +75 +6e +69 +63 +6f +64 +65 +2d +78 +69 +64 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +74 +61 +70 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +35 +35 +39 +33 +37 +65 +31 +37 +39 +39 +31 +38 +35 +62 +31 +32 +38 +36 +33 +64 +34 +34 +37 +66 +34 +32 +35 +39 +37 +65 +64 +36 +39 +64 +39 +39 +32 +38 +36 +38 +36 +62 +38 +64 +38 +38 +61 +31 +64 +66 +31 +37 +33 +37 +36 +61 +30 +39 +37 +64 +38 +33 +36 +39 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +74 +68 +69 +73 +65 +72 +72 +6f +72 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +33 +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +38 +35 +34 +62 +61 +62 +65 +35 +32 +65 +34 +64 +66 +31 +36 +35 +33 +37 +30 +36 +62 +39 +38 +66 +63 +66 +63 +30 +35 +38 +34 +33 +30 +31 +30 +30 +33 +39 +62 +34 +30 +36 +38 +37 +35 +39 +33 +30 +61 +37 +30 +65 +34 +64 +39 +36 +34 +34 +65 +35 +63 +34 +31 +37 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +74 +68 +69 +73 +65 +72 +72 +6f +72 +2d +69 +6d +70 +6c +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +74 +68 +69 +73 +65 +72 +72 +6f +72 +2d +69 +6d +70 +6c +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +31 +2e +30 +2e +33 +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +61 +61 +33 +32 +66 +64 +33 +66 +36 +32 +37 +66 +33 +36 +37 +66 +65 +31 +36 +66 +38 +39 +33 +65 +32 +35 +39 +37 +61 +65 +33 +63 +30 +35 +30 +32 +30 +66 +38 +62 +62 +61 +32 +36 +36 +36 +61 +34 +65 +36 +65 +61 +37 +33 +64 +33 +37 +37 +65 +35 +37 +31 +34 +62 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +70 +72 +6f +63 +2d +6d +61 +63 +72 +6f +32 +22 +2c +0a +20 +22 +71 +75 +6f +74 +65 +22 +2c +0a +20 +22 +73 +79 +6e +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +74 +6f +6d +6c +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +35 +2e +38 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +61 +33 +31 +31 +34 +32 +39 +37 +30 +38 +32 +36 +37 +33 +33 +64 +66 +38 +32 +34 +31 +65 +66 +33 +35 +64 +63 +30 +34 +30 +65 +66 +39 +38 +63 +36 +37 +39 +61 +62 +31 +34 +64 +37 +63 +33 +65 +35 +34 +64 +38 +32 +37 +30 +39 +39 +62 +33 +61 +63 +65 +63 +61 +61 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +73 +65 +72 +64 +65 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +75 +69 +6e +74 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +39 +2e +33 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +31 +32 +66 +30 +33 +61 +66 +37 +63 +63 +66 +30 +31 +64 +64 +36 +31 +31 +63 +63 +34 +35 +30 +61 +30 +64 +31 +30 +64 +62 +63 +39 +62 +37 +34 +35 +37 +37 +30 +64 +30 +39 +36 +34 +37 +33 +65 +32 +66 +61 +66 +30 +63 +61 +36 +65 +32 +64 +36 +36 +64 +31 +65 +30 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +62 +79 +74 +65 +6f +72 +64 +65 +72 +22 +2c +0a +20 +22 +63 +72 +75 +6e +63 +68 +79 +22 +2c +0a +20 +22 +68 +65 +78 +22 +2c +0a +20 +22 +73 +74 +61 +74 +69 +63 +5f +61 +73 +73 +65 +72 +74 +69 +6f +6e +73 +22 +2c +0a +5d +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +75 +6e +69 +63 +6f +64 +65 +2d +78 +69 +64 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +32 +2e +32 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +38 +63 +63 +62 +38 +32 +64 +36 +31 +66 +38 +30 +61 +36 +36 +33 +65 +66 +65 +31 +66 +37 +38 +37 +61 +35 +31 +62 +31 +36 +62 +35 +61 +35 +31 +65 +33 +33 +31 +34 +64 +36 +61 +63 +33 +36 +35 +62 +30 +38 +36 +33 +39 +66 +35 +32 +33 +38 +37 +62 +33 +33 +66 +33 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +77 +61 +73 +69 +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +31 +30 +2e +32 +2b +77 +61 +73 +69 +2d +73 +6e +61 +70 +73 +68 +6f +74 +2d +70 +72 +65 +76 +69 +65 +77 +31 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +66 +64 +36 +66 +62 +64 +39 +61 +37 +39 +38 +32 +39 +64 +64 +31 +61 +64 +30 +63 +63 +32 +30 +36 +32 +37 +62 +66 +31 +65 +64 +36 +30 +36 +37 +35 +36 +61 +37 +66 +37 +37 +65 +64 +66 +66 +37 +62 +36 +36 +62 +37 +30 +36 +34 +66 +39 +63 +62 +33 +32 +37 +63 +36 +22 +0a +0a +5b +5b +70 +61 +63 +6b +61 +67 +65 +5d +5d +0a +6e +61 +6d +65 +20 +3d +20 +22 +77 +79 +7a +22 +0a +76 +65 +72 +73 +69 +6f +6e +20 +3d +20 +22 +30 +2e +35 +2e +30 +22 +0a +73 +6f +75 +72 +63 +65 +20 +3d +20 +22 +72 +65 +67 +69 +73 +74 +72 +79 +2b +68 +74 +74 +70 +73 +3a +2f +2f +67 +69 +74 +68 +75 +62 +2e +63 +6f +6d +2f +72 +75 +73 +74 +2d +6c +61 +6e +67 +2f +63 +72 +61 +74 +65 +73 +2e +69 +6f +2d +69 +6e +64 +65 +78 +22 +0a +63 +68 +65 +63 +6b +73 +75 +6d +20 +3d +20 +22 +33 +30 +62 +33 +31 +35 +39 +34 +66 +32 +39 +64 +32 +37 +30 +33 +36 +63 +33 +38 +33 +62 +35 +33 +62 +35 +39 +65 +64 +33 +34 +37 +36 +38 +37 +34 +64 +35 +31 +38 +66 +30 +65 +66 +62 +31 +35 +31 +62 +32 +37 +61 +34 +63 +32 +37 +35 +31 +34 +31 +33 +39 +30 +65 +22 +0a +64 +65 +70 +65 +6e +64 +65 +6e +63 +69 +65 +73 +20 +3d +20 +5b +0a +20 +22 +74 +61 +70 +22 +2c +0a +5d +0a +`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) "00" 1`] = `00`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) "01" 1`] = `01`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) "ff" 1`] = `ff`; + +snapshot[`\$.hex(\$.sizedUint8Array(16)) "dd0000dd0000eeeeeeee00000cc000cc" 1`] = ` +dd +00 +00 +dd +00 +00 +ee +ee +ee +ee +00 +00 +0c +c0 +00 +cc +`; + +snapshot[`\$.hex(\$.sizedUint8Array(16)) "dd0000dd0000ee000000000000cccc00" 1`] = ` +dd +00 +00 +dd +00 +00 +ee +00 +00 +00 +00 +00 +00 +cc +cc +00 +`; + +snapshot[`\$.hex(\$.sizedUint8Array(16)) "dddddddd0000eeeeeeee0000000cc000" 1`] = ` +dd +dd +dd +dd +00 +00 +ee +ee +ee +ee +00 +00 +00 +0c +c0 +00 +`; + +snapshot[`\$.hex(\$.sizedUint8Array(16)) "dd0000dd0000ee000000000000cccc00" 2`] = ` +dd +00 +00 +dd +00 +00 +ee +00 +00 +00 +00 +00 +00 +cc +cc +00 +`; + +snapshot[`\$.hex(\$.sizedUint8Array(16)) "dd0000dd0000eeeeeeee00000cc000cc" 2`] = ` +dd +00 +00 +dd +00 +00 +ee +ee +ee +ee +00 +00 +0c +c0 +00 +cc +`; + +snapshot[`\$.hex(\$.uint8Array) invalid null 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.uint8Array) invalid 4660 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.uint8Array) invalid "0y00" 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.uint8Array) invalid "hex" 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.uint8Array) invalid "0x000000000000000000000." 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.uint8Array) invalid Uint8Array(5) [ 0, 1, 2, 3, 4 ] 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid null 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid 4660 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "0y00" 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "hex" 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "0x000000000000000000000." 1`] = `ScaleAssertError: value: invalid hex`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid Uint8Array(5) [ 0, 1, 2, 3, 4 ] 1`] = `ScaleAssertError: typeof value !== "string"`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "0000" 1`] = `ScaleAssertError: value#encode.length !== 1`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "" 1`] = `ScaleAssertError: value#encode.length !== 1`; + +snapshot[`\$.hex(\$.sizedUint8Array(1)) invalid "-1" 1`] = `ScaleAssertError: value: invalid hex`; diff --git a/codecs/test/hex.test.ts b/codecs/test/hex.test.ts new file mode 100644 index 0000000..8a60a03 --- /dev/null +++ b/codecs/test/hex.test.ts @@ -0,0 +1,47 @@ +import * as $ from "../../mod.ts" +import { testCodec, testInvalid } from "../../test-util.ts" +import { encodeHex } from "../hex.ts" + +const $unsizedHex = $.hex($.uint8Array) + +testCodec($unsizedHex, [ + "", + "000102030405", + "deadbeef", + encodeHex(await Deno.readFile("Cargo.lock")), +]) + +testCodec($.hex($.sizedUint8Array(1)), [ + "00", + "01", + "ff", +]) + +testCodec($.hex($.sizedUint8Array(16)), [ + "dd0000dd0000eeeeeeee00000cc000cc", + "dd0000dd0000ee000000000000cccc00", + "dddddddd0000eeeeeeee0000000cc000", + "dd0000dd0000ee000000000000cccc00", + "dd0000dd0000eeeeeeee00000cc000cc", +]) + +testInvalid($unsizedHex, [ + null, + 0x1234, + "0y00", + "hex", + "0x000000000000000000000.", + new Uint8Array([0, 1, 2, 3, 4]), +]) + +testInvalid($.hex($.sizedUint8Array(1)), [ + null, + 0x1234, + "0y00", + "hex", + "0x000000000000000000000.", + new Uint8Array([0, 1, 2, 3, 4]), + "0000", + "", + "-1", +]) diff --git a/common/mod.ts b/common/mod.ts index b599786..5cafe71 100644 --- a/common/mod.ts +++ b/common/mod.ts @@ -1,4 +1,4 @@ -// moderate --exclude *.test.ts +// moderate export * from "./assert.ts" export * from "./buffer.ts" diff --git a/fixtures.rs b/fixtures.rs index c238754..9e787bf 100644 --- a/fixtures.rs +++ b/fixtures.rs @@ -18,6 +18,9 @@ pub mod deferred_fixtures; #[path = "./codecs/fixtures/float.rs"] pub mod float_fixtures; +#[path = "./codecs/fixtures/hex.rs"] +pub mod hex_fixtures; + #[path = "./codecs/fixtures/int.rs"] pub mod int_fixtures;