From 969c24ce8352400b177d6a8a3572afc4da79750a Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 13 Oct 2026 10:18:29 +0700 Subject: [PATCH 1/5] feat(skill-tree): add agentkit.skill-tree/v1 digest, archive readers and identity rules Add @skillx/skill-tree, a TypeScript implementation of the AgentKit skill tree contract shared with the AgentKit CLI: - canonical serialization and sha256 tree digest - path, NFC and case-fold collision rules on Unicode 15.0.0 tables generated from pinned inputs, never runtime Intl data - streaming tar/tar.gz and zip readers with exact entry, file and byte limits enforced while content streams (pull-driven inflate) - package identity, alias and directory alias rules, provenance trust and frontmatter exposure The AgentKit conformance vectors are vendored unedited with a provenance note and sha256 drift tests; every tree and identity vector passes. Negative tests cover links, special entries, sparse files, unsafe modes and names, case collisions, damaged archives and decompression bombs. Refs #54 --- packages/skill-tree/.gitattributes | 3 + packages/skill-tree/fixtures/PROVENANCE.md | 34 + .../fixtures/ucd/CaseFolding-15.0.0.txt | 1624 +++++++++ .../fixtures/vectors/identity-v1-vectors.json | 782 +++++ .../vectors/skill-tree-v1-vectors.json | 3091 +++++++++++++++++ packages/skill-tree/package.json | 23 + .../skill-tree/scripts/dump-go-unicode.go | 106 + .../skill-tree/scripts/gen-unicode-tables.mjs | 130 + .../skill-tree/scripts/unicode-15.0.0-go.json | 1 + packages/skill-tree/src/byte-source.ts | 172 + packages/skill-tree/src/collision.ts | 86 + packages/skill-tree/src/entry-collector.ts | 71 + packages/skill-tree/src/errors.ts | 42 + packages/skill-tree/src/exposure.ts | 76 + packages/skill-tree/src/identity.ts | 153 + packages/skill-tree/src/index.ts | 50 + packages/skill-tree/src/path-rules.ts | 155 + packages/skill-tree/src/serialize.ts | 86 + packages/skill-tree/src/tar-header.ts | 159 + packages/skill-tree/src/tar-reader.ts | 159 + packages/skill-tree/src/tree.ts | 170 + packages/skill-tree/src/unicode-15-tables.ts | 14 + packages/skill-tree/src/unicode-15.ts | 200 ++ packages/skill-tree/src/zip-reader.ts | 147 + packages/skill-tree/src/zip-records.ts | 200 ++ .../skill-tree/test/identity-vectors.test.ts | 132 + packages/skill-tree/test/path-fuzz.test.ts | 72 + packages/skill-tree/test/provenance.test.ts | 104 + packages/skill-tree/test/tar-reader.test.ts | 153 + packages/skill-tree/test/tar-writer.ts | 94 + packages/skill-tree/test/tree-vectors.test.ts | 127 + packages/skill-tree/test/vector-helpers.ts | 162 + packages/skill-tree/test/zip-reader.test.ts | 95 + packages/skill-tree/test/zip-writer.ts | 78 + packages/skill-tree/tsconfig.json | 17 + packages/skill-tree/vitest.config.ts | 8 + pnpm-lock.yaml | 82 +- vitest.config.ts | 1 + 38 files changed, 8829 insertions(+), 30 deletions(-) create mode 100644 packages/skill-tree/.gitattributes create mode 100644 packages/skill-tree/fixtures/PROVENANCE.md create mode 100644 packages/skill-tree/fixtures/ucd/CaseFolding-15.0.0.txt create mode 100644 packages/skill-tree/fixtures/vectors/identity-v1-vectors.json create mode 100644 packages/skill-tree/fixtures/vectors/skill-tree-v1-vectors.json create mode 100644 packages/skill-tree/package.json create mode 100644 packages/skill-tree/scripts/dump-go-unicode.go create mode 100644 packages/skill-tree/scripts/gen-unicode-tables.mjs create mode 100644 packages/skill-tree/scripts/unicode-15.0.0-go.json create mode 100644 packages/skill-tree/src/byte-source.ts create mode 100644 packages/skill-tree/src/collision.ts create mode 100644 packages/skill-tree/src/entry-collector.ts create mode 100644 packages/skill-tree/src/errors.ts create mode 100644 packages/skill-tree/src/exposure.ts create mode 100644 packages/skill-tree/src/identity.ts create mode 100644 packages/skill-tree/src/index.ts create mode 100644 packages/skill-tree/src/path-rules.ts create mode 100644 packages/skill-tree/src/serialize.ts create mode 100644 packages/skill-tree/src/tar-header.ts create mode 100644 packages/skill-tree/src/tar-reader.ts create mode 100644 packages/skill-tree/src/tree.ts create mode 100644 packages/skill-tree/src/unicode-15-tables.ts create mode 100644 packages/skill-tree/src/unicode-15.ts create mode 100644 packages/skill-tree/src/zip-reader.ts create mode 100644 packages/skill-tree/src/zip-records.ts create mode 100644 packages/skill-tree/test/identity-vectors.test.ts create mode 100644 packages/skill-tree/test/path-fuzz.test.ts create mode 100644 packages/skill-tree/test/provenance.test.ts create mode 100644 packages/skill-tree/test/tar-reader.test.ts create mode 100644 packages/skill-tree/test/tar-writer.ts create mode 100644 packages/skill-tree/test/tree-vectors.test.ts create mode 100644 packages/skill-tree/test/vector-helpers.ts create mode 100644 packages/skill-tree/test/zip-reader.test.ts create mode 100644 packages/skill-tree/test/zip-writer.ts create mode 100644 packages/skill-tree/tsconfig.json create mode 100644 packages/skill-tree/vitest.config.ts diff --git a/packages/skill-tree/.gitattributes b/packages/skill-tree/.gitattributes new file mode 100644 index 0000000..35fee4c --- /dev/null +++ b/packages/skill-tree/.gitattributes @@ -0,0 +1,3 @@ +# Pinned inputs are hashed byte for byte; never convert their line endings. +fixtures/** -text +scripts/unicode-15.0.0-go.json -text diff --git a/packages/skill-tree/fixtures/PROVENANCE.md b/packages/skill-tree/fixtures/PROVENANCE.md new file mode 100644 index 0000000..887cce0 --- /dev/null +++ b/packages/skill-tree/fixtures/PROVENANCE.md @@ -0,0 +1,34 @@ +# Fixture provenance + +These files are vendored unedited. Tests pin each by sha256 (`test/provenance.test.ts`), so any +edit or line-ending conversion fails the suite. A vector change is an AgentKit contract change: +update by copying the new upstream file and its new hash, never by editing a vector here. + +| File | Source | Commit | sha256 | +|---|---|---|---| +| `vectors/skill-tree-v1-vectors.json` | `bestagentkits/agentkit` `docs/conformance/skill-lifecycle/skill-tree-v1-vectors.json` | `dev` @ `479483bfe8ff022063f7bff21e75df17fabf0997` (git blob `ecb6722af896f41b176e5f5a5e1ba367c58449aa`) | `8eb46f1b8bec49cace740b75614f28f8fb4a6fc266fecfcd7e3d6892f28f3172` | +| `vectors/identity-v1-vectors.json` | `bestagentkits/agentkit` `docs/conformance/skill-lifecycle/identity-v1-vectors.json` | `dev` @ `479483bfe8ff022063f7bff21e75df17fabf0997` (git blob `d532820a500e792eef6445b0e54ba49554ab3fa6`) | `1ab9e013c229d78871abd60e3cd3bf26fcfd0e6067d98dcdd79b4f6bcc1daefb` | +| `ucd/CaseFolding-15.0.0.txt` | Unicode 15.0.0 `CaseFolding.txt`, as vendored by AgentKit at `apps/cli/internal/core/skilltree/testdata/CaseFolding-15.0.0.txt` | `840d924a7` (branch `mrgoonie/feat/skilltree-canonical-digest`) | `cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7` | + +The contract: AgentKit `docs/specs/skill-lifecycle-contract.md` sections 2, 4 and 10.2, and +`docs/specs/skill-lifecycle-schemas.md` section 2.1. + +## Unicode tables + +`src/unicode-15-tables.ts` is generated by `scripts/gen-unicode-tables.mjs` from two pinned +inputs: the case folding file above, and `scripts/unicode-15.0.0-go.json`, which +`scripts/dump-go-unicode.go` writes from the Go `unicode` tables (go1.25.3) and +`golang.org/x/text/unicode/norm` (Unicode 15.0.0), the same tables the AgentKit reference +implementation validates paths with. To regenerate: + +```sh +cd /apps/cli && go run /packages/skill-tree/scripts/dump-go-unicode.go > /packages/skill-tree/scripts/unicode-15.0.0-go.json +cd /packages/skill-tree && node scripts/gen-unicode-tables.mjs +``` + +`scripts/unicode-15.0.0-go.json` is pinned at sha256 +`baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5` (generator and tests). +Tests check the fold table against the case folding file, and the category and combining-class +tables against the Go dump, for every code point. They also check +normalization against the runtime's `String.prototype.normalize` for every code point assigned +in Unicode 15.0.0 (normalization stability makes later Unicode versions agree on those). diff --git a/packages/skill-tree/fixtures/ucd/CaseFolding-15.0.0.txt b/packages/skill-tree/fixtures/ucd/CaseFolding-15.0.0.txt new file mode 100644 index 0000000..65aa0fc --- /dev/null +++ b/packages/skill-tree/fixtures/ucd/CaseFolding-15.0.0.txt @@ -0,0 +1,1624 @@ +# CaseFolding-15.0.0.txt +# Date: 2022-02-02, 23:35:35 GMT +# © 2022 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see https://www.unicode.org/reports/tr44/ +# +# Case Folding Properties +# +# This file is a supplement to the UnicodeData file. +# It provides a case folding mapping generated from the Unicode Character Database. +# If all characters are mapped according to the full mapping below, then +# case differences (according to UnicodeData.txt and SpecialCasing.txt) +# are eliminated. +# +# The data supports both implementations that require simple case foldings +# (where string lengths don't change), and implementations that allow full case folding +# (where string lengths may grow). Note that where they can be supported, the +# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. +# +# All code points not listed in this file map to themselves. +# +# NOTE: case folding does not preserve normalization formats! +# +# For information on case folding, including how to have case folding +# preserve normalization formats, see Section 3.13 Default Case Algorithms in +# The Unicode Standard. +# +# ================================================================================ +# Format +# ================================================================================ +# The entries in this file are in the following machine-readable format: +# +# ; ; ; # +# +# The status field is: +# C: common case folding, common mappings shared by both simple and full mappings. +# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. +# S: simple case folding, mappings to single characters where different from F. +# T: special case for uppercase I and dotted uppercase I +# - For non-Turkic languages, this mapping is normally not used. +# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. +# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. +# See the discussions of case mapping in the Unicode Standard for more information. +# +# Usage: +# A. To do a simple case folding, use the mappings with status C + S. +# B. To do a full case folding, use the mappings with status C + F. +# +# The mappings with status T can be used or omitted depending on the desired case-folding +# behavior. (The default option is to exclude them.) +# +# ================================================================= + +# Property: Case_Folding + +# All code points not explicitly listed for Case_Folding +# have the value C for the status field, and the code point itself for the mapping field. + +# ================================================================= +0041; C; 0061; # LATIN CAPITAL LETTER A +0042; C; 0062; # LATIN CAPITAL LETTER B +0043; C; 0063; # LATIN CAPITAL LETTER C +0044; C; 0064; # LATIN CAPITAL LETTER D +0045; C; 0065; # LATIN CAPITAL LETTER E +0046; C; 0066; # LATIN CAPITAL LETTER F +0047; C; 0067; # LATIN CAPITAL LETTER G +0048; C; 0068; # LATIN CAPITAL LETTER H +0049; C; 0069; # LATIN CAPITAL LETTER I +0049; T; 0131; # LATIN CAPITAL LETTER I +004A; C; 006A; # LATIN CAPITAL LETTER J +004B; C; 006B; # LATIN CAPITAL LETTER K +004C; C; 006C; # LATIN CAPITAL LETTER L +004D; C; 006D; # LATIN CAPITAL LETTER M +004E; C; 006E; # LATIN CAPITAL LETTER N +004F; C; 006F; # LATIN CAPITAL LETTER O +0050; C; 0070; # LATIN CAPITAL LETTER P +0051; C; 0071; # LATIN CAPITAL LETTER Q +0052; C; 0072; # LATIN CAPITAL LETTER R +0053; C; 0073; # LATIN CAPITAL LETTER S +0054; C; 0074; # LATIN CAPITAL LETTER T +0055; C; 0075; # LATIN CAPITAL LETTER U +0056; C; 0076; # LATIN CAPITAL LETTER V +0057; C; 0077; # LATIN CAPITAL LETTER W +0058; C; 0078; # LATIN CAPITAL LETTER X +0059; C; 0079; # LATIN CAPITAL LETTER Y +005A; C; 007A; # LATIN CAPITAL LETTER Z +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON +0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE +0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK +0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE +0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON +010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON +0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE +0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON +0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE +0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK +011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON +011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE +0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA +0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE +0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE +012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON +012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE +012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK +0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132; C; 0133; # LATIN CAPITAL LIGATURE IJ +0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA +0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE +013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA +013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON +013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE +0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE +0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA +0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON +0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A; C; 014B; # LATIN CAPITAL LETTER ENG +014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON +014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE +0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152; C; 0153; # LATIN CAPITAL LIGATURE OE +0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE +0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA +0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON +015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE +015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA +0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON +0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA +0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON +0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE +0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE +016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON +016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE +016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE +0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK +0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE +017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON +017F; C; 0073; # LATIN SMALL LETTER LONG S +0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK +0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR +0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX +0186; C; 0254; # LATIN CAPITAL LETTER OPEN O +0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK +0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D +018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK +018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR +018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E +018F; C; 0259; # LATIN CAPITAL LETTER SCHWA +0190; C; 025B; # LATIN CAPITAL LETTER OPEN E +0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK +0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK +0194; C; 0263; # LATIN CAPITAL LETTER GAMMA +0196; C; 0269; # LATIN CAPITAL LETTER IOTA +0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE +0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK +019C; C; 026F; # LATIN CAPITAL LETTER TURNED M +019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK +019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN +01A2; C; 01A3; # LATIN CAPITAL LETTER OI +01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK +01A6; C; 0280; # LATIN LETTER YR +01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO +01A9; C; 0283; # LATIN CAPITAL LETTER ESH +01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK +01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN +01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON +01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK +01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK +01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE +01B7; C; 0292; # LATIN CAPITAL LETTER EZH +01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED +01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE +01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON +01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C7; C; 01C9; # LATIN CAPITAL LETTER LJ +01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CA; C; 01CC; # LATIN CAPITAL LETTER NJ +01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON +01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON +01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON +01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON +01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON +01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE +01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON +01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON +01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK +01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON +01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON +01F1; C; 01F3; # LATIN CAPITAL LETTER DZ +01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE +01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR +01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN +01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE +01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE +01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C; C; 021D; # LATIN CAPITAL LETTER YOGH +021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON +0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222; C; 0223; # LATIN CAPITAL LETTER OU +0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK +0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA +022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON +023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE +023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE +023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR +023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP +0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE +0244; C; 0289; # LATIN CAPITAL LETTER U BAR +0245; C; 028C; # LATIN CAPITAL LETTER TURNED V +0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE +0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE +024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE +024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE +0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI +0370; C; 0371; # GREEK CAPITAL LETTER HETA +0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F; C; 03F3; # GREEK CAPITAL LETTER YOT +0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS +038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS +038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA +0392; C; 03B2; # GREEK CAPITAL LETTER BETA +0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA +0394; C; 03B4; # GREEK CAPITAL LETTER DELTA +0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON +0396; C; 03B6; # GREEK CAPITAL LETTER ZETA +0397; C; 03B7; # GREEK CAPITAL LETTER ETA +0398; C; 03B8; # GREEK CAPITAL LETTER THETA +0399; C; 03B9; # GREEK CAPITAL LETTER IOTA +039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA +039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA +039C; C; 03BC; # GREEK CAPITAL LETTER MU +039D; C; 03BD; # GREEK CAPITAL LETTER NU +039E; C; 03BE; # GREEK CAPITAL LETTER XI +039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON +03A0; C; 03C0; # GREEK CAPITAL LETTER PI +03A1; C; 03C1; # GREEK CAPITAL LETTER RHO +03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA +03A4; C; 03C4; # GREEK CAPITAL LETTER TAU +03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON +03A6; C; 03C6; # GREEK CAPITAL LETTER PHI +03A7; C; 03C7; # GREEK CAPITAL LETTER CHI +03A8; C; 03C8; # GREEK CAPITAL LETTER PSI +03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA +03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA +03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL +03D0; C; 03B2; # GREEK BETA SYMBOL +03D1; C; 03B8; # GREEK THETA SYMBOL +03D5; C; 03C6; # GREEK PHI SYMBOL +03D6; C; 03C0; # GREEK PI SYMBOL +03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA +03DA; C; 03DB; # GREEK LETTER STIGMA +03DC; C; 03DD; # GREEK LETTER DIGAMMA +03DE; C; 03DF; # GREEK LETTER KOPPA +03E0; C; 03E1; # GREEK LETTER SAMPI +03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI +03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI +03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI +03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI +03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA +03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA +03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI +03F0; C; 03BA; # GREEK KAPPA SYMBOL +03F1; C; 03C1; # GREEK RHO SYMBOL +03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL +03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL +03F7; C; 03F8; # GREEK CAPITAL LETTER SHO +03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL +03FA; C; 03FB; # GREEK CAPITAL LETTER SAN +03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE +0401; C; 0451; # CYRILLIC CAPITAL LETTER IO +0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE +0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE +0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE +0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407; C; 0457; # CYRILLIC CAPITAL LETTER YI +0408; C; 0458; # CYRILLIC CAPITAL LETTER JE +0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE +040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE +040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE +040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE +040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE +040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U +040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE +0410; C; 0430; # CYRILLIC CAPITAL LETTER A +0411; C; 0431; # CYRILLIC CAPITAL LETTER BE +0412; C; 0432; # CYRILLIC CAPITAL LETTER VE +0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE +0414; C; 0434; # CYRILLIC CAPITAL LETTER DE +0415; C; 0435; # CYRILLIC CAPITAL LETTER IE +0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE +0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE +0418; C; 0438; # CYRILLIC CAPITAL LETTER I +0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I +041A; C; 043A; # CYRILLIC CAPITAL LETTER KA +041B; C; 043B; # CYRILLIC CAPITAL LETTER EL +041C; C; 043C; # CYRILLIC CAPITAL LETTER EM +041D; C; 043D; # CYRILLIC CAPITAL LETTER EN +041E; C; 043E; # CYRILLIC CAPITAL LETTER O +041F; C; 043F; # CYRILLIC CAPITAL LETTER PE +0420; C; 0440; # CYRILLIC CAPITAL LETTER ER +0421; C; 0441; # CYRILLIC CAPITAL LETTER ES +0422; C; 0442; # CYRILLIC CAPITAL LETTER TE +0423; C; 0443; # CYRILLIC CAPITAL LETTER U +0424; C; 0444; # CYRILLIC CAPITAL LETTER EF +0425; C; 0445; # CYRILLIC CAPITAL LETTER HA +0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE +0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE +0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA +0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA +042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN +042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU +042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN +042D; C; 044D; # CYRILLIC CAPITAL LETTER E +042E; C; 044E; # CYRILLIC CAPITAL LETTER YU +042F; C; 044F; # CYRILLIC CAPITAL LETTER YA +0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA +0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT +0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E +0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS +0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS +046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI +0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI +0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA +0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA +0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478; C; 0479; # CYRILLIC CAPITAL LETTER UK +047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA +047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E; C; 047F; # CYRILLIC CAPITAL LETTER OT +0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA +048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK +0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE +0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE +04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA +04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE +04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA +04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U +04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE +04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA +04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA +04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE +04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK +04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL +04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK +04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL +04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL +04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE +04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE +04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE +04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA +04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON +04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O +04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON +04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE +0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE +0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE +0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE +0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE +0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE +050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE +050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE +050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE +0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE +0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK +0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA +0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA +0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE +051A; C; 051B; # CYRILLIC CAPITAL LETTER QA +051C; C; 051D; # CYRILLIC CAPITAL LETTER WE +051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA +0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE +052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE +052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER +0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB +0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN +0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM +0534; C; 0564; # ARMENIAN CAPITAL LETTER DA +0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH +0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA +0537; C; 0567; # ARMENIAN CAPITAL LETTER EH +0538; C; 0568; # ARMENIAN CAPITAL LETTER ET +0539; C; 0569; # ARMENIAN CAPITAL LETTER TO +053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE +053B; C; 056B; # ARMENIAN CAPITAL LETTER INI +053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN +053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH +053E; C; 056E; # ARMENIAN CAPITAL LETTER CA +053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN +0540; C; 0570; # ARMENIAN CAPITAL LETTER HO +0541; C; 0571; # ARMENIAN CAPITAL LETTER JA +0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD +0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH +0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN +0545; C; 0575; # ARMENIAN CAPITAL LETTER YI +0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW +0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA +0548; C; 0578; # ARMENIAN CAPITAL LETTER VO +0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA +054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH +054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH +054C; C; 057C; # ARMENIAN CAPITAL LETTER RA +054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH +054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW +054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN +0550; C; 0580; # ARMENIAN CAPITAL LETTER REH +0551; C; 0581; # ARMENIAN CAPITAL LETTER CO +0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN +0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR +0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH +0555; C; 0585; # ARMENIAN CAPITAL LETTER OH +0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH +0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN +10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN +10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN +10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN +10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON +10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN +10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN +10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN +10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN +10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN +10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN +10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS +10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN +10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR +10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON +10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR +10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR +10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE +10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN +10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR +10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN +10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR +10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR +10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN +10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR +10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN +10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN +10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN +10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL +10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL +10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR +10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN +10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN +10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE +10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE +10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE +10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE +10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR +10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE +10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN +10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN +13F8; C; 13F0; # CHEROKEE SMALL LETTER YE +13F9; C; 13F1; # CHEROKEE SMALL LETTER YI +13FA; C; 13F2; # CHEROKEE SMALL LETTER YO +13FB; C; 13F3; # CHEROKEE SMALL LETTER YU +13FC; C; 13F4; # CHEROKEE SMALL LETTER YV +13FD; C; 13F5; # CHEROKEE SMALL LETTER MV +1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE +1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE +1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O +1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES +1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE +1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE +1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN +1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT +1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK +1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN +1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN +1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN +1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON +1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN +1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN +1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN +1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN +1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN +1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN +1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS +1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN +1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR +1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON +1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR +1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR +1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE +1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN +1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR +1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN +1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR +1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR +1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN +1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR +1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN +1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN +1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN +1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL +1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL +1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR +1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN +1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN +1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE +1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE +1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE +1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE +1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR +1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE +1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI +1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN +1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI +1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN +1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN +1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN +1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN +1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW +1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW +1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW +1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW +1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW +1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA +1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW +1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON +1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW +1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS +1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA +1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW +1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE +1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW +1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW +1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW +1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW +1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE +1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW +1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE +1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW +1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW +1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE +1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE +1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW +1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW +1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW +1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW +1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW +1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE +1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW +1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE +1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE +1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS +1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW +1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE +1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE +1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW +1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW +1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS +1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE +1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE +1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING +1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE +1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S +1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S +1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW +1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE +1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW +1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE +1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE +1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE +1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW +1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW +1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE +1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW +1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE +1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE +1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW +1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE +1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL +1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V +1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP +1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI +1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA +1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI +1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA +1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI +1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA +1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI +1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA +1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI +1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA +1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI +1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA +1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA +1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI +1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI +1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA +1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI +1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY +1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON +1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA +1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA +1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FBE; C; 03B9; # GREEK PROSGEGRAMMENI +1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI +1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI +1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA +1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA +1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA +1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA +1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI +1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY +1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON +1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA +1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA +1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI +1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI +1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY +1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON +1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA +1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA +1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA +1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI +1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI +1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA +1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA +1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA +1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA +1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +2126; C; 03C9; # OHM SIGN +212A; C; 006B; # KELVIN SIGN +212B; C; 00E5; # ANGSTROM SIGN +2132; C; 214E; # TURNED CAPITAL F +2160; C; 2170; # ROMAN NUMERAL ONE +2161; C; 2171; # ROMAN NUMERAL TWO +2162; C; 2172; # ROMAN NUMERAL THREE +2163; C; 2173; # ROMAN NUMERAL FOUR +2164; C; 2174; # ROMAN NUMERAL FIVE +2165; C; 2175; # ROMAN NUMERAL SIX +2166; C; 2176; # ROMAN NUMERAL SEVEN +2167; C; 2177; # ROMAN NUMERAL EIGHT +2168; C; 2178; # ROMAN NUMERAL NINE +2169; C; 2179; # ROMAN NUMERAL TEN +216A; C; 217A; # ROMAN NUMERAL ELEVEN +216B; C; 217B; # ROMAN NUMERAL TWELVE +216C; C; 217C; # ROMAN NUMERAL FIFTY +216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED +216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED +216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND +2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED +24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A +24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B +24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C +24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D +24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E +24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F +24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G +24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H +24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I +24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J +24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K +24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L +24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M +24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N +24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O +24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P +24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q +24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R +24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S +24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T +24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U +24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V +24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W +24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X +24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y +24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z +2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU +2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY +2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE +2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI +2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO +2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU +2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE +2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO +2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA +2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE +2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE +2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I +2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI +2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO +2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE +2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE +2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI +2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU +2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI +2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI +2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO +2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO +2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU +2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU +2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU +2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU +2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE +2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA +2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI +2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI +2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA +2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU +2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI +2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI +2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA +2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU +2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS +2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO +2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS +2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA +2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA +2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC +2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A +2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C2F; C; 2C5F; # GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI +2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR +2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE +2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE +2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL +2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER +2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER +2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER +2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA +2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK +2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A +2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA +2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK +2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H +2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL +2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA +2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA +2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA +2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA +2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE +2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU +2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA +2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE +2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE +2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA +2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA +2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA +2C98; C; 2C99; # COPTIC CAPITAL LETTER MI +2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI +2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI +2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O +2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI +2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO +2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA +2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU +2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA +2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI +2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI +2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI +2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU +2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA +2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI +2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI +2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI +2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH +2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI +2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA +2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT +2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU +2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI +A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA +A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO +A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE +A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA +A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV +A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK +A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA +A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER +A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT +A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU +A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A +A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS +A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN +A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE +A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE +A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL +A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM +A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +A680; C; A681; # CYRILLIC CAPITAL LETTER DWE +A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE +A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE +A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE +A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE +A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE +A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE +A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE +A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE +A694; C; A695; # CYRILLIC CAPITAL LETTER HWE +A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE +A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O +A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O +A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +A726; C; A727; # LATIN CAPITAL LETTER HENG +A728; C; A729; # LATIN CAPITAL LETTER TZ +A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO +A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO +A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +A732; C; A733; # LATIN CAPITAL LETTER AA +A734; C; A735; # LATIN CAPITAL LETTER AO +A736; C; A737; # LATIN CAPITAL LETTER AU +A738; C; A739; # LATIN CAPITAL LETTER AV +A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73C; C; A73D; # LATIN CAPITAL LETTER AY +A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT +A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE +A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +A746; C; A747; # LATIN CAPITAL LETTER BROKEN L +A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE +A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP +A74E; C; A74F; # LATIN CAPITAL LETTER OO +A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH +A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA +A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA +A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +A760; C; A761; # LATIN CAPITAL LETTER VY +A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z +A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE +A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +A768; C; A769; # LATIN CAPITAL LETTER VEND +A76A; C; A76B; # LATIN CAPITAL LETTER ET +A76C; C; A76D; # LATIN CAPITAL LETTER IS +A76E; C; A76F; # LATIN CAPITAL LETTER CON +A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D +A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F +A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G +A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G +A780; C; A781; # LATIN CAPITAL LETTER TURNED L +A782; C; A783; # LATIN CAPITAL LETTER INSULAR R +A784; C; A785; # LATIN CAPITAL LETTER INSULAR S +A786; C; A787; # LATIN CAPITAL LETTER INSULAR T +A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO +A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H +A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER +A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR +A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH +A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE +A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE +A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE +A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE +A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK +A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E +A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G +A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT +A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I +A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K +A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T +A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL +A7B3; C; AB53; # LATIN CAPITAL LETTER CHI +A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA +A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA +A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE +A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A +A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I +A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U +A7C0; C; A7C1; # LATIN CAPITAL LETTER OLD POLISH O +A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W +A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK +A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK +A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK +A7C7; C; A7C8; # LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY +A7C9; C; A7CA; # LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7D0; C; A7D1; # LATIN CAPITAL LETTER CLOSED INSULAR G +A7D6; C; A7D7; # LATIN CAPITAL LETTER MIDDLE SCOTS S +A7D8; C; A7D9; # LATIN CAPITAL LETTER SIGMOID S +A7F5; C; A7F6; # LATIN CAPITAL LETTER REVERSED HALF H +AB70; C; 13A0; # CHEROKEE SMALL LETTER A +AB71; C; 13A1; # CHEROKEE SMALL LETTER E +AB72; C; 13A2; # CHEROKEE SMALL LETTER I +AB73; C; 13A3; # CHEROKEE SMALL LETTER O +AB74; C; 13A4; # CHEROKEE SMALL LETTER U +AB75; C; 13A5; # CHEROKEE SMALL LETTER V +AB76; C; 13A6; # CHEROKEE SMALL LETTER GA +AB77; C; 13A7; # CHEROKEE SMALL LETTER KA +AB78; C; 13A8; # CHEROKEE SMALL LETTER GE +AB79; C; 13A9; # CHEROKEE SMALL LETTER GI +AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO +AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU +AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV +AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA +AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE +AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI +AB80; C; 13B0; # CHEROKEE SMALL LETTER HO +AB81; C; 13B1; # CHEROKEE SMALL LETTER HU +AB82; C; 13B2; # CHEROKEE SMALL LETTER HV +AB83; C; 13B3; # CHEROKEE SMALL LETTER LA +AB84; C; 13B4; # CHEROKEE SMALL LETTER LE +AB85; C; 13B5; # CHEROKEE SMALL LETTER LI +AB86; C; 13B6; # CHEROKEE SMALL LETTER LO +AB87; C; 13B7; # CHEROKEE SMALL LETTER LU +AB88; C; 13B8; # CHEROKEE SMALL LETTER LV +AB89; C; 13B9; # CHEROKEE SMALL LETTER MA +AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME +AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI +AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO +AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU +AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA +AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA +AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH +AB91; C; 13C1; # CHEROKEE SMALL LETTER NE +AB92; C; 13C2; # CHEROKEE SMALL LETTER NI +AB93; C; 13C3; # CHEROKEE SMALL LETTER NO +AB94; C; 13C4; # CHEROKEE SMALL LETTER NU +AB95; C; 13C5; # CHEROKEE SMALL LETTER NV +AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA +AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE +AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI +AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO +AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU +AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV +AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA +AB9D; C; 13CD; # CHEROKEE SMALL LETTER S +AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE +AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI +ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO +ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU +ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV +ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA +ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA +ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE +ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE +ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI +ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI +ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO +ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU +ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV +ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA +ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA +ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE +ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI +ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO +ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU +ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV +ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA +ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE +ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI +ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO +ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU +ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV +ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA +ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE +ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI +ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO +ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU +ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV +ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA +FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF +FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI +FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL +FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI +FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL +FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T +FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST +FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW +FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH +FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI +FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW +FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH +FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A +FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B +FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C +FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D +FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E +FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F +FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G +FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H +FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I +FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J +FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K +FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L +FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M +FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N +FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O +FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P +FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q +FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R +FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S +FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T +FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U +FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V +FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W +FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X +FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y +FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z +10400; C; 10428; # DESERET CAPITAL LETTER LONG I +10401; C; 10429; # DESERET CAPITAL LETTER LONG E +10402; C; 1042A; # DESERET CAPITAL LETTER LONG A +10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH +10404; C; 1042C; # DESERET CAPITAL LETTER LONG O +10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO +10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I +10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E +10408; C; 10430; # DESERET CAPITAL LETTER SHORT A +10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH +1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O +1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO +1040C; C; 10434; # DESERET CAPITAL LETTER AY +1040D; C; 10435; # DESERET CAPITAL LETTER OW +1040E; C; 10436; # DESERET CAPITAL LETTER WU +1040F; C; 10437; # DESERET CAPITAL LETTER YEE +10410; C; 10438; # DESERET CAPITAL LETTER H +10411; C; 10439; # DESERET CAPITAL LETTER PEE +10412; C; 1043A; # DESERET CAPITAL LETTER BEE +10413; C; 1043B; # DESERET CAPITAL LETTER TEE +10414; C; 1043C; # DESERET CAPITAL LETTER DEE +10415; C; 1043D; # DESERET CAPITAL LETTER CHEE +10416; C; 1043E; # DESERET CAPITAL LETTER JEE +10417; C; 1043F; # DESERET CAPITAL LETTER KAY +10418; C; 10440; # DESERET CAPITAL LETTER GAY +10419; C; 10441; # DESERET CAPITAL LETTER EF +1041A; C; 10442; # DESERET CAPITAL LETTER VEE +1041B; C; 10443; # DESERET CAPITAL LETTER ETH +1041C; C; 10444; # DESERET CAPITAL LETTER THEE +1041D; C; 10445; # DESERET CAPITAL LETTER ES +1041E; C; 10446; # DESERET CAPITAL LETTER ZEE +1041F; C; 10447; # DESERET CAPITAL LETTER ESH +10420; C; 10448; # DESERET CAPITAL LETTER ZHEE +10421; C; 10449; # DESERET CAPITAL LETTER ER +10422; C; 1044A; # DESERET CAPITAL LETTER EL +10423; C; 1044B; # DESERET CAPITAL LETTER EM +10424; C; 1044C; # DESERET CAPITAL LETTER EN +10425; C; 1044D; # DESERET CAPITAL LETTER ENG +10426; C; 1044E; # DESERET CAPITAL LETTER OI +10427; C; 1044F; # DESERET CAPITAL LETTER EW +104B0; C; 104D8; # OSAGE CAPITAL LETTER A +104B1; C; 104D9; # OSAGE CAPITAL LETTER AI +104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN +104B3; C; 104DB; # OSAGE CAPITAL LETTER AH +104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA +104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA +104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA +104B7; C; 104DF; # OSAGE CAPITAL LETTER E +104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN +104B9; C; 104E1; # OSAGE CAPITAL LETTER HA +104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA +104BB; C; 104E3; # OSAGE CAPITAL LETTER I +104BC; C; 104E4; # OSAGE CAPITAL LETTER KA +104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA +104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA +104BF; C; 104E7; # OSAGE CAPITAL LETTER LA +104C0; C; 104E8; # OSAGE CAPITAL LETTER MA +104C1; C; 104E9; # OSAGE CAPITAL LETTER NA +104C2; C; 104EA; # OSAGE CAPITAL LETTER O +104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN +104C4; C; 104EC; # OSAGE CAPITAL LETTER PA +104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA +104C6; C; 104EE; # OSAGE CAPITAL LETTER SA +104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA +104C8; C; 104F0; # OSAGE CAPITAL LETTER TA +104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA +104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA +104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA +104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA +104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA +104CE; C; 104F6; # OSAGE CAPITAL LETTER U +104CF; C; 104F7; # OSAGE CAPITAL LETTER WA +104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA +104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA +104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA +104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA +10570; C; 10597; # VITHKUQI CAPITAL LETTER A +10571; C; 10598; # VITHKUQI CAPITAL LETTER BBE +10572; C; 10599; # VITHKUQI CAPITAL LETTER BE +10573; C; 1059A; # VITHKUQI CAPITAL LETTER CE +10574; C; 1059B; # VITHKUQI CAPITAL LETTER CHE +10575; C; 1059C; # VITHKUQI CAPITAL LETTER DE +10576; C; 1059D; # VITHKUQI CAPITAL LETTER DHE +10577; C; 1059E; # VITHKUQI CAPITAL LETTER EI +10578; C; 1059F; # VITHKUQI CAPITAL LETTER E +10579; C; 105A0; # VITHKUQI CAPITAL LETTER FE +1057A; C; 105A1; # VITHKUQI CAPITAL LETTER GA +1057C; C; 105A3; # VITHKUQI CAPITAL LETTER HA +1057D; C; 105A4; # VITHKUQI CAPITAL LETTER HHA +1057E; C; 105A5; # VITHKUQI CAPITAL LETTER I +1057F; C; 105A6; # VITHKUQI CAPITAL LETTER IJE +10580; C; 105A7; # VITHKUQI CAPITAL LETTER JE +10581; C; 105A8; # VITHKUQI CAPITAL LETTER KA +10582; C; 105A9; # VITHKUQI CAPITAL LETTER LA +10583; C; 105AA; # VITHKUQI CAPITAL LETTER LLA +10584; C; 105AB; # VITHKUQI CAPITAL LETTER ME +10585; C; 105AC; # VITHKUQI CAPITAL LETTER NE +10586; C; 105AD; # VITHKUQI CAPITAL LETTER NJE +10587; C; 105AE; # VITHKUQI CAPITAL LETTER O +10588; C; 105AF; # VITHKUQI CAPITAL LETTER PE +10589; C; 105B0; # VITHKUQI CAPITAL LETTER QA +1058A; C; 105B1; # VITHKUQI CAPITAL LETTER RE +1058C; C; 105B3; # VITHKUQI CAPITAL LETTER SE +1058D; C; 105B4; # VITHKUQI CAPITAL LETTER SHE +1058E; C; 105B5; # VITHKUQI CAPITAL LETTER TE +1058F; C; 105B6; # VITHKUQI CAPITAL LETTER THE +10590; C; 105B7; # VITHKUQI CAPITAL LETTER U +10591; C; 105B8; # VITHKUQI CAPITAL LETTER VE +10592; C; 105B9; # VITHKUQI CAPITAL LETTER XE +10594; C; 105BB; # VITHKUQI CAPITAL LETTER Y +10595; C; 105BC; # VITHKUQI CAPITAL LETTER ZE +10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A +10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA +10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB +10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB +10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC +10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC +10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS +10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED +10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND +10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E +10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E +10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE +10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF +10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG +10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY +10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH +10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I +10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II +10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ +10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK +10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK +10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK +10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL +10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY +10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM +10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN +10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY +10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O +10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO +10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE +10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE +10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE +10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP +10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP +10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER +10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER +10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES +10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ +10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET +10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT +10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY +10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH +10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U +10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU +10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE +10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE +10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV +10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ +10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS +10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN +10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US +118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA +118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A +118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI +118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU +118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA +118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO +118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II +118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU +118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E +118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O +118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG +118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA +118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO +118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY +118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ +118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC +118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN +118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD +118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE +118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG +118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA +118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT +118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM +118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU +118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU +118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO +118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO +118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR +118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR +118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU +118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII +118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO +16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M +16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S +16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V +16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W +16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU +16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z +16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP +16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P +16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T +16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G +16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F +16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I +16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K +16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A +16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J +16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E +16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B +16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C +16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U +16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU +16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L +16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q +16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP +16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY +16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X +16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D +16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE +16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N +16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R +16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O +16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI +16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y +1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF +1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI +1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM +1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM +1E904; C; 1E926; # ADLAM CAPITAL LETTER BA +1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE +1E906; C; 1E928; # ADLAM CAPITAL LETTER PE +1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE +1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA +1E909; C; 1E92B; # ADLAM CAPITAL LETTER E +1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA +1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I +1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O +1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA +1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE +1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW +1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN +1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF +1E912; C; 1E934; # ADLAM CAPITAL LETTER YA +1E913; C; 1E935; # ADLAM CAPITAL LETTER U +1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM +1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI +1E916; C; 1E938; # ADLAM CAPITAL LETTER HA +1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF +1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA +1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA +1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU +1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA +1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA +1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA +1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE +1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL +1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO +1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA +# +# EOF diff --git a/packages/skill-tree/fixtures/vectors/identity-v1-vectors.json b/packages/skill-tree/fixtures/vectors/identity-v1-vectors.json new file mode 100644 index 0000000..d532820 --- /dev/null +++ b/packages/skill-tree/fixtures/vectors/identity-v1-vectors.json @@ -0,0 +1,782 @@ +{ + "schema": "agentkit.identity-vectors/v1", + "spec": "docs/specs/skill-lifecycle-contract.md#2-identity", + "pattern": "^@[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$", + "notes": [ + "Each identity segment must also pass the canonical-tree segment rules and be at most 64 bytes.", + "kitMapping rows without an error give the identity and portable alias of a kit skill directory.", + "provenance rows give the trust recorded for an accepted identity, or the rejection code. An unknown provider, a kit row without a known origin, an invalid identity, or a kit row whose identity is not @agentkit fails with identity.invalid; these checks run before the reserved-publisher check. verified on a skillx row says whether the release provenance verified.", + "aliases rows are invocation aliases. An alias is 1 to 128 characters from [A-Za-z0-9._:/$-]; '$' may appear anywhere. A leading '/' is allowed only in the native slash form '/:', a single segment after the '/'. Split on '/', the alias has no empty, '.' or '..' segment, so no trailing '/'; every ':' in a segment has non-empty text on both sides; and every segment, and every ':'-separated part of one, holds at least one ASCII letter or digit, so '$', '$$' and '/$:x' are invalid. Any other alias, including a non-ASCII one, fails with identity.invalid.", + "Reserved prefixes: after removing every leading '/' of the alias and every leading '$' of each '/'-separated segment, if any segment starts with ak- or ak:, compared after mapping only ASCII A-Z to a-z, the alias is reserved for @agentkit identities; any other identity fails with identity.reserved_alias. Shape errors are checked first.", + "directoryAliases rows are projection directory names (the portable runtime alias): an alias that is one segment, passes the canonical-tree segment rules (so it never starts with .ak-tmp.) and contains no ':' or '$'; otherwise identity.invalid, then the reserved-prefix check. groupKey is the alias with only ASCII A-Z mapped to a-z; collision and co-ownership grouping use it on every host. directoryAliasCollisions pairs collide exactly when their groupKeys are equal.", + "exposure rows apply to every reader that derives exposure, SkillX included. They give either frontmatter, the YAML text between the delimiter lines, or file, a whole SKILL.md, and the derived exposure. Frontmatter is the block between a first line '---' and the next '---' line, after removing a UTF-8 BOM, a CR before each LF, and trailing spaces or tabs on the delimiter lines. Only top-level plain YAML scalars true, True, TRUE, false, False and FALSE are booleans; quoted strings, yes, no, on, off, 1 and other spellings count as absent.", + "A parse failure is a YAML 1.2 syntax error. A duplicate key other than the two exposure keys is not one (the TypeScript yaml package needs uniqueKeys: false).", + "warning is true when the frontmatter is unterminated or fails to parse, when it holds a YAML value that is not a mapping (a scalar, a sequence or null, such as '~'), or when either key is duplicated, carries an explicit tag, or uses an anchor or alias; exposure is then AUTO. Frontmatter that holds no YAML document at all, because it is empty or only comments, is AUTO without a warning." + ], + "kitMapping": [ + { + "kit": "core", + "dir": "ak-plan", + "identity": "@agentkit/plan", + "portableAlias": "ak-plan" + }, + { + "kit": "core", + "dir": "ak-test", + "identity": "@agentkit/test", + "portableAlias": "ak-test" + }, + { + "kit": "engineer", + "dir": "ak-code-review", + "identity": "@agentkit/code-review", + "portableAlias": "ak-code-review" + }, + { + "kit": "marketing", + "dir": "ak-youtube-thumbnail-design", + "identity": "@agentkit/youtube-thumbnail-design", + "portableAlias": "ak-youtube-thumbnail-design" + }, + { + "kit": "core", + "dir": "plan", + "error": "identity.invalid" + }, + { + "kit": "core", + "dir": "ak-", + "error": "identity.invalid" + }, + { + "kit": "core", + "dir": "ak-Plan", + "error": "identity.invalid" + }, + { + "kit": "core", + "dir": "ak-con", + "error": "identity.invalid" + }, + { + "kit": "core", + "dir": "ak-notes.", + "error": "identity.invalid" + } + ], + "valid": [ + "@agentkit/plan", + "@acme/my_skill.v2", + "@a/b", + "@0pub/0-x", + "@pub/a-", + "@pub/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ], + "invalid": [ + { + "value": "agentkit/plan", + "error": "identity.invalid" + }, + { + "value": "@Agentkit/plan", + "error": "identity.invalid" + }, + { + "value": "@agentkit/Plan", + "error": "identity.invalid" + }, + { + "value": "@-pub/x", + "error": "identity.invalid" + }, + { + "value": "@pub/", + "error": "identity.invalid" + }, + { + "value": "@pub/a/b", + "error": "identity.invalid" + }, + { + "value": "@pub/a b", + "error": "identity.invalid" + }, + { + "value": "ak:plan", + "error": "identity.invalid" + }, + { + "value": "@pub/con", + "error": "identity.invalid" + }, + { + "value": "@pub/aux.x", + "error": "identity.invalid" + }, + { + "value": "@con/x", + "error": "identity.invalid" + }, + { + "value": "@pub/a.", + "error": "identity.invalid" + }, + { + "value": "@pub/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "error": "identity.invalid" + }, + { + "value": "@ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp/x", + "error": "identity.invalid" + } + ], + "provenance": [ + { + "identity": "@agentkit/plan", + "provider": "kit", + "origin": "remote-signed", + "expect": { + "trust": "signed-kit" + } + }, + { + "identity": "@agentkit/plan", + "provider": "kit", + "origin": "local-dev", + "expect": { + "trust": "local-unverified" + } + }, + { + "identity": "@agentkit/plan", + "provider": "kit", + "origin": "remote-signed", + "overlay": true, + "expect": { + "trust": "local-unverified" + } + }, + { + "identity": "@agentkit/plan", + "provider": "kit", + "origin": "mirror", + "expect": { + "error": "identity.invalid" + } + }, + { + "identity": "@agentkit/plan", + "provider": "kit", + "expect": { + "error": "identity.invalid" + } + }, + { + "identity": "@agentkit/plan", + "provider": "skillx", + "verified": true, + "expect": { + "error": "identity.reserved_publisher" + } + }, + { + "identity": "@agentkit/plan", + "provider": "local", + "expect": { + "error": "identity.reserved_publisher" + } + }, + { + "identity": "@agentkit/plan", + "provider": "git", + "expect": { + "error": "identity.reserved_publisher" + } + }, + { + "identity": "@acme/plan", + "provider": "skillx", + "verified": true, + "expect": { + "trust": "publisher-signed" + } + }, + { + "identity": "@acme/plan", + "provider": "skillx", + "verified": false, + "expect": { + "trust": "local-unverified" + } + }, + { + "identity": "@acme/plan", + "provider": "local", + "expect": { + "trust": "local-unverified" + } + }, + { + "identity": "@acme/plan", + "provider": "git", + "expect": { + "trust": "local-unverified" + } + }, + { + "identity": "@acme/plan", + "provider": "npm", + "expect": { + "error": "identity.invalid" + } + }, + { + "identity": "@agentkit/plan", + "provider": "npm", + "expect": { + "error": "identity.invalid" + } + }, + { + "identity": "@acme/plan", + "provider": "kit", + "origin": "remote-signed", + "expect": { + "error": "identity.invalid" + } + }, + { + "identity": "@agentkit/Plan", + "provider": "kit", + "origin": "remote-signed", + "expect": { + "error": "identity.invalid" + } + } + ], + "aliases": [ + { + "identity": "@agentkit/plan", + "alias": "ak-plan", + "error": null + }, + { + "identity": "@agentkit/plan", + "alias": "ak:plan", + "error": null + }, + { + "identity": "@evil/plan", + "alias": "ak-plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "ak:plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "AK-plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@acme/plan", + "alias": "plan", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "acme-plan", + "error": null + }, + { + "identity": "@evil/plan", + "alias": "aK-plan", + "error": "identity.invalid" + }, + { + "identity": "@evil/plan", + "alias": "аk-plan", + "error": "identity.invalid" + }, + { + "identity": "@agentkit/plan", + "alias": "aK-plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "my plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "acme/plan", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "a//b", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "./plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "acme/.", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "acme/..", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "acme/", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/acme-plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "//plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/acme:plan", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "/acme/x:plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a$b", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "plan!", + "error": "identity.invalid" + }, + { + "identity": "@agentkit/plan", + "alias": "/ak:plan", + "error": null + }, + { + "identity": "@evil/plan", + "alias": "/ak:plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@agentkit/plan", + "alias": "$ak:plan", + "error": null + }, + { + "identity": "@evil/plan", + "alias": "$AK:plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "$$ak:plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "/$ak:plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "$/ak:plan", + "error": "identity.invalid" + }, + { + "identity": "@evil/plan", + "alias": "core/ak-plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@agentkit/plan", + "alias": "core/ak-plan", + "error": null + }, + { + "identity": "@acme/plan", + "alias": ":", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/:", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "acme:", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": ":plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/acme:", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a::b", + "error": "identity.invalid" + }, + { + "identity": "@evil/plan", + "alias": "x/$ak-plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@agentkit/plan", + "alias": "x/$ak-plan", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "$", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "$$", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/$:x", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a/-/b", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "/a:b:c", + "error": null + }, + { + "identity": "@acme/plan", + "alias": "/a:$:c", + "error": "identity.invalid" + } + ], + "directoryAliases": [ + { + "identity": "@agentkit/plan", + "alias": "ak-plan", + "error": null, + "groupKey": "ak-plan" + }, + { + "identity": "@acme/foo", + "alias": "Foo", + "error": null, + "groupKey": "foo" + }, + { + "identity": "@other/foo", + "alias": "foo", + "error": null, + "groupKey": "foo" + }, + { + "identity": "@acme/foo", + "alias": "foo-2", + "error": null, + "groupKey": "foo-2" + }, + { + "identity": "@acme/plan", + "alias": "con", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "CON", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "aux.md", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "plan.", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "plan ", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a:b", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a$b", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "a/b", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "PROGRA~1", + "error": "identity.invalid" + }, + { + "identity": "@evil/plan", + "alias": "ak-plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@evil/plan", + "alias": "AK-Plan", + "error": "identity.reserved_alias" + }, + { + "identity": "@acme/plan", + "alias": ".ak-tmp.plan", + "error": "identity.invalid" + }, + { + "identity": "@acme/plan", + "alias": "---", + "error": "identity.invalid" + } + ], + "directoryAliasCollisions": [ + { + "aliases": ["Foo", "foo"], + "collide": true + }, + { + "aliases": ["foo", "foo-2"], + "collide": false + } + ], + "exposure": [ + { + "frontmatter": "", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "user-invocable: false", + "exposure": "INTERNAL", + "warning": false + }, + { + "frontmatter": "user-invocable: False", + "exposure": "INTERNAL", + "warning": false + }, + { + "frontmatter": "user-invocable: FALSE", + "exposure": "INTERNAL", + "warning": false + }, + { + "frontmatter": "user-invocable: fAlse", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "user-invocable: \"false\"", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "user-invocable: no", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "user-invocable: off", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: true", + "exposure": "EXPLICIT", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: True", + "exposure": "EXPLICIT", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: TRUE", + "exposure": "EXPLICIT", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: yes", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: on", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: 'true'", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: 1", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: true\nuser-invocable: false", + "exposure": "INTERNAL", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: true\nuser-invocable: true", + "exposure": "EXPLICIT", + "warning": false + }, + { + "frontmatter": "disable-model-invocation: true\nuser-invocable: yes", + "exposure": "EXPLICIT", + "warning": false + }, + { + "frontmatter": "user-invocable: false ", + "exposure": "INTERNAL", + "warning": false + }, + { + "frontmatter": "user-invocable: !!bool false", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "user-invocable: &x false", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "a: &x false\nuser-invocable: *x", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "user-invocable: false\nuser-invocable: false", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "user-invocable: [false", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "nested:\n user-invocable: false", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "user-invocable", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "~", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "null", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "- user-invocable: false", + "exposure": "AUTO", + "warning": true + }, + { + "frontmatter": "# only a comment", + "exposure": "AUTO", + "warning": false + }, + { + "frontmatter": "name: a\nname: b\nuser-invocable: false", + "exposure": "INTERNAL", + "warning": false + }, + { + "file": "---\r\nuser-invocable: false\r\n---\r\n# Skill\r\n", + "exposure": "INTERNAL", + "warning": false + }, + { + "file": "--- \ndisable-model-invocation: true\n---\n# Skill\n", + "exposure": "EXPLICIT", + "warning": false + }, + { + "file": "# Skill\n---\nuser-invocable: false\n---\n", + "exposure": "AUTO", + "warning": false + }, + { + "file": "---\nuser-invocable: false\n# no closing line\n", + "exposure": "AUTO", + "warning": true + } + ] +} diff --git a/packages/skill-tree/fixtures/vectors/skill-tree-v1-vectors.json b/packages/skill-tree/fixtures/vectors/skill-tree-v1-vectors.json new file mode 100644 index 0000000..ecb6722 --- /dev/null +++ b/packages/skill-tree/fixtures/vectors/skill-tree-v1-vectors.json @@ -0,0 +1,3091 @@ +{ + "schema": "agentkit.skill-tree-vectors/v1", + "contract": "agentkit.skill-tree/v1", + "spec": "docs/specs/skill-lifecycle-contract.md#4-canonical-tree-agentkitskill-treev1", + "unicode": "15.0.0", + "notes": [ + "files[].content is UTF-8 text; files[].contentBase64 is raw bytes.", + "synthesize[] appends count files: {n} in pathPattern is the zero-based index as five decimal digits, and each file holds size bytes of value fill, with mode 100644 unless mode is given.", + "files[] come before synthesized files; input order never changes a digest.", + "files[].type is the entry kind an archive reader or walker reports: file (the default), fs-hardlink and reparse-other are read as regular files; symlink, archive-hardlink, reparse-name-surrogate, reparse-af-unix, reparse-wsl, device, fifo, socket and cont (tar type '7') fail with tree.unsupported_entry; directory and pax-global (a PAX 'g' header) add nothing to the tree but count toward the entry limit. A directory entry name must pass the path and segment rules but gets no NFC check; it may end with one '/', which is not part of its path, and '//' is unsafe. A pax-global name is metadata and is not checked.", + "An entry is a header that Go archive/tar Reader.Next returns. PAX 'x' and GNU long-name headers fold into the following entry and never appear in files[].", + "A directory, symlink or reparse-name-surrogate entry whose own name is a noise directory name is noise and is dropped without being followed. A non-directory entry of any type whose own name is a noise file name is noise; a directory with such a name is an ordinary directory.", + "A directory entry also takes part in the file-versus-directory check: a file equal to a directory entry path is tree.unsafe_path, and one equal under case folding is tree.case_collision. Directory entries are compared only with files, never with each other or with implied directories. A directory that a walker presents is a directory entry too, given without a trailing '/'; so an empty walked directory 'a' next to a file 'A' is tree.case_collision.", + "A pax-global entry whose paxRecords include path, linkpath, size or any GNU.sparse.* key fails with tree.unsupported_entry. Global records never apply to other entries.", + "files[].headerMode, when present, is the raw tar header mode in octal and replaces mode: the type bits (0o170000) are removed and the rest must be exactly 0644 or 0755.", + "type tar-nul is an old-style tar type NUL entry: a regular file, or a directory when its name ends with '/'. No other type is reclassified by a trailing '/'; a file entry 'refs/' is tree.unsafe_path.", + "files[].rawPathBase64, when present, replaces path with raw name bytes. Names that are not valid UTF-8 (including an unpaired UTF-16 surrogate, given as its WTF-8 bytes) fail with tree.unsafe_path; zip names are judged the same way whatever their UTF-8 flag says.", + "synthesize[].type, when present, sets the entry type of every synthesized entry.", + "A segment that starts with .ak-tmp. fails with tree.unsafe_path. Segment lengths count UTF-8 bytes, and paths sort by UTF-8 bytes, never by UTF-16 code units.", + "tree.read_failed has no vector: it depends on a read error, not on entry data.", + "files[].paxRecords, when present, are the PAX records of that archive entry.", + "Vectors model archive reading: the total entry limit counts every entry in files[] and synthesize[] of any type, including directory, pax-global, rejected types and noise; the tree root is not an entry; the file limit counts regular-file entries only.", + "files[] and synthesize[] are the entries the input presents. An archive presents every entry, noise included; a directory walker presents noise files it visits but prunes noise directories without presenting their contents.", + "Case collisions compare NFD(fold(NFD(path))) with full case folding (CaseFolding.txt statuses C and F), for files and for every directory prefix.", + "Vectors with expect.error must fail with exactly that code; no digest is defined.", + "Walker conformance materializes each vector as a directory: every non-directory entry becomes a file at its path with its bytes (or the item its type names), every directory entry and every parent of a path becomes a directory, and the walker walks the result, never listing a pruned noise directory or a directory whose own path is unsafe. Each directory it walks counts as one entry. A vector whose entries the host cannot create (devices, case-colliding or reserved names, invalid names on Windows) is skipped on that host.", + "files[].mode other than 100644 and 100755 is a tar header or git index mode. A walker maps permission bits instead and never rejects them: any execute bit gives 100755, otherwise 100644. On a host without modes (Windows), walker runs skip positive vectors that contain 100755.", + "archiveOnly: true marks a vector that binds archive readers only, and walker conformance skips it: one with more than one defect (more than one validation step fails on its own), one with no on-disk form (an archive-only type or field, an empty, '.' or '..' path segment, a NUL, a segment over 255 UTF-16 code units, a file mode other than 100644, 100755 or 120000, two entries with one path, or a file whose path is also a directory), one that tests archive entry counting (limit-entries-count-noise), or one whose materialized walk gives a different result, such as an entry count that the walked parent directories change.", + "A positive vector without expect.serialization defines only the digest." + ], + "vectors": [ + { + "id": "skill-md-only", + "description": "SKILL.md only", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072", + "serialization": "agentkit.skill-tree/v1\n100644 ec6d8a678a93b3b18a897464bb6822196ce268d5bf60496fc8a58d8efc9ae975 55 SKILL.md\n" + } + }, + { + "id": "empty-file", + "description": "a zero-byte file is a valid entry", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "# x\n" + }, + { + "path": "assets/empty.txt", + "mode": "100644", + "content": "" + } + ], + "expect": { + "digest": "sha256:31151fd31caaceb55e3eda419340a67a5e77dbad94985c5336b8d86c3b44f8aa", + "serialization": "agentkit.skill-tree/v1\n100644 253b610bd786f2543252c8d4b45bb40eb375882587f825cb9ce1fd1241f66f1e 4 SKILL.md\n100644 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 assets/empty.txt\n" + } + }, + { + "id": "nested-resources", + "description": "references, scripts, assets and modules", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-nested\ndescription: Nested.\n---\n" + }, + { + "path": "references/guide.md", + "mode": "100644", + "content": "# Guide\n" + }, + { + "path": "references/deep/a/b/c.md", + "mode": "100644", + "content": "deep\n" + }, + { + "path": "scripts/run.sh", + "mode": "100755", + "content": "#!/bin/sh\necho ok\n" + }, + { + "path": "scripts/lib/util.py", + "mode": "100644", + "content": "print('ok')\n" + }, + { + "path": "assets/logo.bin", + "mode": "100644", + "contentBase64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" + } + ], + "expect": { + "digest": "sha256:9b7717f1b8c9906a84ca6ac4a3f4464aae53b6aed8973aaa5f9321e69b426b30", + "serialization": "agentkit.skill-tree/v1\n100644 c1640b40572bdcc4ea152cd5a5199c53be4e3edf45b4b459f87faca0ab6fb9aa 45 SKILL.md\n100644 40aff2e9d2d8922e47afd4648e6967497158785fbd1da870e7110266bf944880 256 assets/logo.bin\n100644 64896f89fd11190013b70103e603a1c5826e56b7fb7d2197ab279b0690043599 5 references/deep/a/b/c.md\n100644 bc553ffe57e544498b12a9865dbf3abc2004c474e349c52c378eaa402287424b 8 references/guide.md\n100644 ad64355106bb158b020ecf9702be48f7730fc091dd4bb6a2f092b40393495b3d 12 scripts/lib/util.py\n100755 b4d644d4279594903f1a9911956432d9473041f2984fc6014c14d7402c7d126c 18 scripts/run.sh\n" + } + }, + { + "id": "input-order-independent", + "description": "nested-resources listed in reverse order", + "files": [ + { + "path": "assets/logo.bin", + "mode": "100644", + "contentBase64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" + }, + { + "path": "scripts/lib/util.py", + "mode": "100644", + "content": "print('ok')\n" + }, + { + "path": "scripts/run.sh", + "mode": "100755", + "content": "#!/bin/sh\necho ok\n" + }, + { + "path": "references/deep/a/b/c.md", + "mode": "100644", + "content": "deep\n" + }, + { + "path": "references/guide.md", + "mode": "100644", + "content": "# Guide\n" + }, + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-nested\ndescription: Nested.\n---\n" + } + ], + "expect": { + "digest": "sha256:9b7717f1b8c9906a84ca6ac4a3f4464aae53b6aed8973aaa5f9321e69b426b30" + } + }, + { + "id": "mode-differs", + "description": "same bytes as nested-resources but run.sh is not executable", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-nested\ndescription: Nested.\n---\n" + }, + { + "path": "references/guide.md", + "mode": "100644", + "content": "# Guide\n" + }, + { + "path": "references/deep/a/b/c.md", + "mode": "100644", + "content": "deep\n" + }, + { + "path": "scripts/run.sh", + "mode": "100644", + "content": "#!/bin/sh\necho ok\n" + }, + { + "path": "scripts/lib/util.py", + "mode": "100644", + "content": "print('ok')\n" + }, + { + "path": "assets/logo.bin", + "mode": "100644", + "contentBase64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" + } + ], + "expect": { + "digest": "sha256:fc8f3e327b2f3fb536150dd78173fb53e2da8add0b60921bc55754573f979174", + "serialization": "agentkit.skill-tree/v1\n100644 c1640b40572bdcc4ea152cd5a5199c53be4e3edf45b4b459f87faca0ab6fb9aa 45 SKILL.md\n100644 40aff2e9d2d8922e47afd4648e6967497158785fbd1da870e7110266bf944880 256 assets/logo.bin\n100644 64896f89fd11190013b70103e603a1c5826e56b7fb7d2197ab279b0690043599 5 references/deep/a/b/c.md\n100644 bc553ffe57e544498b12a9865dbf3abc2004c474e349c52c378eaa402287424b 8 references/guide.md\n100644 ad64355106bb158b020ecf9702be48f7730fc091dd4bb6a2f092b40393495b3d 12 scripts/lib/util.py\n100644 b4d644d4279594903f1a9911956432d9473041f2984fc6014c14d7402c7d126c 18 scripts/run.sh\n" + } + }, + { + "id": "byte-order-sort", + "description": "sort is by UTF-8 bytes: uppercase before lowercase, '-' before '/'", + "files": [ + { + "path": "b.md", + "mode": "100644", + "content": "b\n" + }, + { + "path": "B2.md", + "mode": "100644", + "content": "B\n" + }, + { + "path": "a-b.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a/b.md", + "mode": "100644", + "content": "y\n" + }, + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "expect": { + "digest": "sha256:223c0846c918d769aba4428a1e67fed9bd6533115d451f4148d5185e44b410d5", + "serialization": "agentkit.skill-tree/v1\n100644 c0cde77fa8fef97d476c10aad3d2d54fcc2f336140d073651c2dcccf1e379fd6 2 B2.md\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 a-b.md\n100644 3bb2abb69ebb27fbfe63c7639624c6ec5e331b841a5bc8c3ebc10b9285e90877 2 a/b.md\n100644 0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f 2 b.md\n" + } + }, + { + "id": "unicode-nfc", + "description": "an NFC non-ASCII path", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references/café.md", + "mode": "100644", + "content": "café\n" + } + ], + "expect": { + "digest": "sha256:dc15e15e754f7fb2f6424b22ede37f80bdcc62db26fc6e712557111eee9fe521", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 7b49b9e063bd91a4f9252b413261f5557b9c570aa61516989499f64a62dbcdd6 6 references/café.md\n" + } + }, + { + "id": "crlf-preserved", + "description": "line endings are bytes; no normalization", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "line1\r\nline2\r\n" + } + ], + "expect": { + "digest": "sha256:846cc6452343bb974f16a18c8150f5c3018488d21f7d24a4789296368cfdcf48", + "serialization": "agentkit.skill-tree/v1\n100644 4ad3ef64dfb83f7a8f789bce6f30cc1f8d18491b14db4c875309b150d2a7d213 14 SKILL.md\n" + } + }, + { + "id": "tilde-not-short-name", + "description": "a tilde not followed by a digit, or in a base longer than 8 bytes, is allowed", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "my~notes.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "abcdefghi~1.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "digest": "sha256:ec5cda9e95f4d5eb8d705d0a889adc38a222be6759654060ece96c367c93972e", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 3bb2abb69ebb27fbfe63c7639624c6ec5e331b841a5bc8c3ebc10b9285e90877 2 abcdefghi~1.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 my~notes.md\n" + } + }, + { + "id": "dotted-capital-i-vs-i", + "description": "U+0130 fully folds to 'i' plus U+0307, which stays distinct from 'i'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "İ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "i.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "digest": "sha256:9f13a5f0b5de100ad63e7e5fe02caf0063f5159492fb929e84eb67c29f7fd33a", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f 2 i.md\n100644 87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7 2 İ.md\n" + } + }, + { + "id": "dotless-i-vs-i", + "description": "U+0131 has no C or F case folding, so it stays distinct from 'i'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ı.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "i.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "digest": "sha256:bc563cbbc73d784a65958e391e10e1aea647eb74be01e5e821452935b4c240cd", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f 2 i.md\n100644 87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7 2 ı.md\n" + } + }, + { + "id": "noise-excluded", + "description": "noise entries are dropped before hashing; digest equals skill-md-only", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + }, + { + "path": ".DS_Store", + "mode": "100644", + "content": "junk" + }, + { + "path": "scripts/__pycache__/x.pyc", + "mode": "100644", + "content": "junk" + }, + { + "path": ".git/HEAD", + "mode": "100644", + "content": "ref\n" + }, + { + "path": "references/Thumbs.db", + "mode": "100644", + "content": "junk" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072" + } + }, + { + "id": "noise-dropped-before-validation", + "description": "entries under noise directories are dropped before type and path checks", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + }, + { + "path": ".git/CON", + "mode": "100644", + "content": "x\n" + }, + { + "path": "__pycache__/link", + "mode": "120000", + "content": "../x" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072" + } + }, + { + "id": "noise-exact-case", + "description": "noise names match exactly; .GIT/ and thumbs.db are content", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": ".GIT/config", + "mode": "100644", + "content": "c\n" + }, + { + "path": "thumbs.db", + "mode": "100644", + "content": "t\n" + } + ], + "expect": { + "digest": "sha256:7046b4fa72a5a9af6d3327b84f3fe9db4f967757f438b02d3c8a5baf538f0b8d", + "serialization": "agentkit.skill-tree/v1\n100644 a3a5e715f0cc574a73c3f9bebb6bc24f32ffd5b67b387244c2c909da779a1478 2 .GIT/config\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 fe8edeeb98cc6d3b93cf2d57000254b84bd9eba34b4df7ce4b87db8b937b7703 2 thumbs.db\n" + } + }, + { + "id": "noise-junction-dropped", + "description": "a junction named .git is dropped as noise and never followed", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + }, + { + "path": ".git", + "mode": "100644", + "type": "reparse-name-surrogate", + "content": "" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072" + } + }, + { + "id": "noise-symlink-dropped", + "description": "a symbolic link named __pycache__ is dropped as noise and never followed", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + }, + { + "path": "scripts/__pycache__", + "mode": "120000", + "type": "symlink", + "content": "/tmp" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072" + } + }, + { + "id": "git-file-is-content", + "description": "a file named .git (not a directory) is content", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": ".git", + "mode": "100644", + "content": "gitdir: ../x\n" + } + ], + "expect": { + "digest": "sha256:5900ff0fa2963ebcca7b38d25db68df667a5fb604e5f82adc1b2e64887b8ac88", + "serialization": "agentkit.skill-tree/v1\n100644 fed6d21816e6fb4c12b8d6c46fec90a93fba25d2b0da2fe0292314bd04adbdba 13 .git\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + } + }, + { + "id": "abs-path", + "description": "rejected path \"/etc/passwd\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "/etc/passwd", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "dotdot", + "description": "rejected path \"references/../../x.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references/../../x.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "dot-segment", + "description": "rejected path \"./SKILL.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "./SKILL.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "empty-segment", + "description": "rejected path \"references//a.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references//a.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "backslash", + "description": "rejected path \"references\\\\a.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references\\a.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "colon-drive", + "description": "rejected path \"C:/x.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "C:/x.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "colon-ads", + "description": "rejected path \"SKILL.md:evil\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "SKILL.md:evil", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "lt", + "description": "rejected path \"ab.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a>b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "dquote", + "description": "rejected path \"a\\\"b.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a\"b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "pipe", + "description": "rejected path \"a|b.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a|b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "question", + "description": "rejected path \"a?.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a?.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "star", + "description": "rejected path \"a*.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a*.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "nul", + "description": "rejected path \"a\\u0000b.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a\u0000b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "newline", + "description": "rejected path \"a\\nb.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a\nb.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "del", + "description": "rejected path \"a\\u007fb.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ab.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "c1-control", + "description": "rejected path \"a\\u0085b.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a…b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "cf-zero-width-space", + "description": "rejected path \"SKILL\\u200b.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "SKILL​.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "cf-rtl-override", + "description": "rejected path \"a\\u202eb.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a‮b.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "cf-bom", + "description": "rejected path \"\\ufeffa.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "unassigned", + "description": "rejected path \"\\u0378.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "͸.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "unassigned-in-15-0", + "description": "rejected path \"\\u2ffc.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "⿼.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "trailing-dot", + "description": "rejected path \"notes.\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "notes.", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "trailing-space", + "description": "rejected path \"notes \"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "notes ", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-con", + "description": "rejected path \"CON\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "CON", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-lpt1-ext", + "description": "rejected path \"assets/lpt1.txt\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "assets/lpt1.txt", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-nul-lower", + "description": "rejected path \"nul.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "nul.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-first-dot", + "description": "rejected path \"nul.tar.gz\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "nul.tar.gz", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-space-before-ext", + "description": "rejected path \"CON .txt\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "CON .txt", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-com0", + "description": "rejected path \"com0.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "com0.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-com-superscript", + "description": "rejected path \"COM\\u00b9.txt\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "COM¹.txt", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-conin", + "description": "rejected path \"CONIN$\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "CONIN$", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "reserved-conout-ext", + "description": "rejected path \"conout$.log\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "conout$.log", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "short-name", + "description": "rejected path \"PROGRA~1\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "PROGRA~1", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "short-name-ext", + "description": "rejected path \"longfi~1.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "longfi~1.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "short-name-dir", + "description": "rejected path \"docs~2/a.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "docs~2/a.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "segment-too-long", + "description": "rejected path \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "path-too-long", + "description": "rejected path \"dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/f.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/dddddddddddddddddddddddddddddddddddddddddddddddddd/f.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "too-deep", + "description": "rejected path \"d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/f.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/f.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "non-nfc", + "description": "rejected path \"references/cafe\\u0301.md\"", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references/café.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.non_nfc_path" + } + }, + { + "id": "case-collision", + "description": "SKILL.md vs skill.md", + "files": [ + { + "path": "x.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "SKILL.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "skill.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-latin1", + "description": "U+00C9 vs U+00E9", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "É.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "é.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-capital-sharp-s", + "description": "U+1E9E folds to U+00DF", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ẞ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ß.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-long-s", + "description": "U+017F folds to 's'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ſ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "s.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-final-sigma", + "description": "U+03C2 folds to U+03C3", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ς.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "σ.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-capital-sigma", + "description": "U+03A3 and U+03C2 meet at U+03C3", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "Σ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ς.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-cherokee", + "description": "U+AB70 folds to U+13A0 under CaseFolding.txt", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "Ꭰ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ꭰ.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-cherokee-small", + "description": "U+13F8 folds to U+13F0 under CaseFolding.txt", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "Ᏸ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ᏸ.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-sharp-s-ss", + "description": "U+00DF fully folds to 'ss'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ß.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ss.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-capital-sharp-s-ss", + "description": "U+1E9E fully folds to 'ss'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ẞ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ss.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-fi-ligature", + "description": "U+FB01 is NFC and fully folds to 'fi'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "fi.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "fi.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "case-collision-decomposed-fold", + "description": "U+1E9B folds to U+1E61; both sides meet as 's' plus U+0307 after NFD", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ẛ.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "ṡ.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "kelvin-sign-not-nfc", + "description": "KELVIN SIGN U+212A is not NFC (it decomposes to 'K'), so it fails before case folding", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "K.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.non_nfc_path" + } + }, + { + "id": "file-dir-conflict", + "description": "a file 'a' and a path under 'a/' with the same name", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a/b.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "file-dir-conflict-case", + "description": "a file 'A' and a path under 'a/' that differ only by case", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "A", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a/b.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "dir-case-collision", + "description": "directories 'A' and 'a' differ only by case and would merge", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "A/x.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a/y.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "nested-dir-case-collision", + "description": "nested directories that differ only by case", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "refs/Docs/x.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "refs/docs/y.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "reserved-name-ascii-only-dotless-i", + "description": "reserved names map only ASCII a-z to A-Z, so U+0131 never matches 'I'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "conın$.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "digest": "sha256:7dceaa1e6864d00e7b653f83e091237775b51fcec93e6be7d194433a4adc5831", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 conın$.md\n" + } + }, + { + "id": "reserved-name-ascii-only-dotted-i", + "description": "reserved names map only ASCII a-z to A-Z, so U+0130 never matches 'I'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "conİn$.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "digest": "sha256:eca107117cd188102d1fb336077747b777487dea0f32d01b6319fed5b1ecae69", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 conİn$.md\n" + } + }, + { + "id": "depth-at-max", + "description": "exactly 32 segments, counting the file name", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/f.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "digest": "sha256:d518869768d056d8f1fb20024424c6e44006e2d50fb81a90873f384b926ffa03", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/d/f.md\n" + } + }, + { + "id": "directory-entry-adds-nothing", + "description": "an archive directory entry and a PAX global header add nothing to the tree", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references/", + "mode": "100644", + "type": "directory", + "content": "" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "" + } + ], + "expect": { + "digest": "sha256:96732f9ead4e00966bdd17e6157641ebdc9d2208d8f7aadb01fa18dbf089e53d", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + }, + "archiveOnly": true + }, + { + "id": "directory-entry-unsafe-name", + "description": "an archive directory entry name must pass the path rules", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "../x/", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "directory-entry-name-path-rules-only", + "description": "directory entry names get only the path rules: a non-NFC name and a case-only twin of a file's directory are accepted and add nothing", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "refs/x.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "Refs/", + "mode": "100644", + "type": "directory", + "content": "" + }, + { + "path": "café/", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "digest": "sha256:6106f63ecba8ca6cde8b1ba75f62603d371872af384bf6dd9955504f12d9b6df", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 refs/x.md\n" + } + }, + { + "id": "pax-global-name-not-checked", + "description": "PAX global header names are metadata and are not checked, so the names Python tarfile and GNU tar write are accepted", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "../pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "" + }, + { + "path": "././@PaxHeader", + "mode": "100644", + "type": "pax-global", + "content": "" + }, + { + "path": "/tmp/GlobalHead.4242.1", + "mode": "100644", + "type": "pax-global", + "content": "" + } + ], + "expect": { + "digest": "sha256:96732f9ead4e00966bdd17e6157641ebdc9d2208d8f7aadb01fa18dbf089e53d", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + }, + "archiveOnly": true + }, + { + "id": "pax-global-unchecked-name-records-rejected", + "description": "a PAX global header with an unchecked name still fails on a path record", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "././@PaxHeader", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "path": "x.md" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "pax-global-record-path", + "description": "a PAX global header carrying a path record is not supported", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "path": "x.md" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "pax-global-record-linkpath", + "description": "a PAX global header carrying a linkpath record is not supported", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "linkpath": "x.md" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "pax-global-record-size", + "description": "a PAX global header carrying a size record is not supported", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "size": "1" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "pax-global-record-gnu-sparse-major", + "description": "a PAX global header carrying a GNU.sparse.major record is not supported", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "GNU.sparse.major": "1" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "pax-global-comment-ignored", + "description": "a PAX global header with only a comment record, as git archive writes, is accepted and applies to no entry", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pax_global_header", + "mode": "100644", + "type": "pax-global", + "content": "", + "paxRecords": { + "comment": "0123456789abcdef0123456789abcdef01234567" + } + } + ], + "expect": { + "digest": "sha256:96732f9ead4e00966bdd17e6157641ebdc9d2208d8f7aadb01fa18dbf089e53d", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + }, + "archiveOnly": true + }, + { + "id": "header-mode-setuid", + "description": "a tar header mode 04755 keeps the setuid bit after the type bits are removed", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "run.sh", + "headerMode": "4755", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "header-mode-type-bits", + "description": "a tar header mode 0100644 is 0644 after the type bits are removed", + "files": [ + { + "path": "SKILL.md", + "headerMode": "100644", + "content": "s\n" + } + ], + "expect": { + "digest": "sha256:96732f9ead4e00966bdd17e6157641ebdc9d2208d8f7aadb01fa18dbf089e53d", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + }, + "archiveOnly": true + }, + { + "id": "tar-type-nul", + "description": "an old-style tar type NUL entry is a regular file, or a directory when its name ends with '/'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "notes.md", + "mode": "100644", + "type": "tar-nul", + "content": "n\n" + }, + { + "path": "refs/", + "mode": "100644", + "type": "tar-nul", + "content": "" + } + ], + "expect": { + "digest": "sha256:097a4ad327d9a2586a6b7c80dd99d4a6c20f96ac5e23d0202d7a7d621a137f6e" + }, + "archiveOnly": true + }, + { + "id": "noise-file-name-special-dropped", + "description": "a symbolic link or special file with a noise file name is dropped as noise", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "---\nname: ak-demo\ndescription: Demo skill.\n---\n\n# Demo\n" + }, + { + "path": ".DS_Store", + "mode": "120000", + "type": "symlink", + "content": "/tmp" + }, + { + "path": "references/Thumbs.db", + "mode": "100644", + "type": "fifo", + "content": "" + } + ], + "expect": { + "digest": "sha256:9bc8434a1aed589954b02ca5456c5fe6caa90eda6bcfec8fba3fd0c041e31072" + } + }, + { + "id": "file-vs-directory-entry", + "description": "a file 'a' and a directory entry 'a/' name the same path", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a/", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "file-vs-directory-entry-case", + "description": "a file 'a' and a directory entry 'A/' differ only by case", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a", + "mode": "100644", + "content": "x\n" + }, + { + "path": "A/", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "raw-name-invalid-utf8", + "description": "a raw name byte sequence that is not UTF-8 is never replaced by U+FFFD", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "rawPathBase64": "YmFk/y5tZA==", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "raw-name-unpaired-surrogate", + "description": "an unpaired UTF-16 surrogate in a name, given as its WTF-8 bytes", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "rawPathBase64": "7aCALm1k", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "contiguous-file-entry", + "description": "a tar contiguous-file entry (type '7') is not supported", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "data.bin", + "mode": "100644", + "type": "cont", + "content": "x" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "mode-0664", + "description": "permissions must be exactly 0644 or 0755", + "files": [ + { + "path": "SKILL.md", + "mode": "100664", + "content": "s\n" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "gitlink-160000", + "description": "a git index gitlink (mode 160000) is not a regular file", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "vendor", + "mode": "160000", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "dir-prefix-not-conflict", + "description": "'a' as a directory and 'ab' as a file do not conflict", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a/b.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "ab", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "digest": "sha256:5ffb8a63647dad3ce84f92291000412ff0702080d376a6255381387622e58ae9", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 a/b.md\n100644 3bb2abb69ebb27fbfe63c7639624c6ec5e331b841a5bc8c3ebc10b9285e90877 2 ab\n" + } + }, + { + "id": "archive-hardlink", + "description": "an archive hard-link entry", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "copy.md", + "mode": "100644", + "type": "archive-hardlink", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "junction", + "description": "a Windows junction, which is a name-surrogate reparse point", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "refs", + "mode": "100644", + "type": "reparse-name-surrogate", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "af-unix-reparse", + "description": "a Windows AF_UNIX socket reparse point", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "agent.sock", + "mode": "100644", + "type": "reparse-af-unix", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "wsl-reparse", + "description": "a WSL special-file reparse point", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "fifo", + "mode": "100644", + "type": "reparse-wsl", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "gnu-sparse-pax", + "description": "a regular-file entry carrying a GNU.sparse PAX record", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "data.bin", + "mode": "100644", + "content": "x", + "paxRecords": { + "GNU.sparse.major": "1", + "GNU.sparse.minor": "0" + } + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "fifo-entry", + "description": "a FIFO", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "pipe", + "mode": "100644", + "type": "fifo", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "device-entry", + "description": "a device node", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "dev", + "mode": "100644", + "type": "device", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "socket-entry", + "description": "a socket", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "sock", + "mode": "100644", + "type": "socket", + "content": "" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "fs-hardlink-read-as-file", + "description": "a filesystem hard link is read as an independent regular file", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "copy.md", + "mode": "100644", + "type": "fs-hardlink", + "content": "s\n" + } + ], + "expect": { + "digest": "sha256:575779d711e2542f300e742f99d46bb09b18e617d797dac0cea3a3aefad1c82e", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 copy.md\n" + } + }, + { + "id": "cloud-placeholder-read-as-file", + "description": "a reparse point without the name-surrogate bit, such as a cloud placeholder, is read as a regular file", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "notes.md", + "mode": "100644", + "type": "reparse-other", + "content": "n\n" + } + ], + "expect": { + "digest": "sha256:097a4ad327d9a2586a6b7c80dd99d4a6c20f96ac5e23d0202d7a7d621a137f6e", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 a4fb621495a0122493b2203591c448903c472e306a1ede54fabad829e01075c0 2 notes.md\n" + } + }, + { + "id": "duplicate-path", + "description": "the same path listed twice", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "SKILL.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "error": "tree.case_collision" + }, + "archiveOnly": true + }, + { + "id": "bad-mode", + "description": "mode must be 100644 or 100755", + "files": [ + { + "path": "SKILL.md", + "mode": "100777", + "content": "s\n" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "symlink-entry", + "description": "a symlink entry is never followed or stored", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "link", + "mode": "120000", + "content": "../outside" + } + ], + "expect": { + "error": "tree.unsupported_entry" + } + }, + { + "id": "empty-tree", + "description": "a tree must contain at least one file", + "files": [], + "expect": { + "error": "tree.empty" + } + }, + { + "id": "only-noise", + "description": "a tree that is empty after noise removal", + "files": [ + { + "path": ".DS_Store", + "mode": "100644", + "content": "x" + }, + { + "path": ".git/HEAD", + "mode": "100644", + "content": "r\n" + } + ], + "expect": { + "error": "tree.empty" + } + }, + { + "id": "order-type-before-path", + "description": "a bad mode wins over an unsafe path", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "a/../x.md", + "mode": "100777", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsupported_entry" + }, + "archiveOnly": true + }, + { + "id": "order-path-before-nfc", + "description": "an unsafe segment wins over a non-NFC segment", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "café/CON", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "order-nfc-before-collision", + "description": "a non-NFC path wins over a case collision", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "skill.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "café.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.non_nfc_path" + }, + "archiveOnly": true + }, + { + "id": "order-path-before-collision", + "description": "an unsafe path wins over a case collision", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "skill.md", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a?.md", + "mode": "100644", + "content": "y\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "utf8-order-not-utf16", + "description": "sort is by UTF-8 bytes: U+FF5E sorts before U+1F600, which UTF-16 code units would order the other way", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "~.md", + "mode": "100644", + "content": "a\n" + }, + { + "path": "😀.md", + "mode": "100644", + "content": "b\n" + } + ], + "expect": { + "digest": "sha256:c0951b75f4d03981fd86ddf53a8b8a17b20639674ae35c90538ce0e44070567c", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7 2 ~.md\n100644 0263829989b6fd954f72baaf2fc64bc2e2f01d692d4de72986ea808f6e99813f 2 😀.md\n" + } + }, + { + "id": "segment-255-bytes-multibyte", + "description": "a segment of 85 three-byte characters is exactly 255 bytes", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "あああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "digest": "sha256:fa2e5bb3fc7f10f55800420621ea84ceae696d469751577a318ab90998d6bd2f", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 あああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ\n" + } + }, + { + "id": "segment-too-long-multibyte", + "description": "a segment of 86 three-byte characters is 258 bytes", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "ああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "segment-too-long-astral", + "description": "a segment of 64 four-byte characters is 256 bytes, though only 128 UTF-16 units", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "short-name-multibyte-base", + "description": "the 8-byte short-name test counts UTF-8 bytes, so a ten-byte base with '~1' is allowed", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "éééé~1.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "digest": "sha256:6d3cf75ae7ac66f049ae662d16e55da21dcd64de498e73de93cf95e2d1404992", + "serialization": "agentkit.skill-tree/v1\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n100644 73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac 2 éééé~1.md\n" + } + }, + { + "id": "ak-tmp-segment", + "description": "a segment that starts with .ak-tmp. is reserved for AgentKit temporary files", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "references/.ak-tmp.notes.md", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + } + }, + { + "id": "tar-regular-trailing-slash", + "description": "only an old-style type NUL entry becomes a directory by a trailing '/'; a regular-file entry 'refs/' has an empty last segment", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "refs/", + "mode": "100644", + "content": "x\n" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "directory-entry-double-slash", + "description": "a directory entry name has exactly one trailing '/'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "refs//", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "error": "tree.unsafe_path" + }, + "archiveOnly": true + }, + { + "id": "noise-file-name-directory-kept", + "description": "a directory named like a noise file is an ordinary directory and its contents are kept", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": ".DS_Store/", + "mode": "100644", + "type": "directory", + "content": "" + }, + { + "path": ".DS_Store/notes.md", + "mode": "100644", + "content": "n\n" + } + ], + "expect": { + "digest": "sha256:292407740f5dbaec5d1da463d240ac4a08f2f1750909ff111bc7b5c9f3cc0c34", + "serialization": "agentkit.skill-tree/v1\n100644 a4fb621495a0122493b2203591c448903c472e306a1ede54fabad829e01075c0 2 .DS_Store/notes.md\n100644 cbc80bb5c0c0f8944bf73b3a429505ac5cde16644978bc9a1e74c5755f8ca556 2 SKILL.md\n" + } + }, + { + "id": "walker-empty-directory-case", + "description": "a directory walker presents an empty directory 'a' (no trailing '/'); it collides with a file 'A'", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": "A", + "mode": "100644", + "content": "x\n" + }, + { + "path": "a", + "mode": "100644", + "type": "directory", + "content": "" + } + ], + "expect": { + "error": "tree.case_collision" + } + }, + { + "id": "limit-files-at-max", + "description": "exactly the maximum file count", + "synthesize": [ + { + "pathPattern": "f/{n}.md", + "count": 4096, + "size": 2, + "fill": 120 + } + ], + "expect": { + "digest": "sha256:ae67fe8ab0326491fedc7276186c0c2449be4f4fcb4f5c18b47df01d2428067d" + } + }, + { + "id": "limit-files-over", + "description": "one file over the maximum file count", + "synthesize": [ + { + "pathPattern": "f/{n}.md", + "count": 4097, + "size": 2, + "fill": 120 + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + }, + { + "id": "limit-count-includes-noise", + "description": "a presented noise file counts toward the file limit", + "synthesize": [ + { + "pathPattern": "f/{n}.md", + "count": 4096, + "size": 2, + "fill": 120 + }, + { + "pathPattern": "x/{n}/.DS_Store", + "count": 1, + "size": 1, + "fill": 0 + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + }, + { + "id": "limit-directory-entries-not-counted", + "description": "directory entries do not count toward the file limit", + "synthesize": [ + { + "pathPattern": "f/{n}.md", + "count": 4096, + "size": 2, + "fill": 120 + }, + { + "pathPattern": "d/{n}", + "count": 1, + "size": 0, + "fill": 0, + "type": "directory" + } + ], + "expect": { + "digest": "sha256:ae67fe8ab0326491fedc7276186c0c2449be4f4fcb4f5c18b47df01d2428067d" + } + }, + { + "id": "limit-large-noise-file", + "description": "a presented noise file counts toward the byte limits", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "x/{n}/.DS_Store", + "count": 1, + "size": 33554433, + "fill": 0 + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + }, + { + "id": "limit-entries-at-max", + "description": "exactly the maximum total entry count, directories included", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "d/{n}", + "count": 9999, + "size": 0, + "fill": 0, + "type": "directory" + } + ], + "expect": { + "digest": "sha256:96732f9ead4e00966bdd17e6157641ebdc9d2208d8f7aadb01fa18dbf089e53d" + }, + "archiveOnly": true + }, + { + "id": "limit-entries-over", + "description": "one entry over the maximum total entry count, directories included", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "d/{n}", + "count": 10000, + "size": 0, + "fill": 0, + "type": "directory" + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + }, + { + "id": "limit-entries-count-noise", + "description": "a noise entry counts toward the total entry limit", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + }, + { + "path": ".git/HEAD", + "mode": "100644", + "content": "r\n" + } + ], + "synthesize": [ + { + "pathPattern": "d/{n}", + "count": 9999, + "size": 0, + "fill": 0, + "type": "directory" + } + ], + "expect": { + "error": "tree.limit_exceeded" + }, + "archiveOnly": true + }, + { + "id": "order-limit-first", + "description": "a limit failure wins over a bad mode", + "files": [ + { + "path": "SKILL.md", + "mode": "100777", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "f/{n}.md", + "count": 4096, + "size": 2, + "fill": 120 + } + ], + "expect": { + "error": "tree.limit_exceeded" + }, + "archiveOnly": true + }, + { + "id": "limit-file-at-max", + "description": "one file of exactly the maximum file size", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "big/{n}.bin", + "count": 1, + "size": 33554432, + "fill": 0 + } + ], + "expect": { + "digest": "sha256:98b7347cb47e4a9e7a005999abc69318d15d2786cbd0f4c0e1cbe8430bf96256" + } + }, + { + "id": "limit-file-over", + "description": "one file a byte over the maximum file size", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "big/{n}.bin", + "count": 1, + "size": 33554433, + "fill": 0 + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + }, + { + "id": "limit-tree-at-max", + "description": "exactly the maximum tree size", + "synthesize": [ + { + "pathPattern": "big/{n}.bin", + "count": 8, + "size": 33554432, + "fill": 0 + } + ], + "expect": { + "digest": "sha256:939d6faff8840f2b9d1377aafe1b20d1cd235bb072a0ab5d49bc7e8d657664c6" + } + }, + { + "id": "limit-tree-over", + "description": "one byte over the maximum tree size", + "files": [ + { + "path": "SKILL.md", + "mode": "100644", + "content": "s\n" + } + ], + "synthesize": [ + { + "pathPattern": "big/{n}.bin", + "count": 8, + "size": 33554432, + "fill": 0 + } + ], + "expect": { + "error": "tree.limit_exceeded" + } + } + ] +} diff --git a/packages/skill-tree/package.json b/packages/skill-tree/package.json new file mode 100644 index 0000000..607a537 --- /dev/null +++ b/packages/skill-tree/package.json @@ -0,0 +1,23 @@ +{ + "name": "@skillx/skill-tree", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "agentkit.skill-tree/v1 canonical tree digest, archive readers, identity and exposure rules shared with AgentKit.", + "exports": { + ".": "./src/index.ts" + }, + "types": "./src/index.ts", + "scripts": { + "typecheck": "tsc --noEmit", + "test": "vitest run", + "gen:unicode": "node scripts/gen-unicode-tables.mjs" + }, + "dependencies": { + "yaml": "^2.9.1" + }, + "devDependencies": { + "@types/node": "^22.19.10", + "typescript": "^5.9.2" + } +} diff --git a/packages/skill-tree/scripts/dump-go-unicode.go b/packages/skill-tree/scripts/dump-go-unicode.go new file mode 100644 index 0000000..9a51c56 --- /dev/null +++ b/packages/skill-tree/scripts/dump-go-unicode.go @@ -0,0 +1,106 @@ +//go:build ignore + +// dump-go-unicode writes the Unicode data the AgentKit reference +// implementation (Go skilltree package) validates paths with: general +// category from the Go unicode tables and canonical normalization from +// golang.org/x/text/unicode/norm, both pinned to Unicode 15.0.0. The output +// is the input of gen-unicode-tables.mjs, so the TypeScript tables match the +// reference exactly. +// +// Run it from the AgentKit apps/cli module, which pins x/text: +// +// cd /apps/cli && go run /packages/skill-tree/scripts/dump-go-unicode.go > /packages/skill-tree/scripts/unicode-15.0.0-go.json +package main + +import ( + "encoding/json" + "fmt" + "os" + "runtime" + "unicode" + "unicode/utf8" + + "golang.org/x/text/unicode/norm" +) + +type dump struct { + UnicodeVersion string `json:"unicodeVersion"` + NormVersion string `json:"normVersion"` + GoVersion string `json:"goVersion"` + Assigned [][2]rune `json:"assigned"` + Format [][2]rune `json:"format"` + CombiningClass [][2]rune `json:"combiningClass"` + // Decompositions maps a code point to its canonical decomposition: the + // one-step pair for a primary composite, the full decomposition otherwise. + Decompositions [][]rune `json:"decompositions"` + Composites []rune `json:"composites"` +} + +func addRange(ranges [][2]rune, r rune) [][2]rune { + if n := len(ranges); n > 0 && ranges[n-1][1]+1 == r { + ranges[n-1][1] = r + return ranges + } + return append(ranges, [2]rune{r, r}) +} + +// compositePair finds the canonical pair (a, b) that NFC composes into r: b +// is one code point of the full decomposition and a is the NFC of the rest, +// which must be a single code point. +func compositePair(r rune, full []rune) ([2]rune, bool) { + for k := len(full) - 1; k >= 1; k-- { + rest := append(append([]rune{}, full[:k]...), full[k+1:]...) + a := norm.NFC.String(string(rest)) + if utf8.RuneCountInString(a) != 1 { + continue + } + ar, _ := utf8.DecodeRuneInString(a) + if norm.NFC.String(a+string(full[k])) == string(r) { + return [2]rune{ar, full[k]}, true + } + } + return [2]rune{}, false +} + +func main() { + d := dump{UnicodeVersion: unicode.Version, NormVersion: norm.Version, GoVersion: runtime.Version()} + for r := rune(0); r <= unicode.MaxRune; r++ { + if unicode.In(r, unicode.L, unicode.M, unicode.N, unicode.P, unicode.S, unicode.Z, unicode.Cc, unicode.Cf, unicode.Co, unicode.Cs) { + d.Assigned = addRange(d.Assigned, r) + } + if unicode.Is(unicode.Cf, r) { + d.Format = addRange(d.Format, r) + } + if r >= 0xD800 && r <= 0xDFFF { + continue + } + s := string(r) + props := norm.NFD.PropertiesString(s) + if ccc := props.CCC(); ccc != 0 { + d.CombiningClass = append(d.CombiningClass, [2]rune{r, rune(ccc)}) + } + if r >= 0xAC00 && r <= 0xD7A3 { + continue // Hangul syllables are algorithmic. + } + full := []rune(norm.NFD.String(s)) + if len(full) == 1 && full[0] == r { + continue + } + if norm.NFC.String(s) == s && len(full) > 1 { + pair, ok := compositePair(r, full) + if !ok { + fmt.Fprintf(os.Stderr, "no canonical pair for U+%04X\n", r) + os.Exit(1) + } + d.Decompositions = append(d.Decompositions, []rune{r, pair[0], pair[1]}) + d.Composites = append(d.Composites, r) + continue + } + d.Decompositions = append(d.Decompositions, append([]rune{r}, full...)) + } + enc := json.NewEncoder(os.Stdout) + if err := enc.Encode(d); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/packages/skill-tree/scripts/gen-unicode-tables.mjs b/packages/skill-tree/scripts/gen-unicode-tables.mjs new file mode 100644 index 0000000..16fbe60 --- /dev/null +++ b/packages/skill-tree/scripts/gen-unicode-tables.mjs @@ -0,0 +1,130 @@ +#!/usr/bin/env node +/** + * Generates src/unicode-15-tables.ts, the Unicode 15.0.0 tables of the + * skill-tree path rules (contract 4.3), from two pinned inputs: + * + * - fixtures/ucd/CaseFolding-15.0.0.txt, the Unicode 15.0.0 data file, also + * committed by AgentKit as the source of its fold table; + * - scripts/unicode-15.0.0-go.json, written by dump-go-unicode.go from the Go + * unicode and x/text norm tables (Unicode 15.0.0) that the AgentKit + * reference implementation uses for category and normalization. + * + * node scripts/gen-unicode-tables.mjs + * + * Each input must match its pinned sha256, so the output is reproducible and + * cannot silently move to another Unicode version. + */ +import { createHash } from "node:crypto"; +import { readFileSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const VERSION = "15.0.0"; +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const INPUTS = { + caseFolding: { + path: "fixtures/ucd/CaseFolding-15.0.0.txt", + sha256: "cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7", + }, + goTables: { + path: "scripts/unicode-15.0.0-go.json", + sha256: "baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5", + }, +}; + +function load({ path, sha256 }) { + const bytes = readFileSync(join(root, path)); + const sum = createHash("sha256").update(bytes).digest("hex"); + if (sum !== sha256) { + throw new Error(`${path}: sha256 ${sum} is not the pinned input ${sha256}`); + } + return { text: bytes.toString("utf8"), sum }; +} + +const b36 = (n) => n.toString(36); + +function encodeRanges(ranges) { + let prev = 0; + return ranges + .map(([lo, hi]) => { + const item = `${b36(lo - prev)}.${b36(hi - lo)}`; + prev = hi; + return item; + }) + .join(","); +} + +function encodeValueRanges(pairs) { + const ranges = []; + for (const [cp, value] of [...pairs].sort((a, b) => a[0] - b[0])) { + const last = ranges[ranges.length - 1]; + if (last && last[1] + 1 === cp && last[2] === value) last[1] = cp; + else ranges.push([cp, cp, value]); + } + let prev = 0; + return ranges + .map(([lo, hi, value]) => { + const item = `${b36(lo - prev)}.${b36(hi - lo)}.${b36(value)}`; + prev = hi; + return item; + }) + .join(","); +} + +function encodeMap(entries) { + let prev = 0; + return [...entries] + .sort((a, b) => a[0] - b[0]) + .map(([cp, values]) => { + const item = `${b36(cp - prev)}:${values.map(b36).join(".")}`; + prev = cp; + return item; + }) + .join(","); +} + +function encodeList(list) { + let prev = 0; + return [...list] + .sort((a, b) => a - b) + .map((cp) => { + const item = b36(cp - prev); + prev = cp; + return item; + }) + .join(","); +} + +const folding = load(INPUTS.caseFolding); +const foldEntries = []; +for (const line of folding.text.split("\n")) { + const fields = line.replace(/#.*/, "").split(";").map((f) => f.trim()); + if (fields.length < 3 || (fields[1] !== "C" && fields[1] !== "F")) continue; + foldEntries.push([parseInt(fields[0], 16), fields[2].split(" ").map((h) => parseInt(h, 16))]); +} + +const go = load(INPUTS.goTables); +const tables = JSON.parse(go.text); +if (tables.unicodeVersion !== VERSION || tables.normVersion !== VERSION) { + throw new Error(`Go tables are Unicode ${tables.unicodeVersion}/${tables.normVersion}, want ${VERSION}`); +} + +const out = `// Code generated by scripts/gen-unicode-tables.mjs. DO NOT EDIT. +// Unicode ${VERSION}. Inputs: +// ${INPUTS.caseFolding.path} sha256 ${folding.sum} +// ${INPUTS.goTables.path} sha256 ${go.sum} (${tables.goVersion}, x/text norm ${tables.normVersion}) +// Encodings: ranges are "delta.length" base-36 items (delta from the previous +// range end); maps are "keyDelta:value.value"; lists are base-36 deltas. + +export const UNICODE_VERSION = "${VERSION}"; +export const ASSIGNED_RANGES = "${encodeRanges(tables.assigned)}"; +export const FORMAT_RANGES = "${encodeRanges(tables.format)}"; +export const COMBINING_CLASSES = "${encodeValueRanges(tables.combiningClass)}"; +export const CANONICAL_DECOMPOSITIONS = "${encodeMap(tables.decompositions.map(([cp, ...m]) => [cp, m]))}"; +export const PRIMARY_COMPOSITES = "${encodeList(tables.composites)}"; +export const CASE_FOLDING = "${encodeMap(foldEntries)}"; +`; + +const target = join(root, "src", "unicode-15-tables.ts"); +writeFileSync(target, out); +console.log(`wrote ${target}`); diff --git a/packages/skill-tree/scripts/unicode-15.0.0-go.json b/packages/skill-tree/scripts/unicode-15.0.0-go.json new file mode 100644 index 0000000..85bb1df --- /dev/null +++ b/packages/skill-tree/scripts/unicode-15.0.0-go.json @@ -0,0 +1 @@ +{"unicodeVersion":"15.0.0","normVersion":"15.0.0","goVersion":"go1.25.3","assigned":[[0,887],[890,895],[900,906],[908,908],[910,929],[931,1327],[1329,1366],[1369,1418],[1421,1423],[1425,1479],[1488,1514],[1519,1524],[1536,1805],[1807,1866],[1869,1969],[1984,2042],[2045,2093],[2096,2110],[2112,2139],[2142,2142],[2144,2154],[2160,2190],[2192,2193],[2200,2435],[2437,2444],[2447,2448],[2451,2472],[2474,2480],[2482,2482],[2486,2489],[2492,2500],[2503,2504],[2507,2510],[2519,2519],[2524,2525],[2527,2531],[2534,2558],[2561,2563],[2565,2570],[2575,2576],[2579,2600],[2602,2608],[2610,2611],[2613,2614],[2616,2617],[2620,2620],[2622,2626],[2631,2632],[2635,2637],[2641,2641],[2649,2652],[2654,2654],[2662,2678],[2689,2691],[2693,2701],[2703,2705],[2707,2728],[2730,2736],[2738,2739],[2741,2745],[2748,2757],[2759,2761],[2763,2765],[2768,2768],[2784,2787],[2790,2801],[2809,2815],[2817,2819],[2821,2828],[2831,2832],[2835,2856],[2858,2864],[2866,2867],[2869,2873],[2876,2884],[2887,2888],[2891,2893],[2901,2903],[2908,2909],[2911,2915],[2918,2935],[2946,2947],[2949,2954],[2958,2960],[2962,2965],[2969,2970],[2972,2972],[2974,2975],[2979,2980],[2984,2986],[2990,3001],[3006,3010],[3014,3016],[3018,3021],[3024,3024],[3031,3031],[3046,3066],[3072,3084],[3086,3088],[3090,3112],[3114,3129],[3132,3140],[3142,3144],[3146,3149],[3157,3158],[3160,3162],[3165,3165],[3168,3171],[3174,3183],[3191,3212],[3214,3216],[3218,3240],[3242,3251],[3253,3257],[3260,3268],[3270,3272],[3274,3277],[3285,3286],[3293,3294],[3296,3299],[3302,3311],[3313,3315],[3328,3340],[3342,3344],[3346,3396],[3398,3400],[3402,3407],[3412,3427],[3430,3455],[3457,3459],[3461,3478],[3482,3505],[3507,3515],[3517,3517],[3520,3526],[3530,3530],[3535,3540],[3542,3542],[3544,3551],[3558,3567],[3570,3572],[3585,3642],[3647,3675],[3713,3714],[3716,3716],[3718,3722],[3724,3747],[3749,3749],[3751,3773],[3776,3780],[3782,3782],[3784,3790],[3792,3801],[3804,3807],[3840,3911],[3913,3948],[3953,3991],[3993,4028],[4030,4044],[4046,4058],[4096,4293],[4295,4295],[4301,4301],[4304,4680],[4682,4685],[4688,4694],[4696,4696],[4698,4701],[4704,4744],[4746,4749],[4752,4784],[4786,4789],[4792,4798],[4800,4800],[4802,4805],[4808,4822],[4824,4880],[4882,4885],[4888,4954],[4957,4988],[4992,5017],[5024,5109],[5112,5117],[5120,5788],[5792,5880],[5888,5909],[5919,5942],[5952,5971],[5984,5996],[5998,6000],[6002,6003],[6016,6109],[6112,6121],[6128,6137],[6144,6169],[6176,6264],[6272,6314],[6320,6389],[6400,6430],[6432,6443],[6448,6459],[6464,6464],[6468,6509],[6512,6516],[6528,6571],[6576,6601],[6608,6618],[6622,6683],[6686,6750],[6752,6780],[6783,6793],[6800,6809],[6816,6829],[6832,6862],[6912,6988],[6992,7038],[7040,7155],[7164,7223],[7227,7241],[7245,7304],[7312,7354],[7357,7367],[7376,7418],[7424,7957],[7960,7965],[7968,8005],[8008,8013],[8016,8023],[8025,8025],[8027,8027],[8029,8029],[8031,8061],[8064,8116],[8118,8132],[8134,8147],[8150,8155],[8157,8175],[8178,8180],[8182,8190],[8192,8292],[8294,8305],[8308,8334],[8336,8348],[8352,8384],[8400,8432],[8448,8587],[8592,9254],[9280,9290],[9312,11123],[11126,11157],[11159,11507],[11513,11557],[11559,11559],[11565,11565],[11568,11623],[11631,11632],[11647,11670],[11680,11686],[11688,11694],[11696,11702],[11704,11710],[11712,11718],[11720,11726],[11728,11734],[11736,11742],[11744,11869],[11904,11929],[11931,12019],[12032,12245],[12272,12283],[12288,12351],[12353,12438],[12441,12543],[12549,12591],[12593,12686],[12688,12771],[12784,12830],[12832,42124],[42128,42182],[42192,42539],[42560,42743],[42752,42954],[42960,42961],[42963,42963],[42965,42969],[42994,43052],[43056,43065],[43072,43127],[43136,43205],[43214,43225],[43232,43347],[43359,43388],[43392,43469],[43471,43481],[43486,43518],[43520,43574],[43584,43597],[43600,43609],[43612,43714],[43739,43766],[43777,43782],[43785,43790],[43793,43798],[43808,43814],[43816,43822],[43824,43883],[43888,44013],[44016,44025],[44032,55203],[55216,55238],[55243,55291],[55296,64109],[64112,64217],[64256,64262],[64275,64279],[64285,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64450],[64467,64911],[64914,64967],[64975,64975],[65008,65049],[65056,65106],[65108,65126],[65128,65131],[65136,65140],[65142,65276],[65279,65279],[65281,65470],[65474,65479],[65482,65487],[65490,65495],[65498,65500],[65504,65510],[65512,65518],[65529,65533],[65536,65547],[65549,65574],[65576,65594],[65596,65597],[65599,65613],[65616,65629],[65664,65786],[65792,65794],[65799,65843],[65847,65934],[65936,65948],[65952,65952],[66000,66045],[66176,66204],[66208,66256],[66272,66299],[66304,66339],[66349,66378],[66384,66426],[66432,66461],[66463,66499],[66504,66517],[66560,66717],[66720,66729],[66736,66771],[66776,66811],[66816,66855],[66864,66915],[66927,66938],[66940,66954],[66956,66962],[66964,66965],[66967,66977],[66979,66993],[66995,67001],[67003,67004],[67072,67382],[67392,67413],[67424,67431],[67456,67461],[67463,67504],[67506,67514],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67742],[67751,67759],[67808,67826],[67828,67829],[67835,67867],[67871,67897],[67903,67903],[67968,68023],[68028,68047],[68050,68099],[68101,68102],[68108,68115],[68117,68119],[68121,68149],[68152,68154],[68159,68168],[68176,68184],[68192,68255],[68288,68326],[68331,68342],[68352,68405],[68409,68437],[68440,68466],[68472,68497],[68505,68508],[68521,68527],[68608,68680],[68736,68786],[68800,68850],[68858,68903],[68912,68921],[69216,69246],[69248,69289],[69291,69293],[69296,69297],[69373,69415],[69424,69465],[69488,69513],[69552,69579],[69600,69622],[69632,69709],[69714,69749],[69759,69826],[69837,69837],[69840,69864],[69872,69881],[69888,69940],[69942,69959],[69968,70006],[70016,70111],[70113,70132],[70144,70161],[70163,70209],[70272,70278],[70280,70280],[70282,70285],[70287,70301],[70303,70313],[70320,70378],[70384,70393],[70400,70403],[70405,70412],[70415,70416],[70419,70440],[70442,70448],[70450,70451],[70453,70457],[70459,70468],[70471,70472],[70475,70477],[70480,70480],[70487,70487],[70493,70499],[70502,70508],[70512,70516],[70656,70747],[70749,70753],[70784,70855],[70864,70873],[71040,71093],[71096,71133],[71168,71236],[71248,71257],[71264,71276],[71296,71353],[71360,71369],[71424,71450],[71453,71467],[71472,71494],[71680,71739],[71840,71922],[71935,71942],[71945,71945],[71948,71955],[71957,71958],[71960,71989],[71991,71992],[71995,72006],[72016,72025],[72096,72103],[72106,72151],[72154,72164],[72192,72263],[72272,72354],[72368,72440],[72448,72457],[72704,72712],[72714,72758],[72760,72773],[72784,72812],[72816,72847],[72850,72871],[72873,72886],[72960,72966],[72968,72969],[72971,73014],[73018,73018],[73020,73021],[73023,73031],[73040,73049],[73056,73061],[73063,73064],[73066,73102],[73104,73105],[73107,73112],[73120,73129],[73440,73464],[73472,73488],[73490,73530],[73534,73561],[73648,73648],[73664,73713],[73727,74649],[74752,74862],[74864,74868],[74880,75075],[77712,77810],[77824,78933],[82944,83526],[92160,92728],[92736,92766],[92768,92777],[92782,92862],[92864,92873],[92880,92909],[92912,92917],[92928,92997],[93008,93017],[93019,93025],[93027,93047],[93053,93071],[93760,93850],[93952,94026],[94031,94087],[94095,94111],[94176,94180],[94192,94193],[94208,100343],[100352,101589],[101632,101640],[110576,110579],[110581,110587],[110589,110590],[110592,110882],[110898,110898],[110928,110930],[110933,110933],[110948,110951],[110960,111355],[113664,113770],[113776,113788],[113792,113800],[113808,113817],[113820,113827],[118528,118573],[118576,118598],[118608,118723],[118784,119029],[119040,119078],[119081,119274],[119296,119365],[119488,119507],[119520,119539],[119552,119638],[119648,119672],[119808,119892],[119894,119964],[119966,119967],[119970,119970],[119973,119974],[119977,119980],[119982,119993],[119995,119995],[119997,120003],[120005,120069],[120071,120074],[120077,120084],[120086,120092],[120094,120121],[120123,120126],[120128,120132],[120134,120134],[120138,120144],[120146,120485],[120488,120779],[120782,121483],[121499,121503],[121505,121519],[122624,122654],[122661,122666],[122880,122886],[122888,122904],[122907,122913],[122915,122916],[122918,122922],[122928,122989],[123023,123023],[123136,123180],[123184,123197],[123200,123209],[123214,123215],[123536,123566],[123584,123641],[123647,123647],[124112,124153],[124896,124902],[124904,124907],[124909,124910],[124912,124926],[124928,125124],[125127,125142],[125184,125259],[125264,125273],[125278,125279],[126065,126132],[126209,126269],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[126704,126705],[126976,127019],[127024,127123],[127136,127150],[127153,127167],[127169,127183],[127185,127221],[127232,127405],[127462,127490],[127504,127547],[127552,127560],[127568,127569],[127584,127589],[127744,128727],[128732,128748],[128752,128764],[128768,128886],[128891,128985],[128992,129003],[129008,129008],[129024,129035],[129040,129095],[129104,129113],[129120,129159],[129168,129197],[129200,129201],[129280,129619],[129632,129645],[129648,129660],[129664,129672],[129680,129725],[129727,129733],[129742,129755],[129760,129768],[129776,129784],[129792,129938],[129940,129994],[130032,130041],[131072,173791],[173824,177977],[177984,178205],[178208,183969],[183984,191456],[194560,195101],[196608,201546],[201552,205743],[917505,917505],[917536,917631],[917760,917999],[983040,1048573],[1048576,1114109]],"format":[[173,173],[1536,1541],[1564,1564],[1757,1757],[1807,1807],[2192,2193],[2274,2274],[6158,6158],[8203,8207],[8234,8238],[8288,8292],[8294,8303],[65279,65279],[65529,65531],[69821,69821],[69837,69837],[78896,78911],[113824,113827],[119155,119162],[917505,917505],[917536,917631]],"combiningClass":[[768,230],[769,230],[770,230],[771,230],[772,230],[773,230],[774,230],[775,230],[776,230],[777,230],[778,230],[779,230],[780,230],[781,230],[782,230],[783,230],[784,230],[785,230],[786,230],[787,230],[788,230],[789,232],[790,220],[791,220],[792,220],[793,220],[794,232],[795,216],[796,220],[797,220],[798,220],[799,220],[800,220],[801,202],[802,202],[803,220],[804,220],[805,220],[806,220],[807,202],[808,202],[809,220],[810,220],[811,220],[812,220],[813,220],[814,220],[815,220],[816,220],[817,220],[818,220],[819,220],[820,1],[821,1],[822,1],[823,1],[824,1],[825,220],[826,220],[827,220],[828,220],[829,230],[830,230],[831,230],[832,230],[833,230],[834,230],[835,230],[836,230],[837,240],[838,230],[839,220],[840,220],[841,220],[842,230],[843,230],[844,230],[845,220],[846,220],[848,230],[849,230],[850,230],[851,220],[852,220],[853,220],[854,220],[855,230],[856,232],[857,220],[858,220],[859,230],[860,233],[861,234],[862,234],[863,233],[864,234],[865,234],[866,233],[867,230],[868,230],[869,230],[870,230],[871,230],[872,230],[873,230],[874,230],[875,230],[876,230],[877,230],[878,230],[879,230],[1155,230],[1156,230],[1157,230],[1158,230],[1159,230],[1425,220],[1426,230],[1427,230],[1428,230],[1429,230],[1430,220],[1431,230],[1432,230],[1433,230],[1434,222],[1435,220],[1436,230],[1437,230],[1438,230],[1439,230],[1440,230],[1441,230],[1442,220],[1443,220],[1444,220],[1445,220],[1446,220],[1447,220],[1448,230],[1449,230],[1450,220],[1451,230],[1452,230],[1453,222],[1454,228],[1455,230],[1456,10],[1457,11],[1458,12],[1459,13],[1460,14],[1461,15],[1462,16],[1463,17],[1464,18],[1465,19],[1466,19],[1467,20],[1468,21],[1469,22],[1471,23],[1473,24],[1474,25],[1476,230],[1477,220],[1479,18],[1552,230],[1553,230],[1554,230],[1555,230],[1556,230],[1557,230],[1558,230],[1559,230],[1560,30],[1561,31],[1562,32],[1611,27],[1612,28],[1613,29],[1614,30],[1615,31],[1616,32],[1617,33],[1618,34],[1619,230],[1620,230],[1621,220],[1622,220],[1623,230],[1624,230],[1625,230],[1626,230],[1627,230],[1628,220],[1629,230],[1630,230],[1631,220],[1648,35],[1750,230],[1751,230],[1752,230],[1753,230],[1754,230],[1755,230],[1756,230],[1759,230],[1760,230],[1761,230],[1762,230],[1763,220],[1764,230],[1767,230],[1768,230],[1770,220],[1771,230],[1772,230],[1773,220],[1809,36],[1840,230],[1841,220],[1842,230],[1843,230],[1844,220],[1845,230],[1846,230],[1847,220],[1848,220],[1849,220],[1850,230],[1851,220],[1852,220],[1853,230],[1854,220],[1855,230],[1856,230],[1857,230],[1858,220],[1859,230],[1860,220],[1861,230],[1862,220],[1863,230],[1864,220],[1865,230],[1866,230],[2027,230],[2028,230],[2029,230],[2030,230],[2031,230],[2032,230],[2033,230],[2034,220],[2035,230],[2045,220],[2070,230],[2071,230],[2072,230],[2073,230],[2075,230],[2076,230],[2077,230],[2078,230],[2079,230],[2080,230],[2081,230],[2082,230],[2083,230],[2085,230],[2086,230],[2087,230],[2089,230],[2090,230],[2091,230],[2092,230],[2093,230],[2137,220],[2138,220],[2139,220],[2200,230],[2201,220],[2202,220],[2203,220],[2204,230],[2205,230],[2206,230],[2207,230],[2250,230],[2251,230],[2252,230],[2253,230],[2254,230],[2255,220],[2256,220],[2257,220],[2258,220],[2259,220],[2260,230],[2261,230],[2262,230],[2263,230],[2264,230],[2265,230],[2266,230],[2267,230],[2268,230],[2269,230],[2270,230],[2271,230],[2272,230],[2273,230],[2275,220],[2276,230],[2277,230],[2278,220],[2279,230],[2280,230],[2281,220],[2282,230],[2283,230],[2284,230],[2285,220],[2286,220],[2287,220],[2288,27],[2289,28],[2290,29],[2291,230],[2292,230],[2293,230],[2294,220],[2295,230],[2296,230],[2297,220],[2298,220],[2299,230],[2300,230],[2301,230],[2302,230],[2303,230],[2364,7],[2381,9],[2385,230],[2386,220],[2387,230],[2388,230],[2492,7],[2509,9],[2558,230],[2620,7],[2637,9],[2748,7],[2765,9],[2876,7],[2893,9],[3021,9],[3132,7],[3149,9],[3157,84],[3158,91],[3260,7],[3277,9],[3387,9],[3388,9],[3405,9],[3530,9],[3640,103],[3641,103],[3642,9],[3656,107],[3657,107],[3658,107],[3659,107],[3768,118],[3769,118],[3770,9],[3784,122],[3785,122],[3786,122],[3787,122],[3864,220],[3865,220],[3893,220],[3895,220],[3897,216],[3953,129],[3954,130],[3956,132],[3962,130],[3963,130],[3964,130],[3965,130],[3968,130],[3970,230],[3971,230],[3972,9],[3974,230],[3975,230],[4038,220],[4151,7],[4153,9],[4154,9],[4237,220],[4957,230],[4958,230],[4959,230],[5908,9],[5909,9],[5940,9],[6098,9],[6109,230],[6313,228],[6457,222],[6458,230],[6459,220],[6679,230],[6680,220],[6752,9],[6773,230],[6774,230],[6775,230],[6776,230],[6777,230],[6778,230],[6779,230],[6780,230],[6783,220],[6832,230],[6833,230],[6834,230],[6835,230],[6836,230],[6837,220],[6838,220],[6839,220],[6840,220],[6841,220],[6842,220],[6843,230],[6844,230],[6845,220],[6847,220],[6848,220],[6849,230],[6850,230],[6851,220],[6852,220],[6853,230],[6854,230],[6855,230],[6856,230],[6857,230],[6858,220],[6859,230],[6860,230],[6861,230],[6862,230],[6964,7],[6980,9],[7019,230],[7020,220],[7021,230],[7022,230],[7023,230],[7024,230],[7025,230],[7026,230],[7027,230],[7082,9],[7083,9],[7142,7],[7154,9],[7155,9],[7223,7],[7376,230],[7377,230],[7378,230],[7380,1],[7381,220],[7382,220],[7383,220],[7384,220],[7385,220],[7386,230],[7387,230],[7388,220],[7389,220],[7390,220],[7391,220],[7392,230],[7394,1],[7395,1],[7396,1],[7397,1],[7398,1],[7399,1],[7400,1],[7405,220],[7412,230],[7416,230],[7417,230],[7616,230],[7617,230],[7618,220],[7619,230],[7620,230],[7621,230],[7622,230],[7623,230],[7624,230],[7625,230],[7626,220],[7627,230],[7628,230],[7629,234],[7630,214],[7631,220],[7632,202],[7633,230],[7634,230],[7635,230],[7636,230],[7637,230],[7638,230],[7639,230],[7640,230],[7641,230],[7642,230],[7643,230],[7644,230],[7645,230],[7646,230],[7647,230],[7648,230],[7649,230],[7650,230],[7651,230],[7652,230],[7653,230],[7654,230],[7655,230],[7656,230],[7657,230],[7658,230],[7659,230],[7660,230],[7661,230],[7662,230],[7663,230],[7664,230],[7665,230],[7666,230],[7667,230],[7668,230],[7669,230],[7670,232],[7671,228],[7672,228],[7673,220],[7674,218],[7675,230],[7676,233],[7677,220],[7678,230],[7679,220],[8400,230],[8401,230],[8402,1],[8403,1],[8404,230],[8405,230],[8406,230],[8407,230],[8408,1],[8409,1],[8410,1],[8411,230],[8412,230],[8417,230],[8421,1],[8422,1],[8423,230],[8424,220],[8425,230],[8426,1],[8427,1],[8428,220],[8429,220],[8430,220],[8431,220],[8432,230],[11503,230],[11504,230],[11505,230],[11647,9],[11744,230],[11745,230],[11746,230],[11747,230],[11748,230],[11749,230],[11750,230],[11751,230],[11752,230],[11753,230],[11754,230],[11755,230],[11756,230],[11757,230],[11758,230],[11759,230],[11760,230],[11761,230],[11762,230],[11763,230],[11764,230],[11765,230],[11766,230],[11767,230],[11768,230],[11769,230],[11770,230],[11771,230],[11772,230],[11773,230],[11774,230],[11775,230],[12330,218],[12331,228],[12332,232],[12333,222],[12334,224],[12335,224],[12441,8],[12442,8],[42607,230],[42612,230],[42613,230],[42614,230],[42615,230],[42616,230],[42617,230],[42618,230],[42619,230],[42620,230],[42621,230],[42654,230],[42655,230],[42736,230],[42737,230],[43014,9],[43052,9],[43204,9],[43232,230],[43233,230],[43234,230],[43235,230],[43236,230],[43237,230],[43238,230],[43239,230],[43240,230],[43241,230],[43242,230],[43243,230],[43244,230],[43245,230],[43246,230],[43247,230],[43248,230],[43249,230],[43307,220],[43308,220],[43309,220],[43347,9],[43443,7],[43456,9],[43696,230],[43698,230],[43699,230],[43700,220],[43703,230],[43704,230],[43710,230],[43711,230],[43713,230],[43766,9],[44013,9],[64286,26],[65056,230],[65057,230],[65058,230],[65059,230],[65060,230],[65061,230],[65062,230],[65063,220],[65064,220],[65065,220],[65066,220],[65067,220],[65068,220],[65069,220],[65070,230],[65071,230],[66045,220],[66272,220],[66422,230],[66423,230],[66424,230],[66425,230],[66426,230],[68109,220],[68111,230],[68152,230],[68153,1],[68154,220],[68159,9],[68325,230],[68326,220],[68900,230],[68901,230],[68902,230],[68903,230],[69291,230],[69292,230],[69373,220],[69374,220],[69375,220],[69446,220],[69447,220],[69448,230],[69449,230],[69450,230],[69451,220],[69452,230],[69453,220],[69454,220],[69455,220],[69456,220],[69506,230],[69507,220],[69508,230],[69509,220],[69702,9],[69744,9],[69759,9],[69817,9],[69818,7],[69888,230],[69889,230],[69890,230],[69939,9],[69940,9],[70003,7],[70080,9],[70090,7],[70197,9],[70198,7],[70377,7],[70378,9],[70459,7],[70460,7],[70477,9],[70502,230],[70503,230],[70504,230],[70505,230],[70506,230],[70507,230],[70508,230],[70512,230],[70513,230],[70514,230],[70515,230],[70516,230],[70722,9],[70726,7],[70750,230],[70850,9],[70851,7],[71103,9],[71104,7],[71231,9],[71350,9],[71351,7],[71467,9],[71737,9],[71738,7],[71997,9],[71998,9],[72003,7],[72160,9],[72244,9],[72263,9],[72345,9],[72767,9],[73026,7],[73028,9],[73029,9],[73111,9],[73537,9],[73538,9],[92912,1],[92913,1],[92914,1],[92915,1],[92916,1],[92976,230],[92977,230],[92978,230],[92979,230],[92980,230],[92981,230],[92982,230],[94192,6],[94193,6],[113822,1],[119141,216],[119142,216],[119143,1],[119144,1],[119145,1],[119149,226],[119150,216],[119151,216],[119152,216],[119153,216],[119154,216],[119163,220],[119164,220],[119165,220],[119166,220],[119167,220],[119168,220],[119169,220],[119170,220],[119173,230],[119174,230],[119175,230],[119176,230],[119177,230],[119178,220],[119179,220],[119210,230],[119211,230],[119212,230],[119213,230],[119362,230],[119363,230],[119364,230],[122880,230],[122881,230],[122882,230],[122883,230],[122884,230],[122885,230],[122886,230],[122888,230],[122889,230],[122890,230],[122891,230],[122892,230],[122893,230],[122894,230],[122895,230],[122896,230],[122897,230],[122898,230],[122899,230],[122900,230],[122901,230],[122902,230],[122903,230],[122904,230],[122907,230],[122908,230],[122909,230],[122910,230],[122911,230],[122912,230],[122913,230],[122915,230],[122916,230],[122918,230],[122919,230],[122920,230],[122921,230],[122922,230],[123023,230],[123184,230],[123185,230],[123186,230],[123187,230],[123188,230],[123189,230],[123190,230],[123566,230],[123628,230],[123629,230],[123630,230],[123631,230],[124140,232],[124141,232],[124142,220],[124143,230],[125136,220],[125137,220],[125138,220],[125139,220],[125140,220],[125141,220],[125142,220],[125252,230],[125253,230],[125254,230],[125255,230],[125256,230],[125257,230],[125258,7]],"decompositions":[[192,65,768],[193,65,769],[194,65,770],[195,65,771],[196,65,776],[197,65,778],[199,67,807],[200,69,768],[201,69,769],[202,69,770],[203,69,776],[204,73,768],[205,73,769],[206,73,770],[207,73,776],[209,78,771],[210,79,768],[211,79,769],[212,79,770],[213,79,771],[214,79,776],[217,85,768],[218,85,769],[219,85,770],[220,85,776],[221,89,769],[224,97,768],[225,97,769],[226,97,770],[227,97,771],[228,97,776],[229,97,778],[231,99,807],[232,101,768],[233,101,769],[234,101,770],[235,101,776],[236,105,768],[237,105,769],[238,105,770],[239,105,776],[241,110,771],[242,111,768],[243,111,769],[244,111,770],[245,111,771],[246,111,776],[249,117,768],[250,117,769],[251,117,770],[252,117,776],[253,121,769],[255,121,776],[256,65,772],[257,97,772],[258,65,774],[259,97,774],[260,65,808],[261,97,808],[262,67,769],[263,99,769],[264,67,770],[265,99,770],[266,67,775],[267,99,775],[268,67,780],[269,99,780],[270,68,780],[271,100,780],[274,69,772],[275,101,772],[276,69,774],[277,101,774],[278,69,775],[279,101,775],[280,69,808],[281,101,808],[282,69,780],[283,101,780],[284,71,770],[285,103,770],[286,71,774],[287,103,774],[288,71,775],[289,103,775],[290,71,807],[291,103,807],[292,72,770],[293,104,770],[296,73,771],[297,105,771],[298,73,772],[299,105,772],[300,73,774],[301,105,774],[302,73,808],[303,105,808],[304,73,775],[308,74,770],[309,106,770],[310,75,807],[311,107,807],[313,76,769],[314,108,769],[315,76,807],[316,108,807],[317,76,780],[318,108,780],[323,78,769],[324,110,769],[325,78,807],[326,110,807],[327,78,780],[328,110,780],[332,79,772],[333,111,772],[334,79,774],[335,111,774],[336,79,779],[337,111,779],[340,82,769],[341,114,769],[342,82,807],[343,114,807],[344,82,780],[345,114,780],[346,83,769],[347,115,769],[348,83,770],[349,115,770],[350,83,807],[351,115,807],[352,83,780],[353,115,780],[354,84,807],[355,116,807],[356,84,780],[357,116,780],[360,85,771],[361,117,771],[362,85,772],[363,117,772],[364,85,774],[365,117,774],[366,85,778],[367,117,778],[368,85,779],[369,117,779],[370,85,808],[371,117,808],[372,87,770],[373,119,770],[374,89,770],[375,121,770],[376,89,776],[377,90,769],[378,122,769],[379,90,775],[380,122,775],[381,90,780],[382,122,780],[416,79,795],[417,111,795],[431,85,795],[432,117,795],[461,65,780],[462,97,780],[463,73,780],[464,105,780],[465,79,780],[466,111,780],[467,85,780],[468,117,780],[469,220,772],[470,252,772],[471,220,769],[472,252,769],[473,220,780],[474,252,780],[475,220,768],[476,252,768],[478,196,772],[479,228,772],[480,550,772],[481,551,772],[482,198,772],[483,230,772],[486,71,780],[487,103,780],[488,75,780],[489,107,780],[490,79,808],[491,111,808],[492,490,772],[493,491,772],[494,439,780],[495,658,780],[496,106,780],[500,71,769],[501,103,769],[504,78,768],[505,110,768],[506,197,769],[507,229,769],[508,198,769],[509,230,769],[510,216,769],[511,248,769],[512,65,783],[513,97,783],[514,65,785],[515,97,785],[516,69,783],[517,101,783],[518,69,785],[519,101,785],[520,73,783],[521,105,783],[522,73,785],[523,105,785],[524,79,783],[525,111,783],[526,79,785],[527,111,785],[528,82,783],[529,114,783],[530,82,785],[531,114,785],[532,85,783],[533,117,783],[534,85,785],[535,117,785],[536,83,806],[537,115,806],[538,84,806],[539,116,806],[542,72,780],[543,104,780],[550,65,775],[551,97,775],[552,69,807],[553,101,807],[554,214,772],[555,246,772],[556,213,772],[557,245,772],[558,79,775],[559,111,775],[560,558,772],[561,559,772],[562,89,772],[563,121,772],[832,768],[833,769],[835,787],[836,776,769],[884,697],[894,59],[901,168,769],[902,913,769],[903,183],[904,917,769],[905,919,769],[906,921,769],[908,927,769],[910,933,769],[911,937,769],[912,970,769],[938,921,776],[939,933,776],[940,945,769],[941,949,769],[942,951,769],[943,953,769],[944,971,769],[970,953,776],[971,965,776],[972,959,769],[973,965,769],[974,969,769],[979,978,769],[980,978,776],[1024,1045,768],[1025,1045,776],[1027,1043,769],[1031,1030,776],[1036,1050,769],[1037,1048,768],[1038,1059,774],[1049,1048,774],[1081,1080,774],[1104,1077,768],[1105,1077,776],[1107,1075,769],[1111,1110,776],[1116,1082,769],[1117,1080,768],[1118,1091,774],[1142,1140,783],[1143,1141,783],[1217,1046,774],[1218,1078,774],[1232,1040,774],[1233,1072,774],[1234,1040,776],[1235,1072,776],[1238,1045,774],[1239,1077,774],[1242,1240,776],[1243,1241,776],[1244,1046,776],[1245,1078,776],[1246,1047,776],[1247,1079,776],[1250,1048,772],[1251,1080,772],[1252,1048,776],[1253,1080,776],[1254,1054,776],[1255,1086,776],[1258,1256,776],[1259,1257,776],[1260,1069,776],[1261,1101,776],[1262,1059,772],[1263,1091,772],[1264,1059,776],[1265,1091,776],[1266,1059,779],[1267,1091,779],[1268,1063,776],[1269,1095,776],[1272,1067,776],[1273,1099,776],[1570,1575,1619],[1571,1575,1620],[1572,1608,1620],[1573,1575,1621],[1574,1610,1620],[1728,1749,1620],[1730,1729,1620],[1747,1746,1620],[2345,2344,2364],[2353,2352,2364],[2356,2355,2364],[2392,2325,2364],[2393,2326,2364],[2394,2327,2364],[2395,2332,2364],[2396,2337,2364],[2397,2338,2364],[2398,2347,2364],[2399,2351,2364],[2507,2503,2494],[2508,2503,2519],[2524,2465,2492],[2525,2466,2492],[2527,2479,2492],[2611,2610,2620],[2614,2616,2620],[2649,2582,2620],[2650,2583,2620],[2651,2588,2620],[2654,2603,2620],[2888,2887,2902],[2891,2887,2878],[2892,2887,2903],[2908,2849,2876],[2909,2850,2876],[2964,2962,3031],[3018,3014,3006],[3019,3015,3006],[3020,3014,3031],[3144,3142,3158],[3264,3263,3285],[3271,3270,3285],[3272,3270,3286],[3274,3270,3266],[3275,3274,3285],[3402,3398,3390],[3403,3399,3390],[3404,3398,3415],[3546,3545,3530],[3548,3545,3535],[3549,3548,3530],[3550,3545,3551],[3907,3906,4023],[3917,3916,4023],[3922,3921,4023],[3927,3926,4023],[3932,3931,4023],[3945,3904,4021],[3955,3953,3954],[3957,3953,3956],[3958,4018,3968],[3960,4019,3968],[3969,3953,3968],[3987,3986,4023],[3997,3996,4023],[4002,4001,4023],[4007,4006,4023],[4012,4011,4023],[4025,3984,4021],[4134,4133,4142],[6918,6917,6965],[6920,6919,6965],[6922,6921,6965],[6924,6923,6965],[6926,6925,6965],[6930,6929,6965],[6971,6970,6965],[6973,6972,6965],[6976,6974,6965],[6977,6975,6965],[6979,6978,6965],[7680,65,805],[7681,97,805],[7682,66,775],[7683,98,775],[7684,66,803],[7685,98,803],[7686,66,817],[7687,98,817],[7688,199,769],[7689,231,769],[7690,68,775],[7691,100,775],[7692,68,803],[7693,100,803],[7694,68,817],[7695,100,817],[7696,68,807],[7697,100,807],[7698,68,813],[7699,100,813],[7700,274,768],[7701,275,768],[7702,274,769],[7703,275,769],[7704,69,813],[7705,101,813],[7706,69,816],[7707,101,816],[7708,552,774],[7709,553,774],[7710,70,775],[7711,102,775],[7712,71,772],[7713,103,772],[7714,72,775],[7715,104,775],[7716,72,803],[7717,104,803],[7718,72,776],[7719,104,776],[7720,72,807],[7721,104,807],[7722,72,814],[7723,104,814],[7724,73,816],[7725,105,816],[7726,207,769],[7727,239,769],[7728,75,769],[7729,107,769],[7730,75,803],[7731,107,803],[7732,75,817],[7733,107,817],[7734,76,803],[7735,108,803],[7736,7734,772],[7737,7735,772],[7738,76,817],[7739,108,817],[7740,76,813],[7741,108,813],[7742,77,769],[7743,109,769],[7744,77,775],[7745,109,775],[7746,77,803],[7747,109,803],[7748,78,775],[7749,110,775],[7750,78,803],[7751,110,803],[7752,78,817],[7753,110,817],[7754,78,813],[7755,110,813],[7756,213,769],[7757,245,769],[7758,213,776],[7759,245,776],[7760,332,768],[7761,333,768],[7762,332,769],[7763,333,769],[7764,80,769],[7765,112,769],[7766,80,775],[7767,112,775],[7768,82,775],[7769,114,775],[7770,82,803],[7771,114,803],[7772,7770,772],[7773,7771,772],[7774,82,817],[7775,114,817],[7776,83,775],[7777,115,775],[7778,83,803],[7779,115,803],[7780,346,775],[7781,347,775],[7782,352,775],[7783,353,775],[7784,7778,775],[7785,7779,775],[7786,84,775],[7787,116,775],[7788,84,803],[7789,116,803],[7790,84,817],[7791,116,817],[7792,84,813],[7793,116,813],[7794,85,804],[7795,117,804],[7796,85,816],[7797,117,816],[7798,85,813],[7799,117,813],[7800,360,769],[7801,361,769],[7802,362,776],[7803,363,776],[7804,86,771],[7805,118,771],[7806,86,803],[7807,118,803],[7808,87,768],[7809,119,768],[7810,87,769],[7811,119,769],[7812,87,776],[7813,119,776],[7814,87,775],[7815,119,775],[7816,87,803],[7817,119,803],[7818,88,775],[7819,120,775],[7820,88,776],[7821,120,776],[7822,89,775],[7823,121,775],[7824,90,770],[7825,122,770],[7826,90,803],[7827,122,803],[7828,90,817],[7829,122,817],[7830,104,817],[7831,116,776],[7832,119,778],[7833,121,778],[7835,383,775],[7840,65,803],[7841,97,803],[7842,65,777],[7843,97,777],[7844,194,769],[7845,226,769],[7846,194,768],[7847,226,768],[7848,194,777],[7849,226,777],[7850,194,771],[7851,226,771],[7852,7840,770],[7853,7841,770],[7854,258,769],[7855,259,769],[7856,258,768],[7857,259,768],[7858,258,777],[7859,259,777],[7860,258,771],[7861,259,771],[7862,7840,774],[7863,7841,774],[7864,69,803],[7865,101,803],[7866,69,777],[7867,101,777],[7868,69,771],[7869,101,771],[7870,202,769],[7871,234,769],[7872,202,768],[7873,234,768],[7874,202,777],[7875,234,777],[7876,202,771],[7877,234,771],[7878,7864,770],[7879,7865,770],[7880,73,777],[7881,105,777],[7882,73,803],[7883,105,803],[7884,79,803],[7885,111,803],[7886,79,777],[7887,111,777],[7888,212,769],[7889,244,769],[7890,212,768],[7891,244,768],[7892,212,777],[7893,244,777],[7894,212,771],[7895,244,771],[7896,7884,770],[7897,7885,770],[7898,416,769],[7899,417,769],[7900,416,768],[7901,417,768],[7902,416,777],[7903,417,777],[7904,416,771],[7905,417,771],[7906,416,803],[7907,417,803],[7908,85,803],[7909,117,803],[7910,85,777],[7911,117,777],[7912,431,769],[7913,432,769],[7914,431,768],[7915,432,768],[7916,431,777],[7917,432,777],[7918,431,771],[7919,432,771],[7920,431,803],[7921,432,803],[7922,89,768],[7923,121,768],[7924,89,803],[7925,121,803],[7926,89,777],[7927,121,777],[7928,89,771],[7929,121,771],[7936,945,787],[7937,945,788],[7938,7936,768],[7939,7937,768],[7940,7936,769],[7941,7937,769],[7942,7936,834],[7943,7937,834],[7944,913,787],[7945,913,788],[7946,7944,768],[7947,7945,768],[7948,7944,769],[7949,7945,769],[7950,7944,834],[7951,7945,834],[7952,949,787],[7953,949,788],[7954,7952,768],[7955,7953,768],[7956,7952,769],[7957,7953,769],[7960,917,787],[7961,917,788],[7962,7960,768],[7963,7961,768],[7964,7960,769],[7965,7961,769],[7968,951,787],[7969,951,788],[7970,7968,768],[7971,7969,768],[7972,7968,769],[7973,7969,769],[7974,7968,834],[7975,7969,834],[7976,919,787],[7977,919,788],[7978,7976,768],[7979,7977,768],[7980,7976,769],[7981,7977,769],[7982,7976,834],[7983,7977,834],[7984,953,787],[7985,953,788],[7986,7984,768],[7987,7985,768],[7988,7984,769],[7989,7985,769],[7990,7984,834],[7991,7985,834],[7992,921,787],[7993,921,788],[7994,7992,768],[7995,7993,768],[7996,7992,769],[7997,7993,769],[7998,7992,834],[7999,7993,834],[8000,959,787],[8001,959,788],[8002,8000,768],[8003,8001,768],[8004,8000,769],[8005,8001,769],[8008,927,787],[8009,927,788],[8010,8008,768],[8011,8009,768],[8012,8008,769],[8013,8009,769],[8016,965,787],[8017,965,788],[8018,8016,768],[8019,8017,768],[8020,8016,769],[8021,8017,769],[8022,8016,834],[8023,8017,834],[8025,933,788],[8027,8025,768],[8029,8025,769],[8031,8025,834],[8032,969,787],[8033,969,788],[8034,8032,768],[8035,8033,768],[8036,8032,769],[8037,8033,769],[8038,8032,834],[8039,8033,834],[8040,937,787],[8041,937,788],[8042,8040,768],[8043,8041,768],[8044,8040,769],[8045,8041,769],[8046,8040,834],[8047,8041,834],[8048,945,768],[8049,945,769],[8050,949,768],[8051,949,769],[8052,951,768],[8053,951,769],[8054,953,768],[8055,953,769],[8056,959,768],[8057,959,769],[8058,965,768],[8059,965,769],[8060,969,768],[8061,969,769],[8064,7936,837],[8065,7937,837],[8066,7938,837],[8067,7939,837],[8068,7940,837],[8069,7941,837],[8070,7942,837],[8071,7943,837],[8072,7944,837],[8073,7945,837],[8074,7946,837],[8075,7947,837],[8076,7948,837],[8077,7949,837],[8078,7950,837],[8079,7951,837],[8080,7968,837],[8081,7969,837],[8082,7970,837],[8083,7971,837],[8084,7972,837],[8085,7973,837],[8086,7974,837],[8087,7975,837],[8088,7976,837],[8089,7977,837],[8090,7978,837],[8091,7979,837],[8092,7980,837],[8093,7981,837],[8094,7982,837],[8095,7983,837],[8096,8032,837],[8097,8033,837],[8098,8034,837],[8099,8035,837],[8100,8036,837],[8101,8037,837],[8102,8038,837],[8103,8039,837],[8104,8040,837],[8105,8041,837],[8106,8042,837],[8107,8043,837],[8108,8044,837],[8109,8045,837],[8110,8046,837],[8111,8047,837],[8112,945,774],[8113,945,772],[8114,8048,837],[8115,945,837],[8116,940,837],[8118,945,834],[8119,8118,837],[8120,913,774],[8121,913,772],[8122,913,768],[8123,913,769],[8124,913,837],[8126,953],[8129,168,834],[8130,8052,837],[8131,951,837],[8132,942,837],[8134,951,834],[8135,8134,837],[8136,917,768],[8137,917,769],[8138,919,768],[8139,919,769],[8140,919,837],[8141,8127,768],[8142,8127,769],[8143,8127,834],[8144,953,774],[8145,953,772],[8146,970,768],[8147,953,776,769],[8150,953,834],[8151,970,834],[8152,921,774],[8153,921,772],[8154,921,768],[8155,921,769],[8157,8190,768],[8158,8190,769],[8159,8190,834],[8160,965,774],[8161,965,772],[8162,971,768],[8163,965,776,769],[8164,961,787],[8165,961,788],[8166,965,834],[8167,971,834],[8168,933,774],[8169,933,772],[8170,933,768],[8171,933,769],[8172,929,788],[8173,168,768],[8174,168,769],[8175,96],[8178,8060,837],[8179,969,837],[8180,974,837],[8182,969,834],[8183,8182,837],[8184,927,768],[8185,927,769],[8186,937,768],[8187,937,769],[8188,937,837],[8189,180],[8192,8194],[8193,8195],[8486,937],[8490,75],[8491,65,778],[8602,8592,824],[8603,8594,824],[8622,8596,824],[8653,8656,824],[8654,8660,824],[8655,8658,824],[8708,8707,824],[8713,8712,824],[8716,8715,824],[8740,8739,824],[8742,8741,824],[8769,8764,824],[8772,8771,824],[8775,8773,824],[8777,8776,824],[8800,61,824],[8802,8801,824],[8813,8781,824],[8814,60,824],[8815,62,824],[8816,8804,824],[8817,8805,824],[8820,8818,824],[8821,8819,824],[8824,8822,824],[8825,8823,824],[8832,8826,824],[8833,8827,824],[8836,8834,824],[8837,8835,824],[8840,8838,824],[8841,8839,824],[8876,8866,824],[8877,8872,824],[8878,8873,824],[8879,8875,824],[8928,8828,824],[8929,8829,824],[8930,8849,824],[8931,8850,824],[8938,8882,824],[8939,8883,824],[8940,8884,824],[8941,8885,824],[9001,12296],[9002,12297],[10972,10973,824],[12364,12363,12441],[12366,12365,12441],[12368,12367,12441],[12370,12369,12441],[12372,12371,12441],[12374,12373,12441],[12376,12375,12441],[12378,12377,12441],[12380,12379,12441],[12382,12381,12441],[12384,12383,12441],[12386,12385,12441],[12389,12388,12441],[12391,12390,12441],[12393,12392,12441],[12400,12399,12441],[12401,12399,12442],[12403,12402,12441],[12404,12402,12442],[12406,12405,12441],[12407,12405,12442],[12409,12408,12441],[12410,12408,12442],[12412,12411,12441],[12413,12411,12442],[12436,12358,12441],[12446,12445,12441],[12460,12459,12441],[12462,12461,12441],[12464,12463,12441],[12466,12465,12441],[12468,12467,12441],[12470,12469,12441],[12472,12471,12441],[12474,12473,12441],[12476,12475,12441],[12478,12477,12441],[12480,12479,12441],[12482,12481,12441],[12485,12484,12441],[12487,12486,12441],[12489,12488,12441],[12496,12495,12441],[12497,12495,12442],[12499,12498,12441],[12500,12498,12442],[12502,12501,12441],[12503,12501,12442],[12505,12504,12441],[12506,12504,12442],[12508,12507,12441],[12509,12507,12442],[12532,12454,12441],[12535,12527,12441],[12536,12528,12441],[12537,12529,12441],[12538,12530,12441],[12542,12541,12441],[63744,35912],[63745,26356],[63746,36554],[63747,36040],[63748,28369],[63749,20018],[63750,21477],[63751,40860],[63752,40860],[63753,22865],[63754,37329],[63755,21895],[63756,22856],[63757,25078],[63758,30313],[63759,32645],[63760,34367],[63761,34746],[63762,35064],[63763,37007],[63764,27138],[63765,27931],[63766,28889],[63767,29662],[63768,33853],[63769,37226],[63770,39409],[63771,20098],[63772,21365],[63773,27396],[63774,29211],[63775,34349],[63776,40478],[63777,23888],[63778,28651],[63779,34253],[63780,35172],[63781,25289],[63782,33240],[63783,34847],[63784,24266],[63785,26391],[63786,28010],[63787,29436],[63788,37070],[63789,20358],[63790,20919],[63791,21214],[63792,25796],[63793,27347],[63794,29200],[63795,30439],[63796,32769],[63797,34310],[63798,34396],[63799,36335],[63800,38706],[63801,39791],[63802,40442],[63803,30860],[63804,31103],[63805,32160],[63806,33737],[63807,37636],[63808,40575],[63809,35542],[63810,22751],[63811,24324],[63812,31840],[63813,32894],[63814,29282],[63815,30922],[63816,36034],[63817,38647],[63818,22744],[63819,23650],[63820,27155],[63821,28122],[63822,28431],[63823,32047],[63824,32311],[63825,38475],[63826,21202],[63827,32907],[63828,20956],[63829,20940],[63830,31260],[63831,32190],[63832,33777],[63833,38517],[63834,35712],[63835,25295],[63836,27138],[63837,35582],[63838,20025],[63839,23527],[63840,24594],[63841,29575],[63842,30064],[63843,21271],[63844,30971],[63845,20415],[63846,24489],[63847,19981],[63848,27852],[63849,25976],[63850,32034],[63851,21443],[63852,22622],[63853,30465],[63854,33865],[63855,35498],[63856,27578],[63857,36784],[63858,27784],[63859,25342],[63860,33509],[63861,25504],[63862,30053],[63863,20142],[63864,20841],[63865,20937],[63866,26753],[63867,31975],[63868,33391],[63869,35538],[63870,37327],[63871,21237],[63872,21570],[63873,22899],[63874,24300],[63875,26053],[63876,28670],[63877,31018],[63878,38317],[63879,39530],[63880,40599],[63881,40654],[63882,21147],[63883,26310],[63884,27511],[63885,36706],[63886,24180],[63887,24976],[63888,25088],[63889,25754],[63890,28451],[63891,29001],[63892,29833],[63893,31178],[63894,32244],[63895,32879],[63896,36646],[63897,34030],[63898,36899],[63899,37706],[63900,21015],[63901,21155],[63902,21693],[63903,28872],[63904,35010],[63905,35498],[63906,24265],[63907,24565],[63908,25467],[63909,27566],[63910,31806],[63911,29557],[63912,20196],[63913,22265],[63914,23527],[63915,23994],[63916,24604],[63917,29618],[63918,29801],[63919,32666],[63920,32838],[63921,37428],[63922,38646],[63923,38728],[63924,38936],[63925,20363],[63926,31150],[63927,37300],[63928,38584],[63929,24801],[63930,20102],[63931,20698],[63932,23534],[63933,23615],[63934,26009],[63935,27138],[63936,29134],[63937,30274],[63938,34044],[63939,36988],[63940,40845],[63941,26248],[63942,38446],[63943,21129],[63944,26491],[63945,26611],[63946,27969],[63947,28316],[63948,29705],[63949,30041],[63950,30827],[63951,32016],[63952,39006],[63953,20845],[63954,25134],[63955,38520],[63956,20523],[63957,23833],[63958,28138],[63959,36650],[63960,24459],[63961,24900],[63962,26647],[63963,29575],[63964,38534],[63965,21033],[63966,21519],[63967,23653],[63968,26131],[63969,26446],[63970,26792],[63971,27877],[63972,29702],[63973,30178],[63974,32633],[63975,35023],[63976,35041],[63977,37324],[63978,38626],[63979,21311],[63980,28346],[63981,21533],[63982,29136],[63983,29848],[63984,34298],[63985,38563],[63986,40023],[63987,40607],[63988,26519],[63989,28107],[63990,33256],[63991,31435],[63992,31520],[63993,31890],[63994,29376],[63995,28825],[63996,35672],[63997,20160],[63998,33590],[63999,21050],[64000,20999],[64001,24230],[64002,25299],[64003,31958],[64004,23429],[64005,27934],[64006,26292],[64007,36667],[64008,34892],[64009,38477],[64010,35211],[64011,24275],[64012,20800],[64013,21952],[64016,22618],[64018,26228],[64021,20958],[64022,29482],[64023,30410],[64024,31036],[64025,31070],[64026,31077],[64027,31119],[64028,38742],[64029,31934],[64030,32701],[64032,34322],[64034,35576],[64037,36920],[64038,37117],[64042,39151],[64043,39164],[64044,39208],[64045,40372],[64046,37086],[64047,38583],[64048,20398],[64049,20711],[64050,20813],[64051,21193],[64052,21220],[64053,21329],[64054,21917],[64055,22022],[64056,22120],[64057,22592],[64058,22696],[64059,23652],[64060,23662],[64061,24724],[64062,24936],[64063,24974],[64064,25074],[64065,25935],[64066,26082],[64067,26257],[64068,26757],[64069,28023],[64070,28186],[64071,28450],[64072,29038],[64073,29227],[64074,29730],[64075,30865],[64076,31038],[64077,31049],[64078,31048],[64079,31056],[64080,31062],[64081,31069],[64082,31117],[64083,31118],[64084,31296],[64085,31361],[64086,31680],[64087,32244],[64088,32265],[64089,32321],[64090,32626],[64091,32773],[64092,33261],[64093,33401],[64094,33401],[64095,33879],[64096,35088],[64097,35222],[64098,35585],[64099,35641],[64100,36051],[64101,36104],[64102,36790],[64103,36920],[64104,38627],[64105,38911],[64106,38971],[64107,24693],[64108,148206],[64109,33304],[64112,20006],[64113,20917],[64114,20840],[64115,20352],[64116,20805],[64117,20864],[64118,21191],[64119,21242],[64120,21917],[64121,21845],[64122,21913],[64123,21986],[64124,22618],[64125,22707],[64126,22852],[64127,22868],[64128,23138],[64129,23336],[64130,24274],[64131,24281],[64132,24425],[64133,24493],[64134,24792],[64135,24910],[64136,24840],[64137,24974],[64138,24928],[64139,25074],[64140,25140],[64141,25540],[64142,25628],[64143,25682],[64144,25942],[64145,26228],[64146,26391],[64147,26395],[64148,26454],[64149,27513],[64150,27578],[64151,27969],[64152,28379],[64153,28363],[64154,28450],[64155,28702],[64156,29038],[64157,30631],[64158,29237],[64159,29359],[64160,29482],[64161,29809],[64162,29958],[64163,30011],[64164,30237],[64165,30239],[64166,30410],[64167,30427],[64168,30452],[64169,30538],[64170,30528],[64171,30924],[64172,31409],[64173,31680],[64174,31867],[64175,32091],[64176,32244],[64177,32574],[64178,32773],[64179,33618],[64180,33775],[64181,34681],[64182,35137],[64183,35206],[64184,35222],[64185,35519],[64186,35576],[64187,35531],[64188,35585],[64189,35582],[64190,35565],[64191,35641],[64192,35722],[64193,36104],[64194,36664],[64195,36978],[64196,37273],[64197,37494],[64198,38524],[64199,38627],[64200,38742],[64201,38875],[64202,38911],[64203,38923],[64204,38971],[64205,39698],[64206,40860],[64207,141386],[64208,141380],[64209,144341],[64210,15261],[64211,16408],[64212,16441],[64213,152137],[64214,154832],[64215,163539],[64216,40771],[64217,40846],[64285,1497,1460],[64287,1522,1463],[64298,1513,1473],[64299,1513,1474],[64300,1513,1468,1473],[64301,1513,1468,1474],[64302,1488,1463],[64303,1488,1464],[64304,1488,1468],[64305,1489,1468],[64306,1490,1468],[64307,1491,1468],[64308,1492,1468],[64309,1493,1468],[64310,1494,1468],[64312,1496,1468],[64313,1497,1468],[64314,1498,1468],[64315,1499,1468],[64316,1500,1468],[64318,1502,1468],[64320,1504,1468],[64321,1505,1468],[64323,1507,1468],[64324,1508,1468],[64326,1510,1468],[64327,1511,1468],[64328,1512,1468],[64329,1513,1468],[64330,1514,1468],[64331,1493,1465],[64332,1489,1471],[64333,1499,1471],[64334,1508,1471],[69786,69785,69818],[69788,69787,69818],[69803,69797,69818],[69934,69937,69927],[69935,69938,69927],[70475,70471,70462],[70476,70471,70487],[70843,70841,70842],[70844,70841,70832],[70846,70841,70845],[71098,71096,71087],[71099,71097,71087],[71992,71989,71984],[119134,119127,119141],[119135,119128,119141],[119136,119128,119141,119150],[119137,119128,119141,119151],[119138,119128,119141,119152],[119139,119128,119141,119153],[119140,119128,119141,119154],[119227,119225,119141],[119228,119226,119141],[119229,119225,119141,119150],[119230,119226,119141,119150],[119231,119225,119141,119151],[119232,119226,119141,119151],[194560,20029],[194561,20024],[194562,20033],[194563,131362],[194564,20320],[194565,20398],[194566,20411],[194567,20482],[194568,20602],[194569,20633],[194570,20711],[194571,20687],[194572,13470],[194573,132666],[194574,20813],[194575,20820],[194576,20836],[194577,20855],[194578,132380],[194579,13497],[194580,20839],[194581,20877],[194582,132427],[194583,20887],[194584,20900],[194585,20172],[194586,20908],[194587,20917],[194588,168415],[194589,20981],[194590,20995],[194591,13535],[194592,21051],[194593,21062],[194594,21106],[194595,21111],[194596,13589],[194597,21191],[194598,21193],[194599,21220],[194600,21242],[194601,21253],[194602,21254],[194603,21271],[194604,21321],[194605,21329],[194606,21338],[194607,21363],[194608,21373],[194609,21375],[194610,21375],[194611,21375],[194612,133676],[194613,28784],[194614,21450],[194615,21471],[194616,133987],[194617,21483],[194618,21489],[194619,21510],[194620,21662],[194621,21560],[194622,21576],[194623,21608],[194624,21666],[194625,21750],[194626,21776],[194627,21843],[194628,21859],[194629,21892],[194630,21892],[194631,21913],[194632,21931],[194633,21939],[194634,21954],[194635,22294],[194636,22022],[194637,22295],[194638,22097],[194639,22132],[194640,20999],[194641,22766],[194642,22478],[194643,22516],[194644,22541],[194645,22411],[194646,22578],[194647,22577],[194648,22700],[194649,136420],[194650,22770],[194651,22775],[194652,22790],[194653,22810],[194654,22818],[194655,22882],[194656,136872],[194657,136938],[194658,23020],[194659,23067],[194660,23079],[194661,23000],[194662,23142],[194663,14062],[194664,14076],[194665,23304],[194666,23358],[194667,23358],[194668,137672],[194669,23491],[194670,23512],[194671,23527],[194672,23539],[194673,138008],[194674,23551],[194675,23558],[194676,24403],[194677,23586],[194678,14209],[194679,23648],[194680,23662],[194681,23744],[194682,23693],[194683,138724],[194684,23875],[194685,138726],[194686,23918],[194687,23915],[194688,23932],[194689,24033],[194690,24034],[194691,14383],[194692,24061],[194693,24104],[194694,24125],[194695,24169],[194696,14434],[194697,139651],[194698,14460],[194699,24240],[194700,24243],[194701,24246],[194702,24266],[194703,172946],[194704,24318],[194705,140081],[194706,140081],[194707,33281],[194708,24354],[194709,24354],[194710,14535],[194711,144056],[194712,156122],[194713,24418],[194714,24427],[194715,14563],[194716,24474],[194717,24525],[194718,24535],[194719,24569],[194720,24705],[194721,14650],[194722,14620],[194723,24724],[194724,141012],[194725,24775],[194726,24904],[194727,24908],[194728,24910],[194729,24908],[194730,24954],[194731,24974],[194732,25010],[194733,24996],[194734,25007],[194735,25054],[194736,25074],[194737,25078],[194738,25104],[194739,25115],[194740,25181],[194741,25265],[194742,25300],[194743,25424],[194744,142092],[194745,25405],[194746,25340],[194747,25448],[194748,25475],[194749,25572],[194750,142321],[194751,25634],[194752,25541],[194753,25513],[194754,14894],[194755,25705],[194756,25726],[194757,25757],[194758,25719],[194759,14956],[194760,25935],[194761,25964],[194762,143370],[194763,26083],[194764,26360],[194765,26185],[194766,15129],[194767,26257],[194768,15112],[194769,15076],[194770,20882],[194771,20885],[194772,26368],[194773,26268],[194774,32941],[194775,17369],[194776,26391],[194777,26395],[194778,26401],[194779,26462],[194780,26451],[194781,144323],[194782,15177],[194783,26618],[194784,26501],[194785,26706],[194786,26757],[194787,144493],[194788,26766],[194789,26655],[194790,26900],[194791,15261],[194792,26946],[194793,27043],[194794,27114],[194795,27304],[194796,145059],[194797,27355],[194798,15384],[194799,27425],[194800,145575],[194801,27476],[194802,15438],[194803,27506],[194804,27551],[194805,27578],[194806,27579],[194807,146061],[194808,138507],[194809,146170],[194810,27726],[194811,146620],[194812,27839],[194813,27853],[194814,27751],[194815,27926],[194816,27966],[194817,28023],[194818,27969],[194819,28009],[194820,28024],[194821,28037],[194822,146718],[194823,27956],[194824,28207],[194825,28270],[194826,15667],[194827,28363],[194828,28359],[194829,147153],[194830,28153],[194831,28526],[194832,147294],[194833,147342],[194834,28614],[194835,28729],[194836,28702],[194837,28699],[194838,15766],[194839,28746],[194840,28797],[194841,28791],[194842,28845],[194843,132389],[194844,28997],[194845,148067],[194846,29084],[194847,148395],[194848,29224],[194849,29237],[194850,29264],[194851,149000],[194852,29312],[194853,29333],[194854,149301],[194855,149524],[194856,29562],[194857,29579],[194858,16044],[194859,29605],[194860,16056],[194861,16056],[194862,29767],[194863,29788],[194864,29809],[194865,29829],[194866,29898],[194867,16155],[194868,29988],[194869,150582],[194870,30014],[194871,150674],[194872,30064],[194873,139679],[194874,30224],[194875,151457],[194876,151480],[194877,151620],[194878,16380],[194879,16392],[194880,30452],[194881,151795],[194882,151794],[194883,151833],[194884,151859],[194885,30494],[194886,30495],[194887,30495],[194888,30538],[194889,16441],[194890,30603],[194891,16454],[194892,16534],[194893,152605],[194894,30798],[194895,30860],[194896,30924],[194897,16611],[194898,153126],[194899,31062],[194900,153242],[194901,153285],[194902,31119],[194903,31211],[194904,16687],[194905,31296],[194906,31306],[194907,31311],[194908,153980],[194909,154279],[194910,154279],[194911,31470],[194912,16898],[194913,154539],[194914,31686],[194915,31689],[194916,16935],[194917,154752],[194918,31954],[194919,17056],[194920,31976],[194921,31971],[194922,32000],[194923,155526],[194924,32099],[194925,17153],[194926,32199],[194927,32258],[194928,32325],[194929,17204],[194930,156200],[194931,156231],[194932,17241],[194933,156377],[194934,32634],[194935,156478],[194936,32661],[194937,32762],[194938,32773],[194939,156890],[194940,156963],[194941,32864],[194942,157096],[194943,32880],[194944,144223],[194945,17365],[194946,32946],[194947,33027],[194948,17419],[194949,33086],[194950,23221],[194951,157607],[194952,157621],[194953,144275],[194954,144284],[194955,33281],[194956,33284],[194957,36766],[194958,17515],[194959,33425],[194960,33419],[194961,33437],[194962,21171],[194963,33457],[194964,33459],[194965,33469],[194966,33510],[194967,158524],[194968,33509],[194969,33565],[194970,33635],[194971,33709],[194972,33571],[194973,33725],[194974,33767],[194975,33879],[194976,33619],[194977,33738],[194978,33740],[194979,33756],[194980,158774],[194981,159083],[194982,158933],[194983,17707],[194984,34033],[194985,34035],[194986,34070],[194987,160714],[194988,34148],[194989,159532],[194990,17757],[194991,17761],[194992,159665],[194993,159954],[194994,17771],[194995,34384],[194996,34396],[194997,34407],[194998,34409],[194999,34473],[195000,34440],[195001,34574],[195002,34530],[195003,34681],[195004,34600],[195005,34667],[195006,34694],[195007,17879],[195008,34785],[195009,34817],[195010,17913],[195011,34912],[195012,34915],[195013,161383],[195014,35031],[195015,35038],[195016,17973],[195017,35066],[195018,13499],[195019,161966],[195020,162150],[195021,18110],[195022,18119],[195023,35488],[195024,35565],[195025,35722],[195026,35925],[195027,162984],[195028,36011],[195029,36033],[195030,36123],[195031,36215],[195032,163631],[195033,133124],[195034,36299],[195035,36284],[195036,36336],[195037,133342],[195038,36564],[195039,36664],[195040,165330],[195041,165357],[195042,37012],[195043,37105],[195044,37137],[195045,165678],[195046,37147],[195047,37432],[195048,37591],[195049,37592],[195050,37500],[195051,37881],[195052,37909],[195053,166906],[195054,38283],[195055,18837],[195056,38327],[195057,167287],[195058,18918],[195059,38595],[195060,23986],[195061,38691],[195062,168261],[195063,168474],[195064,19054],[195065,19062],[195066,38880],[195067,168970],[195068,19122],[195069,169110],[195070,38923],[195071,38923],[195072,38953],[195073,169398],[195074,39138],[195075,19251],[195076,39209],[195077,39335],[195078,39362],[195079,39422],[195080,19406],[195081,170800],[195082,39698],[195083,40000],[195084,40189],[195085,19662],[195086,19693],[195087,40295],[195088,172238],[195089,19704],[195090,172293],[195091,172558],[195092,172689],[195093,40635],[195094,19798],[195095,40697],[195096,40702],[195097,40709],[195098,40719],[195099,40726],[195100,40763],[195101,173568]],"composites":[192,193,194,195,196,197,199,200,201,202,203,204,205,206,207,209,210,211,212,213,214,217,218,219,220,221,224,225,226,227,228,229,231,232,233,234,235,236,237,238,239,241,242,243,244,245,246,249,250,251,252,253,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,296,297,298,299,300,301,302,303,304,308,309,310,311,313,314,315,316,317,318,323,324,325,326,327,328,332,333,334,335,336,337,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,416,417,431,432,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,478,479,480,481,482,483,486,487,488,489,490,491,492,493,494,495,496,500,501,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,542,543,550,551,552,553,554,555,556,557,558,559,560,561,562,563,901,902,904,905,906,908,910,911,912,938,939,940,941,942,943,944,970,971,972,973,974,979,980,1024,1025,1027,1031,1036,1037,1038,1049,1081,1104,1105,1107,1111,1116,1117,1118,1142,1143,1217,1218,1232,1233,1234,1235,1238,1239,1242,1243,1244,1245,1246,1247,1250,1251,1252,1253,1254,1255,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1272,1273,1570,1571,1572,1573,1574,1728,1730,1747,2345,2353,2356,2507,2508,2888,2891,2892,2964,3018,3019,3020,3144,3264,3271,3272,3274,3275,3402,3403,3404,3546,3548,3549,3550,4134,6918,6920,6922,6924,6926,6930,6971,6973,6976,6977,6979,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7835,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8050,8052,8054,8056,8058,8060,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8124,8129,8130,8131,8132,8134,8135,8136,8138,8140,8141,8142,8143,8144,8145,8146,8150,8151,8152,8153,8154,8157,8158,8159,8160,8161,8162,8164,8165,8166,8167,8168,8169,8170,8172,8173,8178,8179,8180,8182,8183,8184,8186,8188,8602,8603,8622,8653,8654,8655,8708,8713,8716,8740,8742,8769,8772,8775,8777,8800,8802,8813,8814,8815,8816,8817,8820,8821,8824,8825,8832,8833,8836,8837,8840,8841,8876,8877,8878,8879,8928,8929,8930,8931,8938,8939,8940,8941,12364,12366,12368,12370,12372,12374,12376,12378,12380,12382,12384,12386,12389,12391,12393,12400,12401,12403,12404,12406,12407,12409,12410,12412,12413,12436,12446,12460,12462,12464,12466,12468,12470,12472,12474,12476,12478,12480,12482,12485,12487,12489,12496,12497,12499,12500,12502,12503,12505,12506,12508,12509,12532,12535,12536,12537,12538,12542,69786,69788,69803,69934,69935,70475,70476,70843,70844,70846,71098,71099,71992]} diff --git a/packages/skill-tree/src/byte-source.ts b/packages/skill-tree/src/byte-source.ts new file mode 100644 index 0000000..008192b --- /dev/null +++ b/packages/skill-tree/src/byte-source.ts @@ -0,0 +1,172 @@ +/** + * Minimal forward-only byte reader over a stream, used by the archive + * readers so content is hashed as it streams and never buffered whole. + */ +import { ERROR_CODES, SkillTreeError } from "./errors"; + +/** Archive bytes: a whole buffer, a web stream, or any async iterable of chunks. */ +export type ByteSource = Uint8Array | ReadableStream | AsyncIterable; + +export function readFailed(detail: string, cause?: unknown): SkillTreeError { + return new SkillTreeError(ERROR_CODES.readFailed, "", detail, cause === undefined ? undefined : { cause }); +} + +async function* iterateStream(stream: ReadableStream): AsyncGenerator { + const reader = stream.getReader(); + try { + for (;;) { + const { done, value } = await reader.read(); + if (done) return; + yield value; + } + } finally { + // Stops an upstream producer (or a decompressor) when reading ends early. + await reader.cancel().catch(() => undefined); + } +} + +export function toAsyncIterable(source: ByteSource): AsyncIterable { + if (source instanceof Uint8Array) { + return (async function* () { + yield source; + })(); + } + if (typeof ReadableStream !== "undefined" && source instanceof ReadableStream) return iterateStream(source); + return source as AsyncIterable; +} + +/** Compressed bytes fed per step. */ +const INFLATE_SLICE = 16 * 1024; +const noop = () => undefined; +const EMPTY = Symbol("empty"); + +/** + * Inflates `source` through a web `DecompressionStream` (gzip or raw deflate), + * pull-driven so a decompression bomb stops near the consumer's limit. A new + * slice is written only when no inflated output is waiting and the previous + * write has been taken by the decompressor; otherwise the writable's queue + * (high-water mark counted in chunks) would accept the whole source. The same + * holds for `pipeThrough`, which pumps input regardless of the consumer. + */ +export async function* decompress(source: AsyncIterable, format: "gzip" | "deflate-raw"): AsyncGenerator { + const stream = new DecompressionStream(format); + const writer = stream.writable.getWriter(); + const reader = stream.readable.getReader(); + const input = source[Symbol.asyncIterator](); + let pending: Uint8Array = new Uint8Array(0); + let inputDone = false; + // Settles (to EMPTY) once the decompressor has taken the last written slice. + let taken: Promise = Promise.resolve(EMPTY); + let read = reader.read(); + read.catch(noop); + try { + for (;;) { + // Output wins when queued (a read of a queued chunk is already settled); + // otherwise wait until the decompressor took the last slice, then feed. + const ready = inputDone ? await read : await Promise.race([read, taken]); + if (ready !== EMPTY) { + if (ready.done) return; + yield ready.value; + read = reader.read(); + read.catch(noop); + continue; + } + if (pending.length === 0) { + const next = await input.next(); + if (next.done) { + inputDone = true; + writer.close().catch(noop); // a failure surfaces through `read` + continue; + } + pending = next.value; + continue; + } + const slice = pending.subarray(0, INFLATE_SLICE); + pending = pending.subarray(slice.length); + // The DOM typings take only ArrayBuffer-backed views; any Uint8Array works at runtime. + taken = writer.write(slice as Uint8Array).then(() => EMPTY); + taken.catch(noop); // a rejection is rethrown by the race above + } + } finally { + await reader.cancel().catch(noop); + await Promise.resolve(input.return?.()).catch(noop); + } +} + +export class StreamReader { + private readonly it: AsyncIterator; + private chunk: Uint8Array = new Uint8Array(0); + private offset = 0; + private ended = false; + + constructor(source: AsyncIterable) { + this.it = source[Symbol.asyncIterator](); + } + + private async nextChunk(): Promise { + while (!this.ended) { + const next = await this.it.next(); + if (next.done) { + this.ended = true; + return false; + } + if (next.value.length > 0) { + this.chunk = next.value; + this.offset = 0; + return true; + } + } + return false; + } + + /** + * Reads exactly `n` bytes. Returns null when the stream ends before the + * first byte; throws `tree.read_failed` when it ends part way. + */ + async readExact(n: number): Promise { + const out = new Uint8Array(n); + let filled = 0; + while (filled < n) { + if (this.offset >= this.chunk.length && !(await this.nextChunk())) { + if (filled === 0) return null; + throw readFailed(`stream ends after ${filled} of ${n} bytes`); + } + const take = Math.min(n - filled, this.chunk.length - this.offset); + out.set(this.chunk.subarray(this.offset, this.offset + take), filled); + this.offset += take; + filled += take; + } + return out; + } + + /** Yields exactly `n` bytes in chunks; throws `tree.read_failed` if the stream ends first. */ + async *chunks(n: number): AsyncGenerator { + let left = n; + while (left > 0) { + if (this.offset >= this.chunk.length && !(await this.nextChunk())) { + throw readFailed(`stream ends ${left} bytes before the end of an entry`); + } + const take = Math.min(left, this.chunk.length - this.offset); + const piece = this.chunk.subarray(this.offset, this.offset + take); + this.offset += take; + left -= take; + yield piece; + } + } + + async skip(n: number): Promise { + for await (const piece of this.chunks(n)) void piece; + } + + /** Releases the underlying stream after an early stop. */ + async close(): Promise { + if (!this.ended) await this.it.return?.(); + } +} + +/** Wraps any non-contract failure of a reader as `tree.read_failed`. */ +export function asTreeError(err: unknown): SkillTreeError { + if (err instanceof SkillTreeError) return err; + const message = err instanceof Error ? err.message : String(err); + return readFailed(`archive read failed: ${message}`, err); +} diff --git a/packages/skill-tree/src/collision.ts b/packages/skill-tree/src/collision.ts new file mode 100644 index 0000000..395edd4 --- /dev/null +++ b/packages/skill-tree/src/collision.ts @@ -0,0 +1,86 @@ +/** + * File-versus-directory and case-collision checks (contract 4.4, validation + * steps 7 and 8). Keys use Unicode canonical caseless matching, + * NFD(fold(NFD(path))), with the generated Unicode 15.0.0 tables. + */ +import { ERROR_CODES, SkillTreeError, treeError } from "./errors"; +import { fold, nfd } from "./unicode-15"; + +/** Canonical caseless key of a path. Folding never touches "/". */ +export function foldKey(p: string): string { + return nfd(fold(nfd(p))); +} + +/** Every directory prefix of `p`, shortest first. */ +function dirPrefixes(p: string): string[] { + const out: string[] = []; + for (let i = p.indexOf("/"); i >= 0; i = p.indexOf("/", i + 1)) out.push(p.slice(0, i)); + return out; +} + +/** A file whose exact path is also a directory of another file or a directory entry. */ +export function checkFileDirs(files: readonly string[], dirEntries: readonly string[]): SkillTreeError | null { + const dirs = new Map(); + for (const file of files) { + for (const dir of dirPrefixes(file)) if (!dirs.has(dir)) dirs.set(dir, file); + } + for (const file of files) { + const child = dirs.get(file); + if (child !== undefined) { + return treeError(ERROR_CODES.unsafePath, file, `is a file and also the directory of ${JSON.stringify(child)}`); + } + } + const entries = new Set(dirEntries); + for (const file of files) { + if (entries.has(file)) return treeError(ERROR_CODES.unsafePath, file, "is a file and also a directory entry"); + } + return null; +} + +/** + * Paths a case-insensitive file system would merge: two files with equal + * keys (including a path listed twice), a file whose key equals a directory + * or directory entry key, and two distinct directories with equal keys. + * Directory entries are compared with files only. Checks follow input order, + * so a given entry list always reports the same path. + */ +export function checkCollisions(files: readonly string[], dirEntries: readonly string[]): SkillTreeError | null { + const byKey = new Map(); + for (const file of files) { + const key = foldKey(file); + const prior = byKey.get(key); + if (prior !== undefined) { + return treeError(ERROR_CODES.caseCollision, file, `collides with ${JSON.stringify(prior)} under case folding`); + } + byKey.set(key, file); + } + const foldedDirs = new Map(); + let dirConflict: SkillTreeError | null = null; + for (const file of files) { + for (const dir of dirPrefixes(file)) { + const key = foldKey(dir); + const prior = foldedDirs.get(key); + if (prior === undefined) foldedDirs.set(key, { dir, file }); + else if (prior.dir !== dir && dirConflict === null) { + dirConflict = treeError( + ERROR_CODES.caseCollision, + file, + `directory ${JSON.stringify(dir)} collides with directory ${JSON.stringify(prior.dir)} of ${JSON.stringify(prior.file)} under case folding`, + ); + } + } + } + for (const file of files) { + const owner = foldedDirs.get(foldKey(file)); + if (owner !== undefined) { + return treeError(ERROR_CODES.caseCollision, file, `collides under case folding with the directory of ${JSON.stringify(owner.file)}`); + } + } + for (const dir of dirEntries) { + const prior = byKey.get(foldKey(dir)); + if (prior !== undefined) { + return treeError(ERROR_CODES.caseCollision, prior, `collides under case folding with directory entry ${JSON.stringify(dir)}`); + } + } + return dirConflict; +} diff --git a/packages/skill-tree/src/entry-collector.ts b/packages/skill-tree/src/entry-collector.ts new file mode 100644 index 0000000..0951970 --- /dev/null +++ b/packages/skill-tree/src/entry-collector.ts @@ -0,0 +1,71 @@ +/** + * Collects the entries an archive reader presents, enforcing the contract + * limits while content streams (contract 4.6): bytes are counted as they are + * read, header sizes are never trusted, and reading stops at the first limit. + */ +import { ERROR_CODES, treeError } from "./errors"; +import { createSha256 } from "./serialize"; +import type { TreeManifest } from "./serialize"; +import { LIMITS, buildTree } from "./tree"; +import type { TreeEntry, TreeLimits } from "./tree"; + +export class EntryCollector { + readonly entries: TreeEntry[] = []; + private listed = 0; + private files = 0; + private total = 0; + + constructor(private readonly limits: TreeLimits = LIMITS) {} + + /** Counts one presented entry of any kind toward the entry limit. */ + present(): void { + if (++this.listed > this.limits.maxEntries) { + throw treeError(ERROR_CODES.limitExceeded, "", `archive has more than ${this.limits.maxEntries} entries`); + } + } + + /** Hashes one regular file's content as it streams, counting it toward the file and byte limits. */ + async hashFile(path: string, content: AsyncIterable): Promise<{ size: number; sha256: string }> { + if (++this.files > this.limits.maxFiles) { + throw treeError(ERROR_CODES.limitExceeded, path, `tree has more than ${this.limits.maxFiles} files`); + } + const hash = createSha256(); + let size = 0; + for await (const chunk of content) { + size += chunk.length; + this.total += chunk.length; + if (size > this.limits.maxFileSize) { + throw treeError(ERROR_CODES.limitExceeded, path, `file exceeds ${this.limits.maxFileSize} bytes`); + } + if (this.total > this.limits.maxTreeSize) { + throw treeError(ERROR_CODES.limitExceeded, path, `tree exceeds ${this.limits.maxTreeSize} bytes`); + } + hash.update(chunk); + } + return { size, sha256: hash.hex() }; + } + + add(entry: TreeEntry): void { + this.entries.push(entry); + } + + build(): TreeManifest { + return buildTree(this.entries, { listed: this.listed, limits: this.limits }); + } +} + +const utf8Strict = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); +const utf8Lossy = new TextDecoder("utf-8", { ignoreBOM: true }); + +/** + * Decodes raw entry name bytes. Invalid UTF-8 (including WTF-8 surrogates) + * is never repaired: the lossy text only serves noise matching and messages, + * and the entry fails with `tree.unsafe_path`. + */ +export function decodeName(raw: Uint8Array): { path: string; utf8Valid: boolean } { + try { + return { path: utf8Strict.decode(raw), utf8Valid: true }; + } catch { + return { path: utf8Lossy.decode(raw), utf8Valid: false }; + } +} diff --git a/packages/skill-tree/src/errors.ts b/packages/skill-tree/src/errors.ts new file mode 100644 index 0000000..84b2ace --- /dev/null +++ b/packages/skill-tree/src/errors.ts @@ -0,0 +1,42 @@ +/** + * Contract error codes of `agentkit.skill-tree/v1` and package identity + * (AgentKit skill lifecycle contract, section 11). Callers branch on `code`, + * never on the message text. + */ +export const ERROR_CODES = { + identityInvalid: "identity.invalid", + identityReservedPublisher: "identity.reserved_publisher", + identityReservedAlias: "identity.reserved_alias", + unsafePath: "tree.unsafe_path", + nonNfcPath: "tree.non_nfc_path", + caseCollision: "tree.case_collision", + unsupportedEntry: "tree.unsupported_entry", + limitExceeded: "tree.limit_exceeded", + empty: "tree.empty", + readFailed: "tree.read_failed", +} as const; + +export type SkillTreeErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES]; + +/** A classified contract failure. `path` names the offending tree path when one exists. */ +export class SkillTreeError extends Error { + readonly code: SkillTreeErrorCode; + readonly path: string; + readonly detail: string; + + constructor(code: SkillTreeErrorCode, path: string, detail: string, options?: { cause?: unknown }) { + super(path === "" ? `${code}: ${detail}` : `${code}: ${JSON.stringify(path)}: ${detail}`, options); + this.name = "SkillTreeError"; + this.code = code; + this.path = path; + this.detail = detail; + } +} + +export function treeError(code: SkillTreeErrorCode, path: string, detail: string): SkillTreeError { + return new SkillTreeError(code, path, detail); +} + +export function isSkillTreeError(value: unknown): value is SkillTreeError { + return value instanceof SkillTreeError; +} diff --git a/packages/skill-tree/src/exposure.ts b/packages/skill-tree/src/exposure.ts new file mode 100644 index 0000000..fc1b003 --- /dev/null +++ b/packages/skill-tree/src/exposure.ts @@ -0,0 +1,76 @@ +/** + * Exposure derivation from SKILL.md frontmatter (AgentKit skill lifecycle + * contract 10.2). Keys are read as YAML 1.2 nodes, never decoded into typed + * booleans: only the plain scalars true/True/TRUE and false/False/FALSE count. + */ +import { isAlias, isMap, isScalar, parseDocument } from "yaml"; +import type { Node, Pair } from "yaml"; + +export type Exposure = "INTERNAL" | "EXPLICIT" | "AUTO"; + +export interface ExposureResult { + exposure: Exposure; + /** True when the frontmatter was unusable and AUTO is a fallback. */ + warning: boolean; +} + +const EXPOSURE_KEYS = new Set(["user-invocable", "disable-model-invocation"]); +const AUTO: ExposureResult = { exposure: "AUTO", warning: false }; +const AUTO_WARN: ExposureResult = { exposure: "AUTO", warning: true }; + +function keyName(key: unknown): string { + if (!isScalar(key)) return ""; + return typeof key.source === "string" ? key.source : String(key.value); +} + +/** An explicit tag, an anchor or an alias makes a key or value unusable. */ +function isUnsafeNode(node: unknown): boolean { + if (isAlias(node)) return true; + if (node === null || typeof node !== "object") return false; + const { anchor, tag } = node as Node; + return (anchor !== undefined && anchor !== "") || (tag !== undefined && tag !== ""); +} + +/** The boolean of a plain scalar spelled exactly as YAML 1.2 core booleans, else undefined. */ +function plainBool(node: unknown): boolean | undefined { + if (!isScalar(node) || node.type !== "PLAIN" || typeof node.source !== "string") return undefined; + if (["true", "True", "TRUE"].includes(node.source)) return true; + if (["false", "False", "FALSE"].includes(node.source)) return false; + return undefined; +} + +/** Exposure of a frontmatter block (the text between the delimiter lines). */ +export function frontmatterExposure(frontmatter: string): ExposureResult { + const doc = parseDocument(frontmatter, { version: "1.2", uniqueKeys: false }); + if (doc.errors.length > 0) return AUTO_WARN; + // An empty or comment-only block holds no document node. + if (doc.contents === null) return AUTO; + if (!isMap(doc.contents)) return AUTO_WARN; + const values = new Map(); + for (const pair of doc.contents.items as Pair[]) { + const name = keyName(pair.key); + if (!EXPOSURE_KEYS.has(name)) continue; + if (values.has(name) || isUnsafeNode(pair.key) || isUnsafeNode(pair.value)) return AUTO_WARN; + values.set(name, pair.value); + } + if (plainBool(values.get("user-invocable")) === false) return { exposure: "INTERNAL", warning: false }; + if (plainBool(values.get("disable-model-invocation")) === true) return { exposure: "EXPLICIT", warning: false }; + return AUTO; +} + +const isFence = (line: string) => line.replace(/[ \t]+$/, "") === "---"; + +/** + * Exposure of a whole SKILL.md: frontmatter is the block between a first + * line "---" and the next "---" line, after removing a UTF-8 BOM and the CR + * of each CRLF. No first fence means no frontmatter; an unclosed block warns. + */ +export function skillFileExposure(file: string): ExposureResult { + const text = (file.startsWith("") ? file.slice(1) : file).replace(/\r\n/g, "\n"); + const lines = text.split("\n"); + if (!isFence(lines[0] ?? "")) return AUTO; + for (let i = 1; i < lines.length; i++) { + if (isFence(lines[i]!)) return frontmatterExposure(lines.slice(1, i).join("\n")); + } + return AUTO_WARN; +} diff --git a/packages/skill-tree/src/identity.ts b/packages/skill-tree/src/identity.ts new file mode 100644 index 0000000..7f28485 --- /dev/null +++ b/packages/skill-tree/src/identity.ts @@ -0,0 +1,153 @@ +/** + * Package identity, provenance trust and alias rules (AgentKit skill + * lifecycle contract section 2). Every check throws a `SkillTreeError` with + * a contract code; nothing here folds case beyond ASCII. + */ +import { ERROR_CODES, treeError } from "./errors"; +import { asciiLower, asciiUpper, segmentViolation } from "./path-rules"; + +/** The SkillX package name pattern; identities compare byte-for-byte after validation. */ +export const IDENTITY_PATTERN = /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/; +export const MAX_IDENTITY_SEGMENT_BYTES = 64; +export const MAX_ALIAS_BYTES = 128; + +/** Publisher reserved for content composed from an AgentKit kit. */ +export const RESERVED_PUBLISHER = "agentkit"; + +export const PROVIDERS = ["kit", "local", "git", "skillx"] as const; +export type Provider = (typeof PROVIDERS)[number]; +export const KIT_ORIGINS = ["remote-signed", "local-dev"] as const; +export type KitOrigin = (typeof KIT_ORIGINS)[number]; +export type Trust = "signed-kit" | "publisher-signed" | "local-unverified"; + +const KIT_DIR_PREFIX = "ak-"; + +const invalid = (detail: string) => treeError(ERROR_CODES.identityInvalid, "", detail); + +function splitIdentity(id: string): [publisher: string, slug: string] { + const slash = id.indexOf("/"); + return [id.slice(1, slash), id.slice(slash + 1)]; +} + +/** `@/` whose publisher and slug each pass the tree segment rules and are at most 64 bytes. */ +export function validateIdentity(id: string): void { + if (!IDENTITY_PATTERN.test(id)) throw invalid(`identity ${JSON.stringify(id)} does not match ${IDENTITY_PATTERN.source}`); + for (const segment of splitIdentity(id)) { + // The pattern admits ASCII only, so the length in bytes is the string length. + if (segment.length > MAX_IDENTITY_SEGMENT_BYTES) { + throw invalid(`identity ${JSON.stringify(id)} segment exceeds ${MAX_IDENTITY_SEGMENT_BYTES} bytes`); + } + const reason = segmentViolation(segment); + if (reason !== "") throw invalid(`identity ${JSON.stringify(id)} segment ${JSON.stringify(segment)} ${reason}`); + } +} + +/** Maps a kit skill directory (`ak-plan`) to its identity (`@agentkit/plan`) and portable alias. */ +export function kitIdentity(dirName: string): { identity: string; alias: string } { + if (!dirName.startsWith(KIT_DIR_PREFIX)) throw invalid(`kit skill directory ${JSON.stringify(dirName)} does not start with "ak-"`); + const identity = `@${RESERVED_PUBLISHER}/${dirName.slice(KIT_DIR_PREFIX.length)}`; + validateIdentity(identity); + return { identity, alias: dirName }; +} + +function isProvider(value: string): value is Provider { + return (PROVIDERS as readonly string[]).includes(value); +} + +function checkPublisherFor(identity: string, provider: Provider): void { + validateIdentity(identity); + const [publisher] = splitIdentity(identity); + if (publisher === RESERVED_PUBLISHER && provider !== "kit") { + throw treeError(ERROR_CODES.identityReservedPublisher, "", `provider ${provider} cannot use the reserved publisher of ${identity}`); + } + if (publisher !== RESERVED_PUBLISHER && provider === "kit") { + throw invalid(`kit content must use the "${RESERVED_PUBLISHER}" publisher, not ${identity}`); + } +} + +/** Provider, then identity, then the reserved-publisher pairing, in contract order. */ +export function checkPublisher(identity: string, provider: string): void { + if (!isProvider(provider)) throw invalid(`unknown source provider ${JSON.stringify(provider)} for ${identity}`); + checkPublisherFor(identity, provider); +} + +export interface Provenance { + provider: string; + /** Kit sources only. */ + origin?: string; + /** SkillX releases only: whether publisher provenance verified. */ + verified?: boolean; + /** Whether the composition has a non-empty overlay. */ + overlay?: boolean; +} + +/** Trust of an accepted package; trust follows origin, not identity. */ +export function trustOf(identity: string, p: Provenance): Trust { + if (!isProvider(p.provider)) throw invalid(`unknown source provider ${JSON.stringify(p.provider)} for ${identity}`); + if (p.provider === "kit" && !(KIT_ORIGINS as readonly string[]).includes(p.origin ?? "")) { + throw invalid(`unknown kit origin ${JSON.stringify(p.origin ?? "")} for ${identity}`); + } + checkPublisherFor(identity, p.provider); + if (p.overlay === true) return "local-unverified"; + if (p.provider === "kit" && p.origin === "remote-signed") return "signed-kit"; + if (p.provider === "skillx" && p.verified === true) return "publisher-signed"; + return "local-unverified"; +} + +const hasAlphanumeric = (s: string) => /[A-Za-z0-9]/.test(s); + +function checkAliasShape(alias: string): void { + if (alias === "" || alias.length > MAX_ALIAS_BYTES) throw invalid(`alias ${JSON.stringify(alias)} is not 1 to ${MAX_ALIAS_BYTES} characters`); + if (!/^[A-Za-z0-9._:/$-]+$/.test(alias)) throw invalid(`alias ${JSON.stringify(alias)} contains a character outside [A-Za-z0-9._:/$-]`); + let rest = alias; + if (alias.startsWith("/")) { + rest = alias.slice(1); + if (rest.includes("/") || !rest.includes(":")) { + throw invalid(`alias ${JSON.stringify(alias)} starts with "/" but is not a native namespace:command form`); + } + } + for (const segment of rest.split("/")) { + if (segment === "" || segment === "." || segment === "..") throw invalid(`alias ${JSON.stringify(alias)} has an empty, "." or ".." segment`); + const parts = segment.split(":"); + if (parts.every(hasAlphanumeric)) continue; + if (parts.includes("")) throw invalid(`alias ${JSON.stringify(alias)} has a ":" without text on both sides`); + throw invalid(`alias ${JSON.stringify(alias)} has a segment or ":"-separated part without an ASCII letter or digit`); + } +} + +function checkAliasInput(identity: string, alias: string): void { + validateIdentity(identity); + if (/[^\x00-\x7f]/.test(alias)) throw invalid(`alias ${JSON.stringify(alias)} contains a non-ASCII character`); + checkAliasShape(alias); +} + +function checkReservedAlias(identity: string, alias: string): void { + if (splitIdentity(identity)[0] === RESERVED_PUBLISHER) return; + const segments = asciiUpper(alias.replace(/^\/+/, "")).split("/"); + for (const raw of segments) { + const segment = raw.replace(/^\$+/, ""); + if (segment.startsWith("AK-") || segment.startsWith("AK:")) { + throw treeError(ERROR_CODES.identityReservedAlias, "", `alias ${JSON.stringify(alias)} is reserved for @${RESERVED_PUBLISHER} identities, not ${identity}`); + } + } +} + +/** Validates an invocation alias for an identity: shape first, then the reserved `ak-`/`ak:` prefixes. */ +export function checkAlias(identity: string, alias: string): void { + checkAliasInput(identity, alias); + checkReservedAlias(identity, alias); +} + +/** Validates a projection directory name: one tree-safe segment without ":" or "$". */ +export function checkDirectoryAlias(identity: string, alias: string): void { + checkAliasInput(identity, alias); + if (/[/:$]/.test(alias)) throw invalid(`directory alias ${JSON.stringify(alias)} is not one segment without ":" or "$"`); + const reason = segmentViolation(alias); + if (reason !== "") throw invalid(`directory alias ${JSON.stringify(alias)} ${reason}`); + checkReservedAlias(identity, alias); +} + +/** Group key of a directory alias: only ASCII A-Z mapped to a-z. */ +export function directoryAliasKey(alias: string): string { + return asciiLower(alias); +} diff --git a/packages/skill-tree/src/index.ts b/packages/skill-tree/src/index.ts new file mode 100644 index 0000000..fc01487 --- /dev/null +++ b/packages/skill-tree/src/index.ts @@ -0,0 +1,50 @@ +/** + * `@skillx/skill-tree`: the TypeScript implementation of AgentKit's + * `agentkit.skill-tree/v1` canonical tree digest, its tar and zip readers, + * package identity and alias rules, and frontmatter exposure. It must agree + * with the AgentKit conformance vectors vendored in `fixtures/vectors`. + */ +export { ERROR_CODES, SkillTreeError, isSkillTreeError } from "./errors"; +export type { SkillTreeErrorCode } from "./errors"; + +export { + MODE_EXECUTABLE, + MODE_REGULAR, + MODE_SOURCE_ASSUMED, + MODE_SOURCE_RECORDED, + TREE_SCHEMA, + compareUtf8, + serializeTree, + treeDigest, +} from "./serialize"; +export type { FileMode, ModeSource, TreeFile, TreeManifest } from "./serialize"; + +export { LIMITS, buildTree, headerMode } from "./tree"; +export type { BuildOptions, EntryKind, TreeEntry } from "./tree"; + +export { isNoisePath, validatePath } from "./path-rules"; +export { foldKey } from "./collision"; +export { UNICODE_VERSION } from "./unicode-15"; + +export type { ByteSource } from "./byte-source"; +export { readTarTree, tarEntryKind } from "./tar-reader"; +export type { TarReadOptions } from "./tar-reader"; +export { readZipTree } from "./zip-reader"; +export type { ZipReadOptions } from "./zip-reader"; +export type { RandomAccessSource } from "./zip-records"; + +export { + IDENTITY_PATTERN, + RESERVED_PUBLISHER, + checkAlias, + checkDirectoryAlias, + checkPublisher, + directoryAliasKey, + kitIdentity, + trustOf, + validateIdentity, +} from "./identity"; +export type { KitOrigin, Provenance, Provider, Trust } from "./identity"; + +export { frontmatterExposure, skillFileExposure } from "./exposure"; +export type { Exposure, ExposureResult } from "./exposure"; diff --git a/packages/skill-tree/src/path-rules.ts b/packages/skill-tree/src/path-rules.ts new file mode 100644 index 0000000..624c821 --- /dev/null +++ b/packages/skill-tree/src/path-rules.ts @@ -0,0 +1,155 @@ +/** + * Path and segment rules of `agentkit.skill-tree/v1` (contract 4.4) and the + * excluded noise (contract 4.5). Rules are ordered tables: the first failing + * rule wins, matching the AgentKit reference implementation. + */ +import { ERROR_CODES, SkillTreeError, treeError } from "./errors"; +import { isAssigned, isFormat, isNfc } from "./unicode-15"; + +export const MAX_PATH_BYTES = 512; +export const MAX_SEGMENT_BYTES = 255; +export const MAX_SEGMENTS = 32; + +/** Reserved prefix of AgentKit temporary files; matched exactly and case-sensitively. */ +export const TEMP_PREFIX = ".ak-tmp."; + +const NOISE_DIRS = new Set([".git", ".hg", ".svn", "__pycache__", ".pytest_cache"]); +const NOISE_FILES = new Set([".DS_Store", "Thumbs.db", "desktop.ini"]); + +const WINDOWS_RESERVED = new Set([ + "CON", "PRN", "AUX", "NUL", "CONIN$", "CONOUT$", + ...Array.from({ length: 10 }, (_, i) => `COM${i}`), + ...Array.from({ length: 10 }, (_, i) => `LPT${i}`), + "COM¹", "COM²", "COM³", "LPT¹", "LPT²", "LPT³", +]); + +const MAX_SHORT_NAME_STEM = 8; +const FORBIDDEN_ASCII = new Set(Array.from('\\:<>"|?*')); + +/** UTF-8 byte length of a well-formed string. */ +export function utf8Length(s: string): number { + let n = 0; + for (const ch of s) { + const cp = ch.codePointAt(0)!; + n += cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4; + } + return n; +} + +/** True when the string holds no unpaired surrogate, so it encodes to valid UTF-8. */ +export function isWellFormed(s: string): boolean { + for (let i = 0; i < s.length; i++) { + const c = s.charCodeAt(i); + if (c >= 0xd800 && c <= 0xdbff) { + const next = s.charCodeAt(i + 1); + if (!(next >= 0xdc00 && next <= 0xdfff)) return false; + i++; + } else if (c >= 0xdc00 && c <= 0xdfff) { + return false; + } + } + return true; +} + +export function asciiUpper(s: string): string { + return s.replace(/[a-z]/g, (c) => c.toUpperCase()); +} + +export function asciiLower(s: string): string { + return s.replace(/[A-Z]/g, (c) => c.toLowerCase()); +} + +/** Separators, Windows-forbidden characters, C0/C1 controls, Cf and unassigned (Cn). */ +function forbiddenCodePoint(cp: number): boolean { + if (cp < 0x80 && FORBIDDEN_ASCII.has(String.fromCharCode(cp))) return true; + if (cp < 0x20 || (cp >= 0x7f && cp <= 0x9f)) return true; + if (isFormat(cp)) return true; + return !isAssigned(cp); +} + +function stemOf(segment: string): string { + const dot = segment.indexOf("."); + return dot < 0 ? segment : segment.slice(0, dot); +} + +function isWindowsReservedName(segment: string): boolean { + return WINDOWS_RESERVED.has(asciiUpper(stemOf(segment).replace(/ +$/, ""))); +} + +function isShortNameShaped(segment: string): boolean { + const stem = stemOf(segment); + return utf8Length(stem) <= MAX_SHORT_NAME_STEM && /~[0-9]/.test(stem); +} + +type Rule = readonly [reason: string, bad: (s: string) => boolean]; + +const PATH_RULES: readonly Rule[] = [ + ["is empty", (p) => p === ""], + ["is not valid UTF-8", (p) => !isWellFormed(p)], + [`exceeds ${MAX_PATH_BYTES} bytes`, (p) => utf8Length(p) > MAX_PATH_BYTES], + [`exceeds ${MAX_SEGMENTS} segments`, (p) => p.split("/").length > MAX_SEGMENTS], +]; + +const SEGMENT_RULES: readonly Rule[] = [ + ["is empty (absolute path or repeated separator)", (s) => s === ""], + ["is a relative directory reference", (s) => s === "." || s === ".."], + [`exceeds ${MAX_SEGMENT_BYTES} bytes`, (s) => utf8Length(s) > MAX_SEGMENT_BYTES], + [`starts with the reserved temporary-file prefix ${TEMP_PREFIX}`, (s) => s.startsWith(TEMP_PREFIX)], + [ + "contains a forbidden, control, format or unassigned character", + (s) => Array.from(s).some((ch) => forbiddenCodePoint(ch.codePointAt(0)!)), + ], + ["ends with a space or dot", (s) => s.endsWith(" ") || s.endsWith(".")], + ["is a Windows reserved device name", isWindowsReservedName], + ["is shaped like an 8.3 short name", isShortNameShaped], +]; + +/** The reason of the first segment rule `segment` fails, or "" when it passes. */ +export function segmentViolation(segment: string): string { + for (const [reason, bad] of SEGMENT_RULES) if (bad(segment)) return reason; + return ""; +} + +/** + * Structural path and segment rules, without NFC. `utf8Valid` is false when + * the raw name bytes were not valid UTF-8 and `p` is only a lossy decoding. + */ +export function checkPathRules(p: string, utf8Valid = true): SkillTreeError | null { + if (p === "") return treeError(ERROR_CODES.unsafePath, p, "path is empty"); + if (!utf8Valid) return treeError(ERROR_CODES.unsafePath, p, "path is not valid UTF-8"); + for (const [reason, bad] of PATH_RULES) { + if (bad(p)) return treeError(ERROR_CODES.unsafePath, p, `path ${reason}`); + } + for (const segment of p.split("/")) { + const reason = segmentViolation(segment); + if (reason !== "") return treeError(ERROR_CODES.unsafePath, p, `segment ${JSON.stringify(segment)} ${reason}`); + } + return null; +} + +export function checkNfc(p: string): SkillTreeError | null { + return isNfc(p) ? null : treeError(ERROR_CODES.nonNfcPath, p, "path is not in Unicode NFC"); +} + +/** + * Validates one tree path. Returns null when it is safe, otherwise a + * `tree.unsafe_path` or `tree.non_nfc_path` error. Never throws. + */ +export function validatePath(p: string): SkillTreeError | null { + return checkPathRules(p) ?? checkNfc(p); +} + +export function isNoiseDirName(name: string): boolean { + return NOISE_DIRS.has(name); +} + +export function isNoiseFileName(name: string): boolean { + return NOISE_FILES.has(name); +} + +/** Whether a tree path is noise: a noise directory segment or a noise file base name. */ +export function isNoisePath(p: string): boolean { + const segments = p.split("/"); + const name = segments.pop() ?? ""; + return segments.some(isNoiseDirName) || isNoiseFileName(name); +} diff --git a/packages/skill-tree/src/serialize.ts b/packages/skill-tree/src/serialize.ts new file mode 100644 index 0000000..1230d5f --- /dev/null +++ b/packages/skill-tree/src/serialize.ts @@ -0,0 +1,86 @@ +/** + * Canonical serialization and digest of `agentkit.skill-tree/v1` (contract + * 4.8): a header line, then one ` ` line per file, + * sorted by the raw UTF-8 bytes of the path. The tree digest is `sha256:` + * plus the hex SHA-256 of the whole serialization. + */ +import { createHash } from "node:crypto"; + +export const TREE_SCHEMA = "agentkit.skill-tree/v1"; + +export const MODE_REGULAR = "100644"; +export const MODE_EXECUTABLE = "100755"; +export type FileMode = typeof MODE_REGULAR | typeof MODE_EXECUTABLE; + +export const MODE_SOURCE_RECORDED = "recorded"; +export const MODE_SOURCE_ASSUMED = "assumed"; +export type ModeSource = typeof MODE_SOURCE_RECORDED | typeof MODE_SOURCE_ASSUMED; + +/** One regular file of a tree. `sha256` is the lowercase hex digest of its content. */ +export interface TreeFile { + path: string; + mode: FileMode; + size: number; + sha256: string; +} + +/** The tree manifest; `files` are sorted by raw UTF-8 path bytes. */ +export interface TreeManifest { + schema: typeof TREE_SCHEMA; + digest: string; + modeSource: ModeSource; + files: TreeFile[]; +} + +/** + * Compares two well-formed strings by their UTF-8 bytes, which is code point + * order (UTF-16 code unit order differs above U+FFFF). + */ +export function compareUtf8(a: string, b: string): number { + const ia = a[Symbol.iterator](); + const ib = b[Symbol.iterator](); + for (;;) { + const ca = ia.next(); + const cb = ib.next(); + if (ca.done || cb.done) return ca.done && cb.done ? 0 : ca.done ? -1 : 1; + const diff = ca.value.codePointAt(0)! - cb.value.codePointAt(0)!; + if (diff !== 0) return diff < 0 ? -1 : 1; + } +} + +export function sortFiles(files: readonly T[]): T[] { + return [...files].sort((a, b) => compareUtf8(a.path, b.path)); +} + +/** + * Renders the canonical serialization. Only a validated file set, whose + * paths are unique, has a defined serialization. + */ +export function serializeTree(files: readonly TreeFile[]): string { + let out = `${TREE_SCHEMA}\n`; + for (const f of sortFiles(files)) out += `${f.mode} ${f.sha256} ${f.size} ${f.path}\n`; + return out; +} + +export function sha256Hex(data: string | Uint8Array): string { + return createHash("sha256").update(data).digest("hex"); +} + +/** `sha256:` over the canonical serialization of `files`. */ +export function treeDigest(files: readonly TreeFile[]): string { + return `sha256:${sha256Hex(serializeTree(files))}`; +} + +/** An incremental SHA-256, for hashing file content as it streams. */ +export interface StreamingHash { + update(chunk: Uint8Array): void; + hex(): string; +} + +export function createSha256(): StreamingHash { + const hash = createHash("sha256"); + return { + update: (chunk) => void hash.update(chunk), + hex: () => hash.digest("hex"), + }; +} diff --git a/packages/skill-tree/src/tar-header.ts b/packages/skill-tree/src/tar-header.ts new file mode 100644 index 0000000..86ce14b --- /dev/null +++ b/packages/skill-tree/src/tar-header.ts @@ -0,0 +1,159 @@ +/** + * Tar header and PAX record parsing with the semantics of Go archive/tar, + * the reader the contract names (contract 4.1). Malformed input throws + * `tree.read_failed`. + */ +import { readFailed } from "./byte-source"; + +export const BLOCK = 512; +/** Go archive/tar caps PAX and GNU long-name payloads at 1 MiB. */ +export const MAX_SPECIAL_FILE_SIZE = 1 << 20; + +export interface RawHeader { + /** Raw name bytes (ustar prefix joined), before any PAX or GNU override. */ + name: Uint8Array; + linkname: Uint8Array; + mode: number; + size: number; + typeflag: string; + /** Old GNU sparse ('S') extension flag at offset 482. */ + gnuExtended: boolean; +} + +const latin = new TextDecoder("latin1"); + +function cString(block: Uint8Array, start: number, length: number): Uint8Array { + const field = block.subarray(start, start + length); + const nul = field.indexOf(0); + return nul < 0 ? field : field.subarray(0, nul); +} + +function trimField(field: Uint8Array): string { + return latin.decode(field).replace(/^[ \0]+|[ \0]+$/g, ""); +} + +/** Octal or GNU base-256 numeric field, like Go's parseNumeric. */ +export function parseNumeric(field: Uint8Array, what: string): number { + const first = field[0] ?? 0; + if (first & 0x80) { + if (first & 0x40) throw readFailed(`negative base-256 ${what}`); + let value = first & 0x3f; + for (const byte of field.subarray(1)) { + value = value * 256 + byte; + if (!Number.isSafeInteger(value)) throw readFailed(`${what} overflows`); + } + return value; + } + const text = trimField(field); + if (text === "") return 0; + if (!/^[0-7]+$/.test(text)) throw readFailed(`invalid octal ${what} ${JSON.stringify(text)}`); + const value = parseInt(text, 8); + if (!Number.isSafeInteger(value)) throw readFailed(`${what} overflows`); + return value; +} + +function checksumMatches(block: Uint8Array): boolean { + const stored = trimField(block.subarray(148, 156)); + if (!/^[0-7]+$/.test(stored)) return false; + const want = parseInt(stored, 8); + let unsigned = 0; + let signed = 0; + for (let i = 0; i < BLOCK; i++) { + const byte = i >= 148 && i < 156 ? 0x20 : block[i]!; + unsigned += byte; + signed += byte > 127 ? byte - 256 : byte; + } + return want === unsigned || want === signed; +} + +function startsWith(block: Uint8Array, offset: number, text: string): boolean { + for (let i = 0; i < text.length; i++) if (block[offset + i] !== text.charCodeAt(i)) return false; + return true; +} + +export function isZeroBlock(block: Uint8Array): boolean { + return block.every((b) => b === 0); +} + +export function parseHeader(block: Uint8Array): RawHeader { + if (!checksumMatches(block)) throw readFailed("tar header checksum mismatch"); + let name = cString(block, 0, 100); + const ustar = startsWith(block, 257, "ustar\u000000"); + const gnu = startsWith(block, 257, "ustar \u0000"); + if (ustar) { + // star archives end the header with "tar\0" and keep a shorter prefix. + const star = startsWith(block, 508, "tar\u0000"); + const prefix = cString(block, 345, star ? 131 : 155); + if (prefix.length > 0) { + const joined = new Uint8Array(prefix.length + 1 + name.length); + joined.set(prefix); + joined[prefix.length] = 0x2f; + joined.set(name, prefix.length + 1); + name = joined; + } + } + const typeflag = String.fromCharCode(block[156]!); + return { + name, + linkname: cString(block, 157, 100), + mode: parseNumeric(block.subarray(100, 108), "mode"), + size: parseNumeric(block.subarray(124, 136), "size"), + typeflag, + gnuExtended: gnu && typeflag === "S" && block[482] !== 0, + }; +} + +const utf8 = new TextDecoder("utf-8"); + +export interface PaxRecords { + records: Record; + /** Raw bytes of the `path` record, which may not be valid UTF-8. */ + rawPath?: Uint8Array; +} + +/** Parses PAX records " =\n" like Go's parsePAX; later records win. */ +export function parsePax(data: Uint8Array): PaxRecords { + const records: Record = {}; + let rawPath: Uint8Array | undefined; + let pos = 0; + while (pos < data.length) { + const space = data.indexOf(0x20, pos); + const lenText = space < 0 ? "" : latin.decode(data.subarray(pos, space)); + if (!/^[1-9][0-9]*$/.test(lenText)) throw readFailed("invalid PAX record length"); + const end = pos + Number(lenText); + if (end > data.length || end <= space + 1 || data[end - 1] !== 0x0a) throw readFailed("invalid PAX record"); + const body = data.subarray(space + 1, end - 1); + const eq = body.indexOf(0x3d); + if (eq <= 0) throw readFailed("invalid PAX record key"); + const key = utf8.decode(body.subarray(0, eq)); + const value = utf8.decode(body.subarray(eq + 1)); + const nulInValue = ["path", "linkpath", "uname", "gname"].includes(key) && value.includes("\0"); + if (key.includes("\0") || nulInValue) throw readFailed(`invalid PAX record ${JSON.stringify(key)}`); + records[key] = value; + if (key === "path") rawPath = body.subarray(eq + 1); + pos = end; + } + return rawPath === undefined ? { records } : { records, rawPath }; +} + +const DECIMAL_RECORDS = ["size", "uid", "gid"]; +const TIME_RECORDS = ["atime", "mtime", "ctime"]; + +/** Rejects records Go's mergePAX cannot parse. */ +export function checkPaxValues(records: Readonly>): void { + for (const [key, value] of Object.entries(records)) { + if (DECIMAL_RECORDS.includes(key) && !(/^[0-9]+$/.test(value) && Number.isSafeInteger(Number(value)))) { + throw readFailed(`invalid PAX ${key}`); + } + if (TIME_RECORDS.includes(key) && !/^-?[0-9]+(\.[0-9]+)?$/.test(value)) throw readFailed(`invalid PAX ${key}`); + } +} + +/** Header-only types carry no data regardless of their size field (Go isHeaderOnlyType). */ +export function isHeaderOnly(typeflag: string): boolean { + return ["1", "2", "3", "4", "5", "6"].includes(typeflag); +} + +export function blockPadding(size: number): number { + return (BLOCK - (size % BLOCK)) % BLOCK; +} diff --git a/packages/skill-tree/src/tar-reader.ts b/packages/skill-tree/src/tar-reader.ts new file mode 100644 index 0000000..eca49f6 --- /dev/null +++ b/packages/skill-tree/src/tar-reader.ts @@ -0,0 +1,159 @@ +/** + * Streaming tar (and tar.gz) reader for `agentkit.skill-tree/v1`. An entry is + * a header as Go archive/tar Reader.Next returns it: PAX `x` and GNU `L`/`K` + * headers fold into the following entry, a PAX `g` header is a metadata + * entry. Content is hashed while it streams; nothing is extracted. + */ +import { StreamReader, asTreeError, decompress, readFailed, toAsyncIterable } from "./byte-source"; +import type { ByteSource } from "./byte-source"; +import { EntryCollector, decodeName } from "./entry-collector"; +import type { TreeManifest } from "./serialize"; +import { + BLOCK, + MAX_SPECIAL_FILE_SIZE, + blockPadding, + checkPaxValues, + isHeaderOnly, + isZeroBlock, + parseHeader, + parsePax, +} from "./tar-header"; +import type { PaxRecords } from "./tar-header"; +import { LIMITS, headerMode } from "./tree"; +import type { EntryKind, TreeLimits } from "./tree"; + +export interface TarReadOptions { + /** "auto" (default) detects the gzip magic bytes. */ + compression?: "auto" | "gzip" | "none"; + /** Test hook: smaller limits. */ + limits?: TreeLimits; +} + +/** Maps a tar type flag to an entry kind; type NUL is a directory when its name ends with "/". */ +export function tarEntryKind(typeflag: string, name: string): EntryKind { + switch (typeflag) { + case "0": + return "regular"; + case "\0": + return name.endsWith("/") ? "directory" : "regular"; + case "5": + return "directory"; + case "g": + return "metadata"; + case "2": + return "symlink"; + case "1": + return "hardlink"; + default: + return "special"; + } +} + +async function gunzipIfNeeded(source: AsyncIterable, compression: string): Promise> { + if (compression === "none") return source; + const it = source[Symbol.asyncIterator](); + const head: Uint8Array[] = []; + let seen = 0; + while (seen < 2) { + const next = await it.next(); + if (next.done) break; + head.push(next.value); + seen += next.value.length; + } + const magic = head.flatMap((chunk) => Array.from(chunk.subarray(0, 2))).slice(0, 2); + const gzip = compression === "gzip" || (magic[0] === 0x1f && magic[1] === 0x8b); + const replay = (async function* () { + yield* head; + for (let next = await it.next(); !next.done; next = await it.next()) yield next.value; + })(); + if (!gzip) return replay; + return decompress(replay, "gzip"); +} + +function nulTerminated(data: Uint8Array): Uint8Array { + const nul = data.indexOf(0); + return nul < 0 ? data : data.subarray(0, nul); +} + +async function readSpecial(reader: StreamReader, size: number): Promise { + if (size > MAX_SPECIAL_FILE_SIZE) throw readFailed(`tar extension header of ${size} bytes is too large`); + const data = (await reader.readExact(size)) ?? new Uint8Array(0); + if (data.length !== size) throw readFailed("truncated tar extension header"); + await reader.skip(blockPadding(size)); + return data; +} + +async function readEntries(reader: StreamReader, collector: EntryCollector): Promise { + let pax: PaxRecords | undefined; + let longName: Uint8Array | undefined; + for (;;) { + const block = await reader.readExact(BLOCK); + if (block === null) return; + if (isZeroBlock(block)) { + const second = await reader.readExact(BLOCK); + if (second === null || isZeroBlock(second)) return; + throw readFailed("tar header follows a single zero block"); + } + const h = parseHeader(block); + if (h.typeflag === "x") { + pax = parsePax(await readSpecial(reader, h.size)); + continue; + } + if (h.typeflag === "L" || h.typeflag === "K") { + const value = nulTerminated(await readSpecial(reader, h.size)); + if (h.typeflag === "L" && value.length > 0) longName = value; + continue; + } + collector.present(); + if (h.typeflag === "g") { + // Global records describe the archive; pending x and L headers are dropped, as in Go. + const global = parsePax(await readSpecial(reader, h.size)); + checkPaxValues(global.records); + const name = decodeName(global.rawPath ?? h.name); + collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: "", size: 0, sha256: "", kind: "metadata", paxRecords: global.records }); + pax = undefined; + longName = undefined; + continue; + } + const records = pax?.records ?? {}; + checkPaxValues(records); + const name = decodeName(longName ?? pax?.rawPath ?? h.name); + const declared = records.size !== undefined ? Number(records.size) : h.size; + const dataSize = isHeaderOnly(h.typeflag) ? 0 : declared; + const kind = tarEntryKind(h.typeflag, name.path); + if (h.gnuExtended) { + // Old GNU sparse headers chain extension blocks before the data. + for (let ext = await reader.readExact(BLOCK); ; ext = await reader.readExact(BLOCK)) { + if (ext === null) throw readFailed("truncated GNU sparse header"); + if (ext[504] === 0) break; + } + } + let size = 0; + let sha256 = ""; + if (kind === "regular") ({ size, sha256 } = await collector.hashFile(name.path, reader.chunks(dataSize))); + else await reader.skip(dataSize); + await reader.skip(blockPadding(dataSize)); + collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: headerMode(h.mode), size, sha256, kind, paxRecords: records }); + pax = undefined; + longName = undefined; + } +} + +/** + * Reads a tar or tar.gz stream into a validated tree manifest. Throws a + * `SkillTreeError`; malformed archives fail with `tree.read_failed` and + * limits stop reading as soon as they are exceeded. + */ +export async function readTarTree(source: ByteSource, options: TarReadOptions = {}): Promise { + const collector = new EntryCollector(options.limits ?? LIMITS); + let reader: StreamReader | undefined; + try { + reader = new StreamReader(await gunzipIfNeeded(toAsyncIterable(source), options.compression ?? "auto")); + await readEntries(reader, collector); + } catch (err) { + throw asTreeError(err); + } finally { + await reader?.close().catch(() => undefined); + } + return collector.build(); +} diff --git a/packages/skill-tree/src/tree.ts b/packages/skill-tree/src/tree.ts new file mode 100644 index 0000000..961e171 --- /dev/null +++ b/packages/skill-tree/src/tree.ts @@ -0,0 +1,170 @@ +/** + * Validation and build of `agentkit.skill-tree/v1` from the entries an input + * presents (contract 4.1-4.7). Readers hand every entry over, of any kind + * and noise included; `buildTree` applies the validation steps in contract + * order, so every implementation reports the same first code. + */ +import { checkCollisions, checkFileDirs } from "./collision"; +import { ERROR_CODES, SkillTreeError, treeError } from "./errors"; +import { checkNfc, checkPathRules, isNoiseDirName, isNoiseFileName } from "./path-rules"; +import { + MODE_EXECUTABLE, + MODE_REGULAR, + MODE_SOURCE_RECORDED, + TREE_SCHEMA, + sortFiles, + treeDigest, +} from "./serialize"; +import type { FileMode, ModeSource, TreeFile, TreeManifest } from "./serialize"; + +/** Exact contract limits; changing one is a contract version change. */ +export const LIMITS = { + maxEntries: 10_000, + maxFiles: 4_096, + maxFileSize: 32 * 1024 * 1024, + maxTreeSize: 256 * 1024 * 1024, +} as const; +export type TreeLimits = { maxEntries: number; maxFiles: number; maxFileSize: number; maxTreeSize: number }; + +/** + * Entry kinds. `directory` and `metadata` (a PAX global header) add no file + * but count toward the entry limit; every kind except `regular`, `directory` + * and `metadata` fails with `tree.unsupported_entry`. + */ +export type EntryKind = "regular" | "symlink" | "hardlink" | "special" | "directory" | "metadata"; + +/** One presented entry. `mode` is a mode class or the raw octal form of a rejected header mode. */ +export interface TreeEntry { + path: string; + /** False when the raw name bytes were not valid UTF-8 and `path` is a lossy decoding. */ + utf8Valid?: boolean; + mode: string; + size: number; + sha256: string; + kind?: EntryKind; + paxRecords?: Readonly>; + /** Explains why a non-regular or malformed entry is unsupported. */ + reason?: string; +} + +const kindOf = (e: TreeEntry): EntryKind => e.kind ?? "regular"; + +/** Tree path of an entry: a directory entry's one trailing "/" is not part of it. */ +function entryPath(e: TreeEntry): string { + return kindOf(e) === "directory" && e.path.endsWith("/") ? e.path.slice(0, -1) : e.path; +} + +function isNoiseEntry(e: TreeEntry): boolean { + const p = entryPath(e); + const slash = p.lastIndexOf("/"); + const name = p.slice(slash + 1); + if (slash >= 0 && p.slice(0, slash).split("/").some(isNoiseDirName)) return true; + switch (kindOf(e)) { + case "directory": + return isNoiseDirName(name); + case "symlink": + return isNoiseDirName(name) || isNoiseFileName(name); + default: + return isNoiseFileName(name); + } +} + +/** Maps a tar or zip header mode to its class; any other mode keeps its octal form and is rejected. */ +export function headerMode(mode: number): string { + const perm = mode & ~0o170000; + if (perm === 0o644) return MODE_REGULAR; + if (perm === 0o755) return MODE_EXECUTABLE; + return `0${mode.toString(8)}`; +} + +function isSparseRecord(key: string): boolean { + return key.startsWith("GNU.sparse."); +} + +const GLOBAL_ONLY_RECORDS = new Set(["path", "linkpath", "size"]); + +function validateEntry(e: TreeEntry): SkillTreeError | null { + const kind = kindOf(e); + const records = Object.keys(e.paxRecords ?? {}).sort(); + const unsupported = (detail: string) => treeError(ERROR_CODES.unsupportedEntry, e.path, detail); + if (kind === "directory") return null; + if (kind === "metadata") { + const key = records.find((k) => GLOBAL_ONLY_RECORDS.has(k) || isSparseRecord(k)); + return key === undefined ? null : unsupported(`PAX global header carries record ${JSON.stringify(key)}`); + } + if (kind !== "regular") return unsupported(e.reason ?? `entry is not a regular file (${kind})`); + if (e.reason !== undefined) return unsupported(e.reason); + const sparse = records.find(isSparseRecord); + if (sparse !== undefined) return unsupported(`PAX record ${JSON.stringify(sparse)} marks a sparse file`); + if (e.mode !== MODE_REGULAR && e.mode !== MODE_EXECUTABLE) return unsupported(`mode ${JSON.stringify(e.mode)} is not a regular file mode`); + if (!Number.isSafeInteger(e.size) || e.size < 0) return unsupported(`size ${e.size} is not a non-negative integer`); + if (!/^[0-9a-f]{64}$/.test(e.sha256)) return unsupported("sha256 is not 64 lowercase hex characters"); + return null; +} + +/** File count and byte limits over every presented regular-file entry, noise included. */ +export function checkLimits(entries: readonly TreeEntry[], listed: number, limits: TreeLimits): SkillTreeError | null { + if (listed > limits.maxEntries) { + return treeError(ERROR_CODES.limitExceeded, "", `tree has ${listed} entries, more than ${limits.maxEntries}`); + } + let count = 0; + let total = 0; + for (const e of entries) { + if (kindOf(e) !== "regular") continue; + if (++count > limits.maxFiles) return treeError(ERROR_CODES.limitExceeded, e.path, `tree has more than ${limits.maxFiles} files`); + const size = Math.max(e.size, 0); + if (size > limits.maxFileSize) return treeError(ERROR_CODES.limitExceeded, e.path, `file exceeds ${limits.maxFileSize} bytes`); + if ((total += size) > limits.maxTreeSize) return treeError(ERROR_CODES.limitExceeded, e.path, `tree exceeds ${limits.maxTreeSize} bytes`); + } + return null; +} + +function firstError(items: readonly T[], check: (item: T) => SkillTreeError | null): SkillTreeError | null { + for (const item of items) { + const err = check(item); + if (err !== null) return err; + } + return null; +} + +export interface BuildOptions { + /** Total entries the input presented, when it passes on fewer than it listed. */ + listed?: number; + modeSource?: ModeSource; + /** Test hook: smaller limits. Public readers always use the contract limits. */ + limits?: TreeLimits; +} + +/** + * Validates every presented entry and returns the sorted manifest with its + * digest. Throws a `SkillTreeError` with the code of the first failing step. + */ +export function buildTree(entries: readonly TreeEntry[], options: BuildOptions = {}): TreeManifest { + const limits = options.limits ?? LIMITS; + const limitError = checkLimits(entries, options.listed ?? entries.length, limits); + if (limitError !== null) throw limitError; + // A PAX global header's name is metadata: never noise, never path-checked. + const named = entries.filter((e) => kindOf(e) === "metadata" || !isNoiseEntry(e)); + const files = named.filter((e) => kindOf(e) !== "directory" && kindOf(e) !== "metadata"); + const dirs = named.filter((e) => kindOf(e) === "directory").map(entryPath); + const filePaths = files.map((e) => e.path); + const stages: Array<() => SkillTreeError | null> = [ + () => firstError(named, validateEntry), + () => firstError(named, (e) => (kindOf(e) === "metadata" ? null : checkPathRules(entryPath(e), e.utf8Valid ?? true))), + () => firstError(filePaths, checkNfc), + () => (files.length === 0 ? treeError(ERROR_CODES.empty, "", "tree contains no files") : null), + () => checkFileDirs(filePaths, dirs), + () => checkCollisions(filePaths, dirs), + ]; + const failure = firstError(stages, (stage) => stage()); + if (failure !== null) throw failure; + const treeFiles: TreeFile[] = sortFiles( + files.map((e) => ({ path: e.path, mode: e.mode as FileMode, size: e.size, sha256: e.sha256 })), + ); + return { + schema: TREE_SCHEMA, + digest: treeDigest(treeFiles), + modeSource: options.modeSource ?? MODE_SOURCE_RECORDED, + files: treeFiles, + }; +} diff --git a/packages/skill-tree/src/unicode-15-tables.ts b/packages/skill-tree/src/unicode-15-tables.ts new file mode 100644 index 0000000..7936df5 --- /dev/null +++ b/packages/skill-tree/src/unicode-15-tables.ts @@ -0,0 +1,14 @@ +// Code generated by scripts/gen-unicode-tables.mjs. DO NOT EDIT. +// Unicode 15.0.0. Inputs: +// fixtures/ucd/CaseFolding-15.0.0.txt sha256 cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7 +// scripts/unicode-15.0.0-go.json sha256 baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5 (go1.25.3, x/text norm 15.0.0) +// Encodings: ranges are "delta.length" base-36 items (delta from the previous +// range end); maps are "keyDelta:value.value"; lists are base-36 deltas. + +export const UNICODE_VERSION = "15.0.0"; +export const ASSIGNED_RANGES = "0.on,3.5,5.6,2.0,2.j,2.b0,2.11,3.1d,3.2,2.1i,9.q,5.5,c.7h,2.1n,3.2s,f.1m,3.1c,3.e,2.r,3.0,2.a,6.u,2.1,7.6j,2.7,3.1,3.l,2.6,2.0,4.3,3.8,3.1,3.3,9.0,5.1,2.4,3.o,3.2,2.5,5.1,3.l,2.6,2.1,2.1,2.1,3.0,2.4,5.1,3.2,4.0,8.3,2.0,8.g,b.2,2.8,2.2,2.l,2.6,2.1,2.4,3.9,2.2,2.2,3.0,g.3,3.b,8.6,2.2,2.7,3.1,3.l,2.6,2.1,2.4,3.8,3.1,3.2,8.2,5.1,2.4,3.h,b.1,2.5,4.2,2.3,4.1,2.0,2.1,4.1,4.2,4.b,5.4,4.2,2.3,3.0,7.0,f.k,6.c,2.2,2.m,2.f,3.8,2.2,2.3,8.1,2.2,3.0,3.3,3.9,8.l,2.2,2.m,2.9,2.4,3.8,2.2,2.3,8.1,7.1,2.3,3.9,2.2,d.c,2.2,2.1e,2.2,2.5,5.f,3.p,2.2,2.h,4.n,2.8,2.0,3.6,4.0,5.5,2.0,2.7,7.9,3.2,d.1l,5.s,12.1,2.0,2.4,2.n,2.0,2.m,3.4,2.0,2.6,2.9,3.3,x.1z,2.z,5.12,2.z,2.e,2.c,12.5h,2.0,6.0,3.ag,2.3,3.6,2.0,2.3,3.14,2.3,3.w,2.3,3.6,2.0,2.3,3.e,2.1k,2.3,3.1u,3.v,4.p,7.2d,3.5,3.ik,4.2g,8.l,a.n,a.j,d.c,2.2,2.1,d.2l,3.9,7.9,7.p,7.2g,8.16,6.1x,b.u,2.b,5.b,5.0,4.15,3.4,c.17,5.p,7.a,4.1p,3.1s,2.s,3.a,7.9,7.d,3.u,1e.24,4.1a,2.37,9.1n,4.e,4.1n,8.16,3.a,9.16,6.et,3.5,3.11,3.5,3.7,2.0,2.0,2.0,2.u,3.1g,2.e,2.d,3.5,2.i,3.2,2.8,2.2s,2.b,3.q,2.c,4.w,g.w,g.3v,5.ie,q.a,m.1eb,3.v,2.9o,6.18,2.0,6.0,3.1j,8.1,f.n,a.6,2.6,2.6,2.6,2.6,2.6,2.6,2.6,2.3h,z.p,2.2g,d.5x,r.b,5.1r,2.2d,3.2u,6.16,2.2l,2.2b,d.1a,2.mlo,4.1i,a.9n,l.53,9.5m,6.1,2.0,2.4,p.1m,4.9,7.1j,9.1x,9.b,7.37,c.t,4.25,2.a,5.w,2.1i,a.d,3.9,3.2u,p.r,b.5,3.5,3.5,a.6,2.6,2.1n,5.3h,3.9,7.8mb,d.m,5.1c,5.6st,3.2x,13.6,d.4,6.p,2.4,2.0,2.1,2.1,2.3g,h.cc,3.1h,8.0,x.15,7.1e,2.i,2.3,5.4,2.3q,3.0,2.59,4.5,3.5,3.5,3.2,4.6,2.6,b.4,3.b,2.p,2.i,2.1,2.e,3.d,z.3e,6.2,5.18,4.2f,2.c,4.0,1c.19,3n.s,4.1c,g.r,5.z,a.t,6.16,6.t,2.10,5.d,17.4d,3.9,7.z,5.z,5.13,9.1f,c.b,2.e,2.6,2.1,2.a,2.e,2.6,2.1,1w.8m,a.l,b.7,p.5,2.15,2.8,1y.5,3.0,2.17,2.1,4.0,3.m,2.1z,9.8,1d.i,2.1,6.w,4.q,6.0,1t.1j,5.j,3.1d,2.1,6.7,2.2,2.s,3.2,5.9,8.8,8.1r,x.12,5.b,a.1h,4.s,3.q,6.p,8.3,d.6,29.20,1k.1e,e.1e,8.19,9.9,87.u,2.15,2.2,3.1,24.16,9.15,n.p,13.r,l.m,a.25,5.z,a.1v,b.0,3.o,8.9,7.1g,2.h,9.12,a.2n,2.j,c.h,2.1a,1r.6,2.0,2.3,2.e,2.a,7.1m,6.9,7.3,2.7,3.1,3.l,2.6,2.1,2.4,2.9,3.1,3.2,3.0,7.0,6.6,3.6,4.4,3w.2j,2.4,v.1z,9.9,4n.1h,3.11,z.1w,c.9,7.c,k.1l,7.9,1j.q,3.e,5.m,56.1n,2t.2a,d.7,3.0,3.7,2.1,2.t,2.1,3.b,a.9,1z.7,3.19,3.a,s.1z,9.2a,e.20,8.9,6v.8,2.18,2.d,b.s,4.v,3.l,2.d,22.6,2.1,2.17,4.0,2.1,2.8,9.9,7.5,2.1,2.10,2.1,2.5,8.9,8n.o,8.g,2.14,4.r,2f.0,g.1d,e.pm,2v.32,2.4,c.5f,219.2q,e.ut,33f.g6,6nu.fs,8.u,2.9,5.28,2.9,7.t,3.5,b.1x,b.9,2.6,2.k,6.i,j5.2i,2u.22,5.1k,8.g,1t.4,c.1,f.4qf,9.yd,17.8,6w8.3,2.6,2.1,2.82,g.0,u.2,3.0,f.3,9.az,1s5.2y,6.c,4.8,8.9,3.7,3ml.19,3.m,a.37,1p.6t,b.12,3.5d,m.1x,3f.j,d.j,d.2e,a.o,3s.2c,2.1y,2.1,3.0,3.1,3.3,2.b,2.0,2.6,2.1s,2.3,3.7,2.6,2.r,2.3,2.4,2.0,4.6,2.9f,3.83,3.jh,g.4,2.e,up.u,7.5,5y.6,2.g,3.6,2.1,2.4,6.1p,y.0,35.18,4.d,3.9,5.1,8x.u,i.1l,6.0,cx.15,kn.6,2.3,2.1,2.e,2.5g,3.f,16.23,5.9,5.1,lu.1v,25.1o,5f.3,2.q,2.1,2.0,3.0,2.9,2.3,2.0,2.0,7.0,5.0,2.0,2.0,2.2,2.1,2.0,3.0,2.0,2.0,2.0,2.0,2.1,2.0,3.3,2.6,2.3,2.3,2.0,2.9,2.g,6.2,2.4,2.g,1h.1,7j.17,5.2r,d.e,3.e,2.e,2.10,b.4t,1l.s,e.17,5.8,8.1,f.5,4b.rb,5.g,4.c,4.3a,5.2m,7.b,5.0,g.b,5.1j,9.9,7.13,9.t,3.1,27.9f,d.d,3.c,4.8,8.19,2.6,9.d,5.8,8.8,8.42,2.1i,12.9,sn.wyn,x.37d,7.65,3.4g1,f.5rk,2e8.f1,15v.3t6,6.38f,f976.0,v.2n,3l.6n,1e6p.1ekd,3.1ekd"; +export const FORMAT_RANGES = "4t.0,11v.5,n.0,5d.0,1e.0,ap.1,29.0,2zw.0,1kt.4,r.4,1e.4,2.9,17yo.0,6y.2,3b6.0,g.0,6zn.f,qxt.3,440.7,h407.0,v.2n"; +export const COMBINING_CLASSES = "lc.k.6e,1.0.6g,1.3.64,1.0.6g,1.0.60,1.4.64,1.1.5m,1.3.64,1.1.5m,1.a.64,1.4.1,1.3.64,1.7.6e,1.0.6o,1.0.6e,1.2.64,1.2.6e,1.1.64,2.2.6e,1.3.64,1.0.6e,1.0.6g,1.1.64,1.0.6e,1.0.6h,1.1.6i,1.0.6h,1.1.6i,1.0.6h,1.c.6e,7o.4.6e,7e.0.64,1.3.6e,1.0.64,1.2.6e,1.0.66,1.0.64,1.5.6e,1.5.64,1.1.6e,1.0.64,1.1.6e,1.0.66,1.0.6c,1.0.6e,1.0.a,1.0.b,1.0.c,1.0.d,1.0.e,1.0.f,1.0.g,1.0.h,1.0.i,1.1.j,1.0.k,1.0.l,1.0.m,2.0.n,2.0.o,1.0.p,2.0.6e,1.0.64,2.0.i,21.7.6e,1.0.u,1.0.v,1.0.w,1d.0.r,1.0.s,1.0.t,1.0.u,1.0.v,1.0.w,1.0.x,1.0.y,1.1.6e,1.1.64,1.4.6e,1.0.64,1.1.6e,1.0.64,h.0.z,2u.6.6e,3.3.6e,1.0.64,1.0.6e,3.1.6e,2.0.64,1.1.6e,1.0.64,10.0.10,v.0.6e,1.0.64,1.1.6e,1.0.64,1.1.6e,1.2.64,1.0.6e,1.1.64,1.0.6e,1.0.64,1.2.6e,1.0.64,1.0.6e,1.0.64,1.0.6e,1.0.64,1.0.6e,1.0.64,1.1.6e,4h.6.6e,1.0.64,1.0.6e,a.0.64,p.3.6e,2.8.6e,2.2.6e,2.4.6e,18.2.64,1p.0.6e,1.2.64,1.3.6e,17.4.6e,1.4.64,1.d.6e,2.0.64,1.1.6e,1.0.64,1.1.6e,1.0.64,1.2.6e,1.2.64,1.0.r,1.0.s,1.0.t,1.2.6e,1.0.64,1.1.6e,1.1.64,1.4.6e,1p.0.7,h.0.9,4.0.6e,1.0.64,1.1.6e,2w.0.7,h.0.9,1d.0.6e,1q.0.7,h.0.9,33.0.7,h.0.9,33.0.7,h.0.9,3k.0.9,33.0.7,h.0.9,8.0.2c,1.0.2j,2u.0.7,h.0.9,32.1.9,h.0.9,3h.0.9,32.1.2v,1.0.9,e.3.2z,31.1.3a,1.0.9,e.3.3e,25.1.64,s.0.64,2.0.64,2.0.60,1k.0.3l,1.0.3m,2.0.3o,6.3.3m,3.0.3m,2.1.6e,1.0.9,2.1.6e,1r.0.64,35.0.7,2.1.9,2b.0.64,k0.2.6e,qd.1.9,v.0.9,4e.0.9,b.0.6e,5o.0.6c,40.0.66,1.0.6e,1.0.64,64.0.6e,1.0.64,20.0.9,l.7.6e,3.0.64,1d.4.6e,1.5.64,1.1.6e,1.0.64,2.1.64,1.1.6e,1.1.64,1.4.6e,1.0.64,1.3.6e,2u.0.7,g.0.9,13.0.6e,1.0.64,1.6.6e,1j.1.9,1n.0.7,c.1.9,1w.0.7,49.2.6e,2.0.1,1.4.64,1.1.6e,1.3.64,1.0.6e,2.6.1,5.0.64,7.0.6e,4.1.6e,5j.1.6e,1.0.64,1.6.6e,1.0.64,1.1.6e,1.0.6i,1.0.5y,1.0.64,1.0.5m,1.10.6e,1.0.6g,1.1.6c,1.0.64,1.0.62,1.0.6e,1.0.6h,1.0.64,1.0.6e,1.0.64,k1.1.6e,1.1.1,1.3.6e,1.2.1,1.1.6e,5.0.6e,4.1.1,1.0.6e,1.0.64,1.0.6e,1.1.1,1.3.64,1.0.6e,2db.2.6e,3y.0.9,2p.v.6e,ff.0.62,1.0.6c,1.0.6g,1.0.66,1.1.68,2y.1.8,n9x.0.6e,5.9.6e,x.1.6e,29.1.6e,7p.0.9,12.0.9,48.0.9,s.h.6e,1m.2.64,12.0.9,2o.0.7,d.0.9,6o.0.6e,2.1.6e,1.0.64,3.1.6e,6.1.6e,2.0.6e,1h.0.9,6v.0.9,fn5.0.q,le.6.6e,1.6.64,1.1.6e,r2.0.64,6b.0.64,46.4.6e,1ar.0.64,2.0.6e,15.0.6e,1.0.1,1.0.64,5.0.9,4m.0.6e,1.0.64,fy.3.6e,as.1.6e,29.2.64,1z.1.64,1.2.6e,1.0.64,1.0.6e,1.3.64,1e.0.6e,1.0.64,1.0.6e,1.0.64,5d.0.9,16.0.9,f.0.9,1m.0.9,1.0.7,1y.2.6e,1d.1.9,1r.0.7,25.0.9,a.0.7,2z.0.9,1.0.7,4z.0.7,1.0.9,29.1.7,h.0.9,p.6.6e,4.4.6e,5q.0.9,4.0.7,o.0.6e,2s.0.9,1.0.7,70.0.9,1.0.7,3j.0.9,3b.0.9,1.0.7,38.0.9,7i.0.9,1.0.7,77.1.9,5.0.7,4d.0.9,2c.0.9,j.0.9,2a.0.9,bq.0.9,77.0.7,2.1.9,2a.0.9,bu.1.9,ey6.4.1,1o.6.6e,xm.1.6,f59.0.1,43r.1.60,1.2.1,4.0.6a,1.4.60,9.7.64,3.4.6e,1.1.64,v.3.6e,45.2.6e,2po.6.6e,2.g.6e,3.6.6e,2.1.6e,2.4.6e,2t.0.6e,4h.6.6e,ag.0.6e,1q.3.6e,e5.1.6g,1.0.64,1.0.6e,rl.6.64,32.5.6e,1.0.7"; +export const CANONICAL_DECOMPOSITIONS = "5c:1t.lc,1:1t.ld,1:1t.le,1:1t.lf,1:1t.lk,1:1t.lm,2:1v.mf,1:1x.lc,1:1x.ld,1:1x.le,1:1x.lk,1:21.lc,1:21.ld,1:21.le,1:21.lk,2:26.lf,1:27.lc,1:27.ld,1:27.le,1:27.lf,1:27.lk,3:2d.lc,1:2d.ld,1:2d.le,1:2d.lk,1:2h.ld,3:2p.lc,1:2p.ld,1:2p.le,1:2p.lf,1:2p.lk,1:2p.lm,2:2r.mf,1:2t.lc,1:2t.ld,1:2t.le,1:2t.lk,1:2x.lc,1:2x.ld,1:2x.le,1:2x.lk,2:32.lf,1:33.lc,1:33.ld,1:33.le,1:33.lf,1:33.lk,3:39.lc,1:39.ld,1:39.le,1:39.lk,1:3d.ld,2:3d.lk,1:1t.lg,1:2p.lg,1:1t.li,1:2p.li,1:1t.mg,1:2p.mg,1:1v.ld,1:2r.ld,1:1v.le,1:2r.le,1:1v.lj,1:2r.lj,1:1v.lo,1:2r.lo,1:1w.lo,1:2s.lo,3:1x.lg,1:2t.lg,1:1x.li,1:2t.li,1:1x.lj,1:2t.lj,1:1x.mg,1:2t.mg,1:1x.lo,1:2t.lo,1:1z.le,1:2v.le,1:1z.li,1:2v.li,1:1z.lj,1:2v.lj,1:1z.mf,1:2v.mf,1:20.le,1:2w.le,3:21.lf,1:2x.lf,1:21.lg,1:2x.lg,1:21.li,1:2x.li,1:21.mg,1:2x.mg,1:21.lj,4:22.le,1:2y.le,1:23.mf,1:2z.mf,2:24.ld,1:30.ld,1:24.mf,1:30.mf,1:24.lo,1:30.lo,5:26.ld,1:32.ld,1:26.mf,1:32.mf,1:26.lo,1:32.lo,4:27.lg,1:33.lg,1:27.li,1:33.li,1:27.ln,1:33.ln,3:2a.ld,1:36.ld,1:2a.mf,1:36.mf,1:2a.lo,1:36.lo,1:2b.ld,1:37.ld,1:2b.le,1:37.le,1:2b.mf,1:37.mf,1:2b.lo,1:37.lo,1:2c.mf,1:38.mf,1:2c.lo,1:38.lo,3:2d.lf,1:39.lf,1:2d.lg,1:39.lg,1:2d.li,1:39.li,1:2d.lm,1:39.lm,1:2d.ln,1:39.ln,1:2d.mg,1:39.mg,1:2f.le,1:3b.le,1:2h.le,1:3d.le,1:2h.lk,1:2i.ld,1:3e.ld,1:2i.lj,1:3e.lj,1:2i.lo,1:3e.lo,y:27.m3,1:33.m3,e:2d.m3,1:39.m3,t:1t.lo,1:2p.lo,1:21.lo,1:2x.lo,1:27.lo,1:33.lo,1:2d.lo,1:39.lo,1:64.lg,1:70.lg,1:64.ld,1:70.ld,1:64.lo,1:70.lo,1:64.lc,1:70.lc,2:5g.lg,1:6c.lg,1:fa.lg,1:fb.lg,1:5i.lg,1:6e.lg,3:1z.lo,1:2v.lo,1:23.lo,1:2z.lo,1:27.mg,1:33.mg,1:dm.lg,1:dn.lg,1:c7.lo,1:ia.lo,1:2y.lo,4:1z.ld,1:2v.ld,3:26.lc,1:32.lc,1:5h.ld,1:6d.ld,1:5i.ld,1:6e.ld,1:60.ld,1:6w.ld,1:1t.lr,1:2p.lr,1:1t.lt,1:2p.lt,1:1x.lr,1:2t.lr,1:1x.lt,1:2t.lt,1:21.lr,1:2x.lr,1:21.lt,1:2x.lt,1:27.lr,1:33.lr,1:27.lt,1:33.lt,1:2a.lr,1:36.lr,1:2a.lt,1:36.lt,1:2d.lr,1:39.lr,1:2d.lt,1:39.lt,1:2b.me,1:37.me,1:2c.me,1:38.me,3:20.lo,1:2w.lo,7:1t.lj,1:2p.lj,1:1x.mf,1:2t.mf,1:5y.lg,1:6u.lg,1:5x.lg,1:6t.lg,1:27.lj,1:33.lj,1:fi.lg,1:fj.lg,1:2h.lg,1:3d.lg,7h:lc,1:ld,2:lv,1:lk.ld,1c:jd,a:1n,7:4o.ld,1:pd.ld,1:53,1:ph.ld,1:pj.ld,1:pl.ld,2:pr.ld,2:px.ld,1:q1.ld,1:qy.ld,q:pl.lk,1:px.lk,1:q9.ld,1:qd.ld,1:qf.ld,1:qh.ld,1:qz.ld,q:qh.lk,1:qt.lk,1:qn.ld,1:qt.ld,1:qx.ld,5:r6.ld,1:r6.lk,18:t1.lc,1:t1.lk,2:sz.ld,4:sm.lk,5:t6.ld,1:t4.lc,1:tf.li,b:t4.li,w:u0.li,n:tx.lc,1:tx.lk,2:tv.ld,4:uu.lk,5:u2.ld,1:u0.lc,1:ub.li,o:vo.lr,1:vp.lr,22:t2.li,1:ty.li,e:sw.li,1:ts.li,1:sw.lk,1:ts.lk,3:t1.li,1:tx.li,3:yg.lk,1:yh.lk,1:t2.lk,1:ty.lk,1:t3.lk,1:tz.lk,3:t4.lg,1:u0.lg,1:t4.lk,1:u0.lk,1:ta.lk,1:u6.lk,3:yw.lk,1:yx.lk,1:tp.lk,1:ul.lk,1:tf.lg,1:ub.lg,1:tf.lk,1:ub.lk,1:tf.ln,1:ub.ln,1:tj.lk,1:uf.lk,3:tn.lk,1:uj.lk,89:17r.18z,1:17r.190,1:18o.190,1:17r.191,1:18q.190,4a:1cl.190,2:1c1.190,h:1ci.190,gm:1t4.1to,8:1tc.1to,3:1tf.1to,10:1sl.1to,1:1sm.1to,1:1sn.1to,1:1ss.1to,1:1sx.1to,1:1sy.1to,1:1t7.1to,1:1tb.1to,30:1xj.1xa,1:1xj.1xz,g:1wh.1x8,1:1wi.1x8,2:1wv.1x8,2c:20i.20s,3:20o.20s,z:1zq.20s,1:1zr.20s,1:1zw.20s,3:20b.20s,6i:287.28m,3:287.27y,1:287.28n,g:275.27w,1:276.27w,1j:2aa.2c7,1i:2bq.2bi,1:2br.2bi,1:2bq.2c7,3g:2fa.2fq,3c:2in.2j9,7:2iu.2j9,1:2iu.2ja,2:2iu.2iq,1:2iy.2j9,3j:2me.2m6,1:2mf.2m6,1:2me.2mv,3y:2qh.2q2,2:2qh.2q7,1:2qk.2q2,1:2qh.2qn,9x:30i.33r,a:30s.33r,5:30x.33r,5:312.33r,5:317.33r,d:30g.33p,a:31t.31u,2:31t.31w,1:33m.328,2:33n.328,9:31t.328,i:32q.33r,a:330.33r,5:335.33r,5:33a.33r,5:33f.33r,d:32o.33p,31:36t.372,25c:5c5.5dh,2:5c7.5dh,2:5c9.5dh,2:5cb.5dh,2:5cd.5dh,4:5ch.5dh,15:5dm.5dh,2:5do.5dh,3:5dq.5dh,1:5dr.5dh,2:5du.5dh,jh:1t.md,1:2p.md,1:1u.lj,1:2q.lj,1:1u.mb,1:2q.mb,1:1u.mp,1:2q.mp,1:5j.ld,1:6f.ld,1:1w.lj,1:2s.lj,1:1w.mb,1:2s.mb,1:1w.mp,1:2s.mp,1:1w.mf,1:2s.mf,1:1w.ml,1:2s.ml,1:7m.lc,1:7n.lc,1:7m.ld,1:7n.ld,1:1x.ml,1:2t.ml,1:1x.mo,1:2t.mo,1:fc.li,1:fd.li,1:1y.lj,1:2u.lj,1:1z.lg,1:2v.lg,1:20.lj,1:2w.lj,1:20.mb,1:2w.mb,1:20.lk,1:2w.lk,1:20.mf,1:2w.mf,1:20.mm,1:2w.mm,1:21.mo,1:2x.mo,1:5r.ld,1:6n.ld,1:23.ld,1:2z.ld,1:23.mb,1:2z.mb,1:23.mp,1:2z.mp,1:24.mb,1:30.mb,1:5yu.lg,1:5yv.lg,1:24.mp,1:30.mp,1:24.ml,1:30.ml,1:25.ld,1:31.ld,1:25.lj,1:31.lj,1:25.mb,1:31.mb,1:26.lj,1:32.lj,1:26.mb,1:32.mb,1:26.mp,1:32.mp,1:26.ml,1:32.ml,1:5x.ld,1:6t.ld,1:5x.lk,1:6t.lk,1:98.lc,1:99.lc,1:98.ld,1:99.ld,1:28.ld,1:34.ld,1:28.lj,1:34.lj,1:2a.lj,1:36.lj,1:2a.mb,1:36.mb,1:5zu.lg,1:5zv.lg,1:2a.mp,1:36.mp,1:2b.lj,1:37.lj,1:2b.mb,1:37.mb,1:9m.lj,1:9n.lj,1:9s.lj,1:9t.lj,1:602.lj,1:603.lj,1:2c.lj,1:38.lj,1:2c.mb,1:38.mb,1:2c.mp,1:38.mp,1:2c.ml,1:38.ml,1:2d.mc,1:39.mc,1:2d.mo,1:39.mo,1:2d.ml,1:39.ml,1:a0.ld,1:a1.ld,1:a2.lk,1:a3.lk,1:2e.lf,1:3a.lf,1:2e.mb,1:3a.mb,1:2f.lc,1:3b.lc,1:2f.ld,1:3b.ld,1:2f.lk,1:3b.lk,1:2f.lj,1:3b.lj,1:2f.mb,1:3b.mb,1:2g.lj,1:3c.lj,1:2g.lk,1:3c.lk,1:2h.lj,1:3d.lj,1:2i.le,1:3e.le,1:2i.mb,1:3e.mb,1:2i.mp,1:3e.mp,1:2w.mp,1:38.lk,1:3b.lm,1:3d.lm,2:an.lj,5:1t.mb,1:2p.mb,1:1t.ll,1:2p.ll,1:5e.ld,1:6a.ld,1:5e.lc,1:6a.lc,1:5e.ll,1:6a.ll,1:5e.lf,1:6a.lf,1:61s.le,1:61t.le,1:76.ld,1:77.ld,1:76.lc,1:77.lc,1:76.ll,1:77.ll,1:76.lf,1:77.lf,1:61s.li,1:61t.li,1:1x.mb,1:2t.mb,1:1x.ll,1:2t.ll,1:1x.lf,1:2t.lf,1:5m.ld,1:6i.ld,1:5m.lc,1:6i.lc,1:5m.ll,1:6i.ll,1:5m.lf,1:6i.lf,1:62g.le,1:62h.le,1:21.ll,1:2x.ll,1:21.mb,1:2x.mb,1:27.mb,1:33.mb,1:27.ll,1:33.ll,1:5w.ld,1:6s.ld,1:5w.lc,1:6s.lc,1:5w.ll,1:6s.ll,1:5w.lf,1:6s.lf,1:630.le,1:631.le,1:bk.ld,1:bl.ld,1:bk.lc,1:bl.lc,1:bk.ll,1:bl.ll,1:bk.lf,1:bl.lf,1:bk.mb,1:bl.mb,1:2d.mb,1:39.mb,1:2d.ll,1:39.ll,1:bz.ld,1:c0.ld,1:bz.lc,1:c0.lc,1:bz.ll,1:c0.ll,1:bz.lf,1:c0.lf,1:bz.mb,1:c0.mb,1:2h.lc,1:3d.lc,1:2h.mb,1:3d.mb,1:2h.ll,1:3d.ll,1:2h.lf,1:3d.lf,7:q9.lv,1:q9.lw,1:64g.lc,1:64h.lc,1:64g.ld,1:64h.ld,1:64g.n6,1:64h.n6,1:pd.lv,1:pd.lw,1:64o.lc,1:64p.lc,1:64o.ld,1:64p.ld,1:64o.n6,1:64p.n6,1:qd.lv,1:qd.lw,1:64w.lc,1:64x.lc,1:64w.ld,1:64x.ld,3:ph.lv,1:ph.lw,1:654.lc,1:655.lc,1:654.ld,1:655.ld,3:qf.lv,1:qf.lw,1:65c.lc,1:65d.lc,1:65c.ld,1:65d.ld,1:65c.n6,1:65d.n6,1:pj.lv,1:pj.lw,1:65k.lc,1:65l.lc,1:65k.ld,1:65l.ld,1:65k.n6,1:65l.n6,1:qh.lv,1:qh.lw,1:65s.lc,1:65t.lc,1:65s.ld,1:65t.ld,1:65s.n6,1:65t.n6,1:pl.lv,1:pl.lw,1:660.lc,1:661.lc,1:660.ld,1:661.ld,1:660.n6,1:661.n6,1:qn.lv,1:qn.lw,1:668.lc,1:669.lc,1:668.ld,1:669.ld,3:pr.lv,1:pr.lw,1:66g.lc,1:66h.lc,1:66g.ld,1:66h.ld,3:qt.lv,1:qt.lw,1:66o.lc,1:66p.lc,1:66o.ld,1:66p.ld,1:66o.n6,1:66p.n6,2:px.lw,2:66x.lc,2:66x.ld,2:66x.n6,1:qx.lv,1:qx.lw,1:674.lc,1:675.lc,1:674.ld,1:675.ld,1:674.n6,1:675.n6,1:q1.lv,1:q1.lw,1:67c.lc,1:67d.lc,1:67c.ld,1:67d.ld,1:67c.n6,1:67d.n6,1:q9.lc,1:q9.ld,1:qd.lc,1:qd.ld,1:qf.lc,1:qf.ld,1:qh.lc,1:qh.ld,1:qn.lc,1:qn.ld,1:qt.lc,1:qt.ld,1:qx.lc,1:qx.ld,3:64g.n9,1:64h.n9,1:64i.n9,1:64j.n9,1:64k.n9,1:64l.n9,1:64m.n9,1:64n.n9,1:64o.n9,1:64p.n9,1:64q.n9,1:64r.n9,1:64s.n9,1:64t.n9,1:64u.n9,1:64v.n9,1:65c.n9,1:65d.n9,1:65e.n9,1:65f.n9,1:65g.n9,1:65h.n9,1:65i.n9,1:65j.n9,1:65k.n9,1:65l.n9,1:65m.n9,1:65n.n9,1:65o.n9,1:65p.n9,1:65q.n9,1:65r.n9,1:674.n9,1:675.n9,1:676.n9,1:677.n9,1:678.n9,1:679.n9,1:67a.n9,1:67b.n9,1:67c.n9,1:67d.n9,1:67e.n9,1:67f.n9,1:67g.n9,1:67h.n9,1:67i.n9,1:67j.n9,1:q9.li,1:q9.lg,1:67k.n9,1:q9.n9,1:q4.n9,2:q9.n6,1:69i.n9,1:pd.li,1:pd.lg,1:pd.lc,1:pd.ld,1:pd.n9,2:qh,3:4o.n6,1:67o.n9,1:qf.n9,1:q6.n9,2:qf.n6,1:69y.n9,1:ph.lc,1:ph.ld,1:pj.lc,1:pj.ld,1:pj.n9,1:69r.lc,1:69r.ld,1:69r.n6,1:qh.li,1:qh.lg,1:qy.lc,1:qh.lk.ld,3:qh.n6,1:qy.n6,1:pl.li,1:pl.lg,1:pl.lc,1:pl.ld,2:6bi.lc,1:6bi.ld,1:6bi.n6,1:qt.li,1:qt.lg,1:qz.lc,1:qt.lk.ld,1:qp.lv,1:qp.lw,1:qt.n6,1:qz.n6,1:px.li,1:px.lg,1:px.lc,1:px.ld,1:pt.lw,1:4o.lc,1:4o.ld,1:2o,3:67w.n9,1:qx.n9,1:r2.n9,2:qx.n6,1:6ba.n9,1:pr.lc,1:pr.ld,1:q1.lc,1:q1.ld,1:q1.n9,1:50,3:6bm,1:6bn,85:q1,4:23,1:1t.lm,33:6mo.mw,1:6mq.mw,j:6ms.mw,v:6og.mw,1:6ok.mw,1:6oi.mw,1h:6pv.mw,5:6q0.mw,3:6q3.mw,o:6qr.mw,2:6qt.mw,r:6rg.mw,3:6rn.mw,3:6rp.mw,2:6rs.mw,n:1p.mw,2:6sh.mw,b:6rx.mw,1:1o.mw,1:1q.mw,1:6sk.mw,1:6sl.mw,3:6sy.mw,1:6sz.mw,3:6t2.mw,1:6t3.mw,7:6t6.mw,1:6t7.mw,3:6te.mw,1:6tf.mw,3:6ti.mw,1:6tj.mw,z:6ua.mw,1:6ug.mw,1:6uh.mw,1:6uj.mw,1d:6t8.mw,1:6t9.mw,1:6tt.mw,1:6tu.mw,7:6uq.mw,1:6ur.mw,1:6us.mw,1:6ut.mw,1o:9hk,1:9hl,1iq:8gt.mw,12o:9jf.9ll,2:9jh.9ll,2:9jj.9ll,2:9jl.9ll,2:9jn.9ll,2:9jp.9ll,2:9jr.9ll,2:9jt.9ll,2:9jv.9ll,2:9jx.9ll,2:9jz.9ll,2:9k1.9ll,3:9k4.9ll,2:9k6.9ll,2:9k8.9ll,7:9kf.9ll,1:9kf.9lm,2:9ki.9ll,1:9ki.9lm,2:9kl.9ll,1:9kl.9lm,2:9ko.9ll,1:9ko.9lm,2:9kr.9ll,1:9kr.9lm,n:9ja.9ll,a:9lp.9ll,e:9m3.9ll,2:9m5.9ll,2:9m7.9ll,2:9m9.9ll,2:9mb.9ll,2:9md.9ll,2:9mf.9ll,2:9mh.9ll,2:9mj.9ll,2:9ml.9ll,2:9mn.9ll,2:9mp.9ll,3:9ms.9ll,2:9mu.9ll,2:9mw.9ll,7:9n3.9ll,1:9n3.9lm,2:9n6.9ll,1:9n6.9lm,2:9n9.9ll,1:9n9.9lm,2:9nc.9ll,1:9nc.9lm,2:9nf.9ll,1:9nf.9lm,n:9ly.9ll,3:9nz.9ll,1:9o0.9ll,1:9o1.9ll,1:9o2.9ll,4:9od.9ll,13ia:rpk,1:kc4,1:s7e,1:rt4,1:lw1,1:fg2,1:gkl,1:vj0,1:vj0,1:hn5,1:ssx,1:gw7,1:hmw,1:jcm,1:ne1,1:p6t,1:qin,1:qt6,1:r20,1:sjz,1:kxu,1:ljv,1:mah,1:mvy,1:q4d,1:sq2,1:uep,1:fia,1:ghh,1:l50,1:mjf,1:qi5,1:v8e,1:ifk,1:m3v,1:qfh,1:r50,1:jih,1:pnc,1:qvz,1:iq2,1:kd3,1:lm2,1:mpo,1:slq,1:fpi,1:g53,1:gda,1:jwk,1:l3n,1:mj4,1:nhj,1:pa9,1:qh2,1:qjg,1:s1b,1:tv6,1:upb,1:v7e,1:nt8,1:nzz,1:otc,1:q15,1:t1g,1:vb3,1:rfa,1:hjz,1:iro,1:okg,1:pdq,1:mle,1:nuy,1:rsy,1:ttj,1:hjs,1:i8y,1:kyb,1:lp6,1:lxr,1:oq7,1:oxj,1:tor,1:gcy,1:pe3,1:g64,1:g5o,1:o4c,1:ou6,1:q29,1:tpx,1:rk0,1:jin,1:kxu,1:rge,1:fg9,1:i5j,1:iz6,1:mtj,1:n74,1:gev,1:nwb,1:fr3,1:iw9,1:ff1,1:lho,1:k1k,1:opu,1:gjn,1:hge,1:ni9,1:q4p,1:re2,1:la2,1:sds,1:lfs,1:jjy,1:put,1:jog,1:n6t,1:fji,1:g2x,1:g5l,1:kn5,1:oo7,1:prj,1:rf6,1:ssv,1:gdx,1:gn6,1:ho3,1:ir0,1:k3p,1:m4e,1:nxm,1:tkd,1:ui2,1:vbr,1:vda,1:gbf,1:kau,1:l87,1:sbm,1:ino,1:j9s,1:jcw,1:jve,1:lyb,1:mdl,1:n0p,1:o22,1:ovo,1:pdb,1:s9y,1:q9a,1:sgz,1:t3e,1:g7r,1:gbn,1:gql,1:ma0,1:r0i,1:re2,1:iq1,1:iyd,1:jnf,1:l9q,1:oji,1:mt1,1:fl0,1:h6h,1:i5j,1:iii,1:izg,1:muq,1:mzt,1:p7e,1:pc6,1:svo,1:tti,1:tvs,1:u1k,1:fpn,1:o1a,1:ss4,1:trs,1:j4x,1:fie,1:fyy,1:i5q,1:i7z,1:k2h,1:kxu,1:mha,1:ncy,1:q9o,1:sjg,1:vil,1:k94,1:tny,1:gax,1:kfv,1:kj7,1:lkx,1:luk,1:mx5,1:n6h,1:nsb,1:opc,1:u3i,1:g31,1:je6,1:tq0,1:fu3,1:ie1,1:lpm,1:sa2,1:ivf,1:j7o,1:kk7,1:mtj,1:tqe,1:g89,1:glr,1:i91,1:k5v,1:kem,1:ko8,1:lid,1:mx2,1:naa,1:p6h,1:r0v,1:r1d,1:sss,1:tsy,1:gfz,1:lve,1:gm5,1:mhc,1:n14,1:qgq,1:tr7,1:uvr,1:vbz,1:kgn,1:lor,1:pns,1:o97,1:obk,1:olu,1:mo0,1:m8p,1:riw,1:fk0,1:px2,1:g8q,1:g7b,1:ip2,1:jir,1:onq,1:i2t,1:ljy,1:kac,1:saj,1:qx8,1:tot,1:r63,1:iqb,1:g1s,1:gxs,3:hga,2:k8k,3:g66,1:mqy,1:ngq,1:ny4,1:nz2,1:nz9,1:o0f,1:tw6,1:on2,1:p8d,2:qhe,2:rg8,3:shk,1:sn1,4:u7j,1:u7w,1:u94,1:v5g,1:sm6,1:trr,1:fqm,1:fzb,1:g25,1:gcp,1:gdg,1:ggh,1:gwt,1:gzq,1:h2g,1:hfk,1:hig,1:i90,1:i9a,1:j2s,1:j8o,1:j9q,1:jci,1:k0f,1:k4i,1:k9d,1:kn9,1:lmf,1:lqy,1:lya,1:mem,1:mjv,1:mxu,1:ntd,1:ny6,1:nyh,1:nyg,1:nyo,1:nyu,1:nz1,1:o0d,1:o0e,1:o5c,1:o75,1:og0,1:ovo,1:ow9,1:oxt,1:p6a,1:pad,1:pnx,1:prt,1:prt,1:q53,1:r2o,1:r6e,1:rgh,1:ri1,1:rtf,1:ruw,1:sdy,1:shk,1:tsz,1:u0v,1:u2j,1:j1x,1:36cu,1:pp4,3:ffq,1:g51,1:g2w,1:fpc,1:g1x,1:g3k,1:gcn,1:ge2,1:gwt,1:gut,1:gwp,1:gyq,1:hga,1:hir,1:hms,1:hn8,1:huq,1:i08,1:iqa,1:iqh,1:iuh,1:iwd,1:j4o,1:j7y,1:j60,1:j9q,1:j8g,1:jci,1:jec,1:jpg,1:jrw,1:jte,1:k0m,1:k8k,1:kd3,1:kd7,1:keu,1:l89,1:la2,1:lkx,1:lwb,1:lvv,1:lya,1:m5a,1:mem,1:nmv,1:mk5,1:mnj,1:mqy,1:n01,1:n46,1:n5n,1:nbx,1:nbz,1:ngq,1:nh7,1:nhw,1:nka,1:nk0,1:nv0,1:o8h,1:og0,1:ol7,1:orf,1:ovo,1:p4u,1:pad,1:pxu,1:q27,1:qrd,1:r41,1:r5y,1:r6e,1:ren,1:rg8,1:rez,1:rgh,1:rge,1:rfx,1:ri1,1:rka,1:ruw,1:sag,1:sj6,1:srd,1:sxi,1:tq4,1:tsz,1:tw6,1:tzv,1:u0v,1:u17,1:u2j,1:umq,1:vj0,1:313e,1:3138,1:33dh,1:brx,1:cns,1:cop,1:39e1,1:3bgw,1:3i6r,1:vgj,1:vim,1w:15l.14k,2:16a.14n,b:161.14x,1:161.14y,1:161.14s.14x,1:161.14s.14y,1:15c.14n,1:15c.14o,1:15c.14s,1:15d.14s,1:15e.14s,1:15f.14s,1:15g.14s,1:15h.14s,1:15i.14s,2:15k.14s,1:15l.14s,1:15m.14s,1:15n.14s,1:15o.14s,2:15q.14s,2:15s.14s,1:15t.14s,2:15v.14s,1:15w.14s,2:15y.14s,1:15z.14s,1:160.14s,1:161.14s,1:162.14s,1:15h.14p,1:15d.14v,1:15n.14v,1:15w.14v,47g:1huh.1hve,2:1huj.1hve,f:1hut.1hve,3n:1hyp.1hyf,1:1hyq.1hyf,f0:1idj.1ida,1:1idj.1idz,a7:1int.1inu,1:1int.1ink,2:1int.1inx,70:1iuw.1iun,1:1iux.1iun,ot:1jjp.1jjk,10di:2jx3.2jxh,1:2jx4.2jxh,1:2jx4.2jxh.2jxq,1:2jx4.2jxh.2jxr,1:2jx4.2jxh.2jxs,1:2jx4.2jxh.2jxt,1:2jx4.2jxh.2jxu,2f:2jzt.2jxh,1:2jzu.2jxh,1:2jzt.2jxh.2jxq,1:2jzu.2jxh.2jxq,1:2jzt.2jxh.2jxr,1:2jzu.2jxh.2jxr,1m4g:fgd,1:fg8,1:fgh,1:2tcy,1:fog,1:fqm,1:fqz,1:fsy,1:fwa,1:fx5,1:fzb,1:fyn,1:ae6,1:2ud6,1:g25,1:g2c,1:g2s,1:g3b,1:2u58,1:aex,1:g2v,1:g3x,1:2u6j,1:g47,1:g4k,1:fkc,1:g4s,1:g51,1:3ly7,1:g6t,1:g77,1:afz,1:g8r,1:g92,1:gaa,1:gaf,1:ahh,1:gcn,1:gcp,1:gdg,1:ge2,1:ged,1:gee,1:gev,1:gg9,1:ggh,1:ggq,1:ghf,1:ghp,1:ghr,1:ghr,1:ghr,1:2v58,1:m7k,1:gju,1:gkf,1:2vdv,1:gkr,1:gkx,1:gli,1:gpq,1:gmw,1:gnc,1:go8,1:gpu,1:gs6,1:gsw,1:gur,1:gv7,1:gw4,1:gw4,1:gwp,1:gx7,1:gxf,1:gxu,1:h7a,1:gzq,1:h7b,1:h1t,1:h2s,1:g7b,1:hke,1:hce,1:hdg,1:he5,1:haj,1:hf6,1:hf5,1:hik,1:2x9g,1:hki,1:hkn,1:hl2,1:hlm,1:hlu,1:hnm,1:2xm0,1:2xnu,1:hrg,1:hsr,1:ht3,1:hqw,1:huu,1:aum,1:av0,1:hzc,1:i0u,1:i0u,1:2y88,1:i4j,1:i54,1:i5j,1:i5v,1:2yhk,1:i67,1:i6e,1:itv,1:i76,1:ayp,1:i8w,1:i9a,1:ibk,1:ia5,1:2z1g,1:if7,1:2z1i,1:ige,1:igb,1:igs,1:ijl,1:ijm,1:b3j,1:ikd,1:ilk,1:im5,1:ind,1:b4y,1:2zr7,1:b5o,1:ipc,1:ipf,1:ipi,1:iq2,1:3pg2,1:iri,1:3035,1:3035,1:poh,1:isi,1:isi,1:b7r,1:335k,1:3cgq,1:iua,1:iuj,1:b8j,1:ivu,1:ix9,1:ixj,1:iyh,1:j29,1:bay,1:ba4,1:j2s,1:30t0,1:j47,1:j7s,1:j7w,1:j7y,1:j7w,1:j96,1:j9q,1:jaq,1:jac,1:jan,1:jby,1:jci,1:jcm,1:jdc,1:jdn,1:jfh,1:jht,1:jis,1:jm8,1:31n0,1:jlp,1:jjw,1:jmw,1:jnn,1:jqc,1:31td,1:js2,1:jph,1:jop,1:bhq,1:ju1,1:jum,1:jvh,1:juf,1:bjg,1:k0f,1:k18,1:32mi,1:k4j,1:kc8,1:k7d,1:bo9,1:k9d,1:bns,1:bms,1:g42,1:g45,1:kcg,1:k9o,1:pf1,1:deh,1:kd3,1:kd7,1:kdd,1:kf2,1:ker,1:33cz,1:bpl,1:kje,1:kg5,1:klu,1:kn9,1:33hp,1:kni,1:kkf,1:kr8,1:brx,1:ksi,1:kv7,1:kx6,1:l2g,1:33xf,1:l3v,1:bvc,1:l5t,1:34br,1:l78,1:bwu,1:l82,1:l9b,1:la2,1:la3,1:34p9,1:2yvf,1:34sa,1:le6,1:354s,1:lhb,1:lhp,1:lev,1:ljq,1:lku,1:lmf,1:lkx,1:lm1,1:lmg,1:lmt,1:357i,1:lkk,1:lrj,1:lta,1:c37,1:lvv,1:lvr,1:35jl,1:lq1,1:m0e,1:35ni,1:35ou,1:m2u,1:m61,1:m5a,1:m57,1:c5y,1:m6i,1:m7x,1:m7r,1:m99,1:2u5h,1:mdh,1:368z,1:mfw,1:36i3,1:mjs,1:mk5,1:mkw,1:36yw,1:mm8,1:mmt,1:3779,1:37dg,1:mt6,1:mtn,1:cdo,1:mud,1:ce0,1:ce0,1:myv,1:mzg,1:n01,1:n0l,1:n2i,1:cgr,1:n50,1:386u,1:n5q,1:389e,1:n74,1:2zrz,1:nbk,1:38v5,1:38vs,1:38zo,1:cn0,1:cnc,1:nhw,1:394j,1:394i,1:395l,1:396b,1:nj2,1:nj3,1:nj3,1:nka,1:cop,1:nm3,1:cp2,1:cra,1:39r1,1:nri,1:nt8,1:nv0,1:ctf,1:3a5i,1:nyu,1:3a8q,1:3a9x,1:o0f,1:o2z,1:cvj,1:o5c,1:o5m,1:o5r,1:3at8,1:3b1j,1:3b1j,1:oa6,1:d1e,1:3b8r,1:og6,1:og9,1:d2f,1:3beo,1:onm,1:d5s,1:oo8,1:oo3,1:oow,1:3c06,1:orn,1:d8h,1:ouf,1:ow2,1:oxx,1:d9w,1:3ciw,1:3cjr,1:dax,1:3cnt,1:p6i,1:3cqm,1:p79,1:pa2,1:pad,1:3d22,1:3d43,1:pcw,1:3d7s,1:pdc,1:33a7,1:ded,1:pf6,1:phf,1:dfv,1:pj2,1:hx1,1:3dlz,1:3dmd,1:33bn,1:33bw,1:poh,1:pok,1:sda,1:dij,1:psh,1:psb,1:pst,1:gc3,1:ptd,1:ptf,1:ptp,1:puu,1:3ebg,1:put,1:pwd,1:pyb,1:q0d,1:pwj,1:q0t,1:q1z,1:q53,1:pxv,1:q16,1:q18,1:q1o,1:3eie,1:3eqz,1:3emt,1:dnv,1:q9d,1:q9f,1:qae,1:3g0a,1:qck,1:3f3g,1:dp9,1:dpd,1:3f75,1:3ff6,1:dpn,1:qj4,1:qjg,1:qjr,1:qjt,1:qll,1:qko,1:qoe,1:qn6,1:qrd,1:qp4,1:qqz,1:qrq,1:dsn,1:qu9,1:qv5,1:dtl,1:qxs,1:qxv,1:3giv,1:r13,1:r1a,1:dv9,1:r22,1:aez,1:3gz2,1:3h46,1:dz2,1:dzb,1:rds,1:rfx,1:rka,1:rpx,1:3hrc,1:rsb,1:rsx,1:rvf,1:rxz,1:3i9b,1:2upw,1:s0b,1:rzw,1:s1c,1:2uvy,1:s7o,1:sag,1:3jki,1:3jl9,1:sk4,1:smp,1:snl,1:3ju6,1:snv,1:svs,1:t07,1:t08,1:sxo,1:t89,1:t91,1:3ksa,1:tjf,1:ej9,1:tkn,1:3l2v,1:eli,1:ts3,1:iia,1:tur,1:3ltx,1:3lzu,1:epa,1:epi,1:u00,1:3mdm,1:er6,1:3mhi,1:u17,1:u17,1:u21,1:3mpi,1:u76,1:eur,1:u95,1:ucn,1:ude,1:uf2,1:ez2,1:3nsg,1:umq,1:uv4,1:v0d,1:f66,1:f71,1:v3b,1:3owe,1:f7c,1:3oxx,1:3p5a,1:3p8x,1:vcr,1:f9y,1:veh,1:vem,1:vet,1:vf3,1:vfa,1:vgb,1:3pxc"; +export const PRIMARY_COMPOSITES = "5c,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,4,1,1,1,2,1,1,1,1,1,5,1,1,1,1,1,4,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,y,1,e,1,t,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,4,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,7,1,1,1,1,1,1,1,1,1,1,1,1,1,9e,1,2,1,1,2,2,1,1,q,1,1,1,1,1,1,q,1,1,1,1,5,1,18,1,2,4,5,1,1,b,w,n,1,2,4,5,1,1,o,1,22,1,e,1,1,1,3,1,3,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,3,1,89,1,1,1,1,4a,2,h,gm,8,3,47,1,ak,3,1,20,1i,1,1,3g,3c,7,1,2,1,3j,1,1,3y,2,1,1,g8,25c,2,2,2,2,4,15,2,3,1,2,jh,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,5,1,1,1,2,1,1,2,2,1,1,1,1,1,1,4,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,2,1,5,1,1,2,1,1,2,2,bi,1,j,v,1,1,1h,5,3,o,2,r,3,3,2,n,2,b,1,1,1,1,3,1,3,1,7,1,3,1,3,1,z,1,1,1,1d,1,1,1,7,1,1,1,2n3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,7,1,2,1,2,1,2,1,2,1,n,a,e,2,2,2,2,2,2,2,2,2,2,2,3,2,2,7,1,2,1,2,1,2,1,2,1,n,3,1,1,1,4,1864,2,f,3n,1,f0,1,a7,1,2,70,1,ot"; +export const CASE_FOLDING = "1t:2p,1:2q,1:2r,1:2s,1:2t,1:2u,1:2v,1:2w,1:2x,1:2y,1:2z,1:30,1:31,1:32,1:33,1:34,1:35,1:36,1:37,1:38,1:39,1:3a,1:3b,1:3c,1:3d,1:3e,2j:qk,b:68,1:69,1:6a,1:6b,1:6c,1:6d,1:6e,1:6f,1:6g,1:6h,1:6i,1:6j,1:6k,1:6l,1:6m,1:6n,1:6o,1:6p,1:6q,1:6r,1:6s,1:6t,1:6u,2:6w,1:6x,1:6y,1:6z,1:70,1:71,1:72,1:37.37,x:75,2:77,2:79,2:7b,2:7d,2:7f,2:7h,2:7j,2:7l,2:7n,2:7p,2:7r,2:7t,2:7v,2:7x,2:7z,2:81,2:83,2:85,2:87,2:89,2:8b,2:8d,2:8f,2:2x.lj,2:8j,2:8l,2:8n,3:8q,2:8s,2:8u,2:8w,2:8y,2:90,2:92,2:94,2:jg.32,1:97,2:99,2:9b,2:9d,2:9f,2:9h,2:9j,2:9l,2:9n,2:9p,2:9r,2:9t,2:9v,2:9x,2:9z,2:a1,2:a3,2:a5,2:a7,2:a9,2:ab,2:ad,2:af,2:73,1:ai,2:ak,2:am,2:37,2:gj,1:ar,2:at,2:gk,1:aw,2:gm,1:gn,1:b0,3:d9,1:gp,1:gr,1:b6,2:gw,1:gz,2:h5,1:h4,1:bd,4:hb,1:he,2:hh,1:bl,2:bn,2:bp,2:hs,1:bs,2:hv,3:bx,2:i0,1:c0,2:i2,1:i3,1:c4,2:c6,2:ia,1:c9,4:cd,8:cm,1:cm,2:cp,1:cp,2:cs,1:cs,2:cu,2:cw,2:cy,2:d0,2:d2,2:d4,2:d6,2:d8,3:db,2:dd,2:df,2:dh,2:dj,2:dl,2:dn,2:dp,2:dr,2:2y.lo,1:dv,1:dv,2:dx,2:b9,1:cf,1:e1,2:e3,2:e5,2:e7,2:e9,2:eb,2:ed,2:ef,2:eh,2:ej,2:el,2:en,2:ep,2:er,2:et,2:ev,2:ex,2:ez,2:f1,2:f3,2:bi,2:f7,2:f9,2:fb,2:fd,2:ff,2:fh,2:fj,2:fl,2:fn,8:8rp,1:fw,2:be,1:8rq,3:g2,2:ao,1:i1,1:i4,1:g7,2:g9,2:gb,2:gd,2:gf,6v:qh,17:oh,2:oj,4:on,9:s3,7:q4,2:q5,1:q6,1:q7,2:r0,2:r1,1:r2,1:qh.lk.ld,1:q9,1:qa,1:qb,1:qc,1:qd,1:qe,1:qf,1:qg,1:qh,1:qi,1:qj,1:qk,1:ql,1:qm,1:qn,1:qo,1:qp,2:qr,1:qs,1:qt,1:qu,1:qv,1:qw,1:qx,1:qy,1:qz,5:qt.lk.ld,i:qr,d:rb,1:qa,1:qg,4:qu,1:qo,2:rd,2:rf,2:rh,2:rj,2:rl,2:rn,2:rp,2:rr,2:rt,2:rv,2:rx,2:rz,2:qi,1:qp,3:qg,1:qd,2:s8,2:s2,1:sb,3:or,1:os,1:ot,1:uo,1:up,1:uq,1:ur,1:us,1:ut,1:uu,1:uv,1:uw,1:ux,1:uy,1:uz,1:v0,1:v1,1:v2,1:v3,1:ts,1:tt,1:tu,1:tv,1:tw,1:tx,1:ty,1:tz,1:u0,1:u1,1:u2,1:u3,1:u4,1:u5,1:u6,1:u7,1:u8,1:u9,1:ua,1:ub,1:uc,1:ud,1:ue,1:uf,1:ug,1:uh,1:ui,1:uj,1:uk,1:ul,1:um,1:un,1d:v5,2:v7,2:v9,2:vb,2:vd,2:vf,2:vh,2:vj,2:vl,2:vn,2:vp,2:vr,2:vt,2:vv,2:vx,2:vz,2:w1,a:wb,2:wd,2:wf,2:wh,2:wj,2:wl,2:wn,2:wp,2:wr,2:wt,2:wv,2:wx,2:wz,2:x1,2:x3,2:x5,2:x7,2:x9,2:xb,2:xd,2:xf,2:xh,2:xj,2:xl,2:xn,2:xp,2:xr,2:y7,1:xu,2:xw,2:xy,2:y0,2:y2,2:y4,2:y6,3:y9,2:yb,2:yd,2:yf,2:yh,2:yj,2:yl,2:yn,2:yp,2:yr,2:yt,2:yv,2:yx,2:yz,2:z1,2:z3,2:z5,2:z7,2:z9,2:zb,2:zd,2:zf,2:zh,2:zj,2:zl,2:zn,2:zp,2:zr,2:zt,2:zv,2:zx,2:zz,2:101,2:103,2:105,2:107,2:109,2:10b,2:10d,2:10f,2:10h,2:10j,2:10l,2:10n,2:10p,2:10r,2:10t,2:10v,3:129,1:12a,1:12b,1:12c,1:12d,1:12e,1:12f,1:12g,1:12h,1:12i,1:12j,1:12k,1:12l,1:12m,1:12n,1:12o,1:12p,1:12q,1:12r,1:12s,1:12t,1:12u,1:12v,1:12w,1:12x,1:12y,1:12z,1:130,1:131,1:132,1:133,1:134,1:135,1:136,1:137,1:138,1:139,1:13a,1d:12d.136,26x:8w0,1:8w1,1:8w2,1:8w3,1:8w4,1:8w5,1:8w6,1:8w7,1:8w8,1:8w9,1:8wa,1:8wb,1:8wc,1:8wd,1:8we,1:8wf,1:8wg,1:8wh,1:8wi,1:8wj,1:8wk,1:8wl,1:8wm,1:8wn,1:8wo,1:8wp,1:8wq,1:8wr,1:8ws,1:8wt,1:8wu,1:8wv,1:8ww,1:8wx,1:8wy,1:8wz,1:8x0,1:8x1,2:8x3,6:8x9,mj:3xs,1:3xt,1:3xu,1:3xv,1:3xw,1:3xx,1oj:tu,1:tw,1:u6,1:u9,1:ua,1:ua,1:ui,1:v7,1:wuj,8:3bk,1:3bl,1:3bm,1:3bn,1:3bo,1:3bp,1:3bq,1:3br,1:3bs,1:3bt,1:3bu,1:3bv,1:3bw,1:3bx,1:3by,1:3bz,1:3c0,1:3c1,1:3c2,1:3c3,1:3c4,1:3c5,1:3c6,1:3c7,1:3c8,1:3c9,1:3ca,1:3cb,1:3cc,1:3cd,1:3ce,1:3cf,1:3cg,1:3ch,1:3ci,1:3cj,1:3ck,1:3cl,1:3cm,1:3cn,1:3co,1:3cp,1:3cq,3:3ct,1:3cu,1:3cv,8x:5xd,2:5xf,2:5xh,2:5xj,2:5xl,2:5xn,2:5xp,2:5xr,2:5xt,2:5xv,2:5xx,2:5xz,2:5y1,2:5y3,2:5y5,2:5y7,2:5y9,2:5yb,2:5yd,2:5yf,2:5yh,2:5yj,2:5yl,2:5yn,2:5yp,2:5yr,2:5yt,2:5yv,2:5yx,2:5yz,2:5z1,2:5z3,2:5z5,2:5z7,2:5z9,2:5zb,2:5zd,2:5zf,2:5zh,2:5zj,2:5zl,2:5zn,2:5zp,2:5zr,2:5zt,2:5zv,2:5zx,2:5zz,2:601,2:603,2:605,2:607,2:609,2:60b,2:60d,2:60f,2:60h,2:60j,2:60l,2:60n,2:60p,2:60r,2:60t,2:60v,2:60x,2:60z,2:611,2:613,2:615,2:617,2:619,2:61b,2:61d,2:61f,2:61h,2:2w.mp,1:38.lk,1:3b.lm,1:3d.lm,1:2p.ji,1:601,3:37.37,2:61t,2:61v,2:61x,2:61z,2:621,2:623,2:625,2:627,2:629,2:62b,2:62d,2:62f,2:62h,2:62j,2:62l,2:62n,2:62p,2:62r,2:62t,2:62v,2:62x,2:62z,2:631,2:633,2:635,2:637,2:639,2:63b,2:63d,2:63f,2:63h,2:63j,2:63l,2:63n,2:63p,2:63r,2:63t,2:63v,2:63x,2:63z,2:641,2:643,2:645,2:647,2:649,2:64b,2:64d,2:64f,a:64g,1:64h,1:64i,1:64j,1:64k,1:64l,1:64m,1:64n,9:64w,1:64x,1:64y,1:64z,1:650,1:651,b:65c,1:65d,1:65e,1:65f,1:65g,1:65h,1:65i,1:65j,9:65s,1:65t,1:65u,1:65v,1:65w,1:65x,1:65y,1:65z,9:668,1:669,1:66a,1:66b,1:66c,1:66d,3:qt.lv,2:qt.lv.lc,2:qt.lv.ld,2:qt.lv.n6,3:66p,2:66r,2:66t,2:66v,9:674,1:675,1:676,1:677,1:678,1:679,1:67a,1:67b,h:64g.qh,1:64h.qh,1:64i.qh,1:64j.qh,1:64k.qh,1:64l.qh,1:64m.qh,1:64n.qh,1:64g.qh,1:64h.qh,1:64i.qh,1:64j.qh,1:64k.qh,1:64l.qh,1:64m.qh,1:64n.qh,1:65c.qh,1:65d.qh,1:65e.qh,1:65f.qh,1:65g.qh,1:65h.qh,1:65i.qh,1:65j.qh,1:65c.qh,1:65d.qh,1:65e.qh,1:65f.qh,1:65g.qh,1:65h.qh,1:65i.qh,1:65j.qh,1:674.qh,1:675.qh,1:676.qh,1:677.qh,1:678.qh,1:679.qh,1:67a.qh,1:67b.qh,1:674.qh,1:675.qh,1:676.qh,1:677.qh,1:678.qh,1:679.qh,1:67a.qh,1:67b.qh,3:67k.qh,1:q9.qh,1:q4.qh,2:q9.n6,1:q9.n6.qh,1:69c,1:69d,1:67k,1:67l,1:q9.qh,2:qh,4:67o.qh,1:qf.qh,1:q6.qh,2:qf.n6,1:qf.n6.qh,1:67m,1:67n,1:67o,1:67p,1:qf.qh,6:qh.lk.lc,1:qh.lk.ld,3:qh.n6,1:qh.lk.n6,1:6a8,1:6a9,1:67q,1:67r,7:qt.lk.lc,1:qt.lk.ld,1:qp.lv,2:qt.n6,1:qt.lk.n6,1:6ao,1:6ap,1:67u,1:67v,1:6at,6:67w.qh,1:qx.qh,1:r2.qh,2:qx.n6,1:qx.n6.qh,1:67s,1:67t,1:67w,1:67x,1:qx.qh,8a:qx,4:2z,1:6d,7:6ku,1a:6ls,1:6lt,1:6lu,1:6lv,1:6lw,1:6lx,1:6ly,1:6lz,1:6m0,1:6m1,1:6m2,1:6m3,1:6m4,1:6m5,1:6m6,1:6m7,k:6mc,mr:79s,1:79t,1:79u,1:79v,1:79w,1:79x,1:79y,1:79z,1:7a0,1:7a1,1:7a2,1:7a3,1:7a4,1:7a5,1:7a6,1:7a7,1:7a8,1:7a9,1:7aa,1:7ab,1:7ac,1:7ad,1:7ae,1:7af,1:7ag,1:7ah,1f5:8q8,1:8q9,1:8qa,1:8qb,1:8qc,1:8qd,1:8qe,1:8qf,1:8qg,1:8qh,1:8qi,1:8qj,1:8qk,1:8ql,1:8qm,1:8qn,1:8qo,1:8qp,1:8qq,1:8qr,1:8qs,1:8qt,1:8qu,1:8qv,1:8qw,1:8qx,1:8qy,1:8qz,1:8r0,1:8r1,1:8r2,1:8r3,1:8r4,1:8r5,1:8r6,1:8r7,1:8r8,1:8r9,1:8ra,1:8rb,1:8rc,1:8rd,1:8re,1:8rf,1:8rg,1:8rh,1:8ri,1:8rj,1d:8rl,2:h7,1:5tp,1:hp,3:8rs,2:8ru,2:8rw,2:gh,1:hd,1:gg,1:gi,2:8s3,3:8s6,9:fz,1:g0,1:8sh,2:8sj,2:8sl,2:8sn,2:8sp,2:8sr,2:8st,2:8sv,2:8sx,2:8sz,2:8t1,2:8t3,2:8t5,2:8t7,2:8t9,2:8tb,2:8td,2:8tf,2:8th,2:8tj,2:8tl,2:8tn,2:8tp,2:8tr,2:8tt,2:8tv,2:8tx,2:8tz,2:8u1,2:8u3,2:8u5,2:8u7,2:8u9,2:8ub,2:8ud,2:8uf,2:8uh,2:8uj,2:8ul,2:8un,2:8up,2:8ur,2:8ut,2:8uv,2:8ux,2:8uz,2:8v1,2:8v3,2:8v5,2:8v7,9:8vg,2:8vi,5:8vn,nym:wu9,2:wub,2:wud,2:wuf,2:wuh,2:wuj,2:wul,2:wun,2:wup,2:wur,2:wut,2:wuv,2:wux,2:wuz,2:wv1,2:wv3,2:wv5,2:wv7,2:wv9,2:wvb,2:wvd,2:wvf,2:wvh,k:ww1,2:ww3,2:ww5,2:ww7,2:ww9,2:wwb,2:wwd,2:wwf,2:wwh,2:wwj,2:wwl,2:wwn,2:wwp,2:wwr,3s:x0j,2:x0l,2:x0n,2:x0p,2:x0r,2:x0t,2:x0v,4:x0z,2:x11,2:x13,2:x15,2:x17,2:x19,2:x1b,2:x1d,2:x1f,2:x1h,2:x1j,2:x1l,2:x1n,2:x1p,2:x1r,2:x1t,2:x1v,2:x1x,2:x1z,2:x21,2:x23,2:x25,2:x27,2:x29,2:x2b,2:x2d,2:x2f,2:x2h,2:x2j,2:x2l,2:x2n,b:x2y,2:x30,2:5tl,1:x33,2:x35,2:x37,2:x39,2:x3b,5:x3g,2:h1,3:x3l,2:x3n,4:x3r,2:x3t,2:x3v,2:x3x,2:x3z,2:x41,2:x43,2:x45,2:x47,2:x49,2:h2,1:gs,1:gx,1:h8,1:h6,2:im,1:hz,1:il,1:xub,1:x4l,2:x4n,2:x4p,2:x4r,2:x4t,2:x4v,2:x4x,2:x4z,2:x3o,1:hu,1:5u6,1:x54,2:x56,7:x5d,6:x5j,2:x5l,t:x6e,or:3vk,1:3vl,1:3vm,1:3vn,1:3vo,1:3vp,1:3vq,1:3vr,1:3vs,1:3vt,1:3vu,1:3vv,1:3vw,1:3vx,1:3vy,1:3vz,1:3w0,1:3w1,1:3w2,1:3w3,1:3w4,1:3w5,1:3w6,1:3w7,1:3w8,1:3w9,1:3wa,1:3wb,1:3wc,1:3wd,1:3we,1:3wf,1:3wg,1:3wh,1:3wi,1:3wj,1:3wk,1:3wl,1:3wm,1:3wn,1:3wo,1:3wp,1:3wq,1:3wr,1:3ws,1:3wt,1:3wu,1:3wv,1:3ww,1:3wx,1:3wy,1:3wz,1:3x0,1:3x1,1:3x2,1:3x3,1:3x4,1:3x5,1:3x6,1:3x7,1:3x8,1:3x9,1:3xa,1:3xb,1:3xc,1:3xd,1:3xe,1:3xf,1:3xg,1:3xh,1:3xi,1:3xj,1:3xk,1:3xl,1:3xm,1:3xn,1:3xo,1:3xp,1:3xq,1:3xr,fnl:2u.2u,1:2u.2x,1:2u.30,1:2u.2u.2x,1:2u.2u.30,1:37.38,1:37.38,d:12s.12u,1:12s.12d,1:12s.12j,1:132.12u,1:12s.12l,sq:1ef5,1:1ef6,1:1ef7,1:1ef8,1:1ef9,1:1efa,1:1efb,1:1efc,1:1efd,1:1efe,1:1eff,1:1efg,1:1efh,1:1efi,1:1efj,1:1efk,1:1efl,1:1efm,1:1efn,1:1efo,1:1efp,1:1efq,1:1efr,1:1efs,1:1eft,1:1efu,xy:1fe0,1:1fe1,1:1fe2,1:1fe3,1:1fe4,1:1fe5,1:1fe6,1:1fe7,1:1fe8,1:1fe9,1:1fea,1:1feb,1:1fec,1:1fed,1:1fee,1:1fef,1:1feg,1:1feh,1:1fei,1:1fej,1:1fek,1:1fel,1:1fem,1:1fen,1:1feo,1:1fep,1:1feq,1:1fer,1:1fes,1:1fet,1:1feu,1:1fev,1:1few,1:1fex,1:1fey,1:1fez,1:1ff0,1:1ff1,1:1ff2,1:1ff3,3t:1fiw,1:1fix,1:1fiy,1:1fiz,1:1fj0,1:1fj1,1:1fj2,1:1fj3,1:1fj4,1:1fj5,1:1fj6,1:1fj7,1:1fj8,1:1fj9,1:1fja,1:1fjb,1:1fjc,1:1fjd,1:1fje,1:1fjf,1:1fjg,1:1fjh,1:1fji,1:1fjj,1:1fjk,1:1fjl,1:1fjm,1:1fjn,1:1fjo,1:1fjp,1:1fjq,1:1fjr,1:1fjs,1:1fjt,1:1fju,1:1fjv,4d:1fo7,1:1fo8,1:1fo9,1:1foa,1:1fob,1:1foc,1:1fod,1:1foe,1:1fof,1:1fog,1:1foh,2:1foj,1:1fok,1:1fol,1:1fom,1:1fon,1:1foo,1:1fop,1:1foq,1:1for,1:1fos,1:1fot,1:1fou,1:1fov,1:1fow,1:1fox,2:1foz,1:1fp0,1:1fp1,1:1fp2,1:1fp3,1:1fp4,1:1fp5,2:1fp7,1:1fp8,1d7:1h34,1:1h35,1:1h36,1:1h37,1:1h38,1:1h39,1:1h3a,1:1h3b,1:1h3c,1:1h3d,1:1h3e,1:1h3f,1:1h3g,1:1h3h,1:1h3i,1:1h3j,1:1h3k,1:1h3l,1:1h3m,1:1h3n,1:1h3o,1:1h3p,1:1h3q,1:1h3r,1:1h3s,1:1h3t,1:1h3u,1:1h3v,1:1h3w,1:1h3x,1:1h3y,1:1h3z,1:1h40,1:1h41,1:1h42,1:1h43,1:1h44,1:1h45,1:1h46,1:1h47,1:1h48,1:1h49,1:1h4a,1:1h4b,1:1h4c,1:1h4d,1:1h4e,1:1h4f,1:1h4g,1:1h4h,1:1h4i,2cu:1jgg,1:1jgh,1:1jgi,1:1jgj,1:1jgk,1:1jgl,1:1jgm,1:1jgn,1:1jgo,1:1jgp,1:1jgq,1:1jgr,1:1jgs,1:1jgt,1:1jgu,1:1jgv,1:1jgw,1:1jgx,1:1jgy,1:1jgz,1:1jh0,1:1jh1,1:1jh2,1:1jh3,1:1jh4,1:1jh5,1:1jh6,1:1jh7,1:1jh8,1:1jh9,1:1jha,1:1jhb,gw1:20dc,1:20dd,1:20de,1:20df,1:20dg,1:20dh,1:20di,1:20dj,1:20dk,1:20dl,1:20dm,1:20dn,1:20do,1:20dp,1:20dq,1:20dr,1:20ds,1:20dt,1:20du,1:20dv,1:20dw,1:20dx,1:20dy,1:20dz,1:20e0,1:20e1,1:20e2,1:20e3,1:20e4,1:20e5,1:20e6,1:20e7,o81:2oma,1:2omb,1:2omc,1:2omd,1:2ome,1:2omf,1:2omg,1:2omh,1:2omi,1:2omj,1:2omk,1:2oml,1:2omm,1:2omn,1:2omo,1:2omp,1:2omq,1:2omr,1:2oms,1:2omt,1:2omu,1:2omv,1:2omw,1:2omx,1:2omy,1:2omz,1:2on0,1:2on1,1:2on2,1:2on3,1:2on4,1:2on5,1:2on6,1:2on7"; diff --git a/packages/skill-tree/src/unicode-15.ts b/packages/skill-tree/src/unicode-15.ts new file mode 100644 index 0000000..9b3aee5 --- /dev/null +++ b/packages/skill-tree/src/unicode-15.ts @@ -0,0 +1,200 @@ +/** + * Unicode 15.0.0 character data for path validation: general category + * (assigned / Cf), canonical normalization (NFD, NFC) and full case folding + * (CaseFolding.txt statuses C and F). Everything is driven by tables + * generated from the 15.0.0 UCD files, never by the runtime's Intl or + * String.prototype.normalize data, so every runtime classifies a path + * identically (contract 4.3). + */ +import { + ASSIGNED_RANGES, + CANONICAL_DECOMPOSITIONS, + CASE_FOLDING, + COMBINING_CLASSES, + FORMAT_RANGES, + PRIMARY_COMPOSITES, + UNICODE_VERSION, +} from "./unicode-15-tables"; + +export { UNICODE_VERSION }; + +/** Decodes "delta.len" base-36 range items into flat [lo, hi, ...] pairs. */ +function decodeRanges(encoded: string): Int32Array { + const items = encoded.split(","); + const out = new Int32Array(items.length * 2); + let prev = 0; + items.forEach((item, i) => { + const [delta = "", len = ""] = item.split("."); + const lo = prev + parseInt(delta, 36); + const hi = lo + parseInt(len, 36); + out[i * 2] = lo; + out[i * 2 + 1] = hi; + prev = hi; + }); + return out; +} + +/** Decodes "deltaKey:v1.v2" items (key delta-coded, values absolute) into a map. */ +function decodeMap(encoded: string): Map { + const out = new Map(); + let prev = 0; + for (const item of encoded.split(",")) { + const [key = "", values = ""] = item.split(":"); + prev += parseInt(key, 36); + out.set(prev, values.split(".").map((v) => parseInt(v, 36))); + } + return out; +} + +function inRanges(ranges: Int32Array, cp: number): boolean { + let lo = 0; + let hi = ranges.length / 2 - 1; + while (lo <= hi) { + const mid = (lo + hi) >> 1; + if (cp < ranges[mid * 2]!) hi = mid - 1; + else if (cp > ranges[mid * 2 + 1]!) lo = mid + 1; + else return true; + } + return false; +} + +const assigned = decodeRanges(ASSIGNED_RANGES); +const format = decodeRanges(FORMAT_RANGES); +const decompositions = decodeMap(CANONICAL_DECOMPOSITIONS); +const folding = decodeMap(CASE_FOLDING); + +const combiningClasses = new Map(); +{ + let prev = 0; + for (const item of COMBINING_CLASSES.split(",")) { + const [delta = "", len = "", value = ""] = item.split("."); + const lo = prev + parseInt(delta, 36); + const hi = lo + parseInt(len, 36); + for (let cp = lo; cp <= hi; cp++) combiningClasses.set(cp, parseInt(value, 36)); + prev = hi; + } +} + +const compositions = new Map(); +{ + let prev = 0; + for (const delta of PRIMARY_COMPOSITES.split(",")) { + prev += parseInt(delta, 36); + const [a, b] = decompositions.get(prev) ?? []; + if (a !== undefined && b !== undefined) compositions.set(pairKey(a, b), prev); + } +} + +function pairKey(a: number, b: number): number { + return a * 0x110000 + b; +} + +/** General category is not Cn (Co and Cs count as assigned). */ +export function isAssigned(cp: number): boolean { + return inRanges(assigned, cp); +} + +/** General category Cf. */ +export function isFormat(cp: number): boolean { + return inRanges(format, cp); +} + +export function combiningClass(cp: number): number { + return combiningClasses.get(cp) ?? 0; +} + +/** The C+F case folding of one code point, or undefined when it has none. */ +export function caseFold(cp: number): readonly number[] | undefined { + return folding.get(cp); +} + +/** Every code point with a C or F case folding entry. */ +export function caseFoldEntries(): ReadonlyMap { + return folding; +} + +// Hangul syllable constants (Unicode 3.12). +const S_BASE = 0xac00, L_BASE = 0x1100, V_BASE = 0x1161, T_BASE = 0x11a7; +const L_COUNT = 19, V_COUNT = 21, T_COUNT = 28, N_COUNT = V_COUNT * T_COUNT, S_COUNT = L_COUNT * N_COUNT; + +function decomposeInto(cp: number, out: number[]): void { + const s = cp - S_BASE; + if (s >= 0 && s < S_COUNT) { + out.push(L_BASE + Math.floor(s / N_COUNT), V_BASE + Math.floor((s % N_COUNT) / T_COUNT)); + if (s % T_COUNT !== 0) out.push(T_BASE + (s % T_COUNT)); + return; + } + const mapping = decompositions.get(cp); + if (mapping === undefined) out.push(cp); + else for (const m of mapping) decomposeInto(m, out); +} + +/** Canonical decomposition with canonical ordering (NFD) over code points. */ +function nfdCodePoints(cps: Iterable): number[] { + const out: number[] = []; + for (const cp of cps) decomposeInto(cp, out); + // Canonical ordering: stable insertion sort of each run of non-starters. + for (let i = 1; i < out.length; i++) { + const cc = combiningClass(out[i]!); + if (cc === 0) continue; + let j = i; + while (j > 0 && combiningClass(out[j - 1]!) > cc) { + [out[j - 1], out[j]] = [out[j]!, out[j - 1]!]; + j--; + } + } + return out; +} + +function composePair(a: number, b: number): number | undefined { + const l = a - L_BASE, v = b - V_BASE; + if (l >= 0 && l < L_COUNT && v >= 0 && v < V_COUNT) return S_BASE + (l * V_COUNT + v) * T_COUNT; + const s = a - S_BASE, t = b - T_BASE; + if (s >= 0 && s < S_COUNT && s % T_COUNT === 0 && t > 0 && t < T_COUNT) return a + t; + return compositions.get(pairKey(a, b)); +} + +function nfcCodePoints(cps: Iterable): number[] { + const d = nfdCodePoints(cps); + if (d.length === 0) return d; + const out = [d[0]!]; + let starterPos = 0; + let lastClass = combiningClass(d[0]!) === 0 ? 0 : 256; + for (let i = 1; i < d.length; i++) { + const ch = d[i]!; + const chClass = combiningClass(ch); + const composite = composePair(out[starterPos]!, ch); + if (composite !== undefined && (lastClass < chClass || lastClass === 0)) { + out[starterPos] = composite; + continue; + } + if (chClass === 0) starterPos = out.length; + lastClass = chClass; + out.push(ch); + } + return out; +} + +const codePoints = (s: string): number[] => Array.from(s, (ch) => ch.codePointAt(0)!); +export function nfd(s: string): string { + return String.fromCodePoint(...nfdCodePoints(codePoints(s))); +} + +export function nfc(s: string): string { + return String.fromCodePoint(...nfcCodePoints(codePoints(s))); +} + +export function isNfc(s: string): boolean { + return nfc(s) === s; +} + +/** Full case folding (statuses C and F), code point by code point. */ +export function fold(s: string): string { + const out: number[] = []; + for (const cp of codePoints(s)) { + const mapped = folding.get(cp); + if (mapped === undefined) out.push(cp); + else out.push(...mapped); + } + return String.fromCodePoint(...out); +} diff --git a/packages/skill-tree/src/zip-reader.ts b/packages/skill-tree/src/zip-reader.ts new file mode 100644 index 0000000..d360735 --- /dev/null +++ b/packages/skill-tree/src/zip-reader.ts @@ -0,0 +1,147 @@ +/** + * Zip reader for `agentkit.skill-tree/v1` (schemas 2.1). The central + * directory is read first; the local entries must be exactly its entries, + * contiguous from offset 0 up to the central directory. Content is inflated + * and hashed as it streams, then checked against the central CRC-32. + */ +import { asTreeError, decompress, readFailed } from "./byte-source"; +import { EntryCollector, decodeName } from "./entry-collector"; +import { ERROR_CODES, treeError } from "./errors"; +import type { TreeManifest } from "./serialize"; +import { LIMITS, headerMode } from "./tree"; +import type { TreeLimits } from "./tree"; +import { + crc32, + parseDescriptor, + readAt, + readCentralDirectory, + readDirectoryEnd, + readLocalHeader, + toRandomAccess, +} from "./zip-records"; +import type { CentralEntry, LocalHeader, RandomAccessSource, Sizes } from "./zip-records"; + +const CHUNK = 64 * 1024; +const S_IFMT = 0o170000, S_IFREG = 0o100000, S_IFDIR = 0o040000; +const UNIX_HOST = 3; + +const sameBytes = (a: Uint8Array, b: Uint8Array) => a.length === b.length && a.every((x, i) => x === b[i]); + +/** Header agreement on CRC-32 and sizes (schemas 2.1); returns a disagreement or undefined. */ +function sizesDisagree(local: LocalHeader, central: CentralEntry, descriptor: Sizes | null): string | undefined { + const keys = ["crc", "csize", "usize"] as const; + if (central.flags & 0x8) { + if (descriptor === null) return "data descriptor is malformed"; + if (keys.some((k) => local[k] !== 0 && local[k] !== descriptor[k])) return "local header disagrees with its data descriptor"; + if (keys.some((k) => descriptor[k] !== central[k])) return "data descriptor disagrees with the central directory"; + return undefined; + } + return keys.some((k) => local[k] !== central[k]) ? "local header disagrees with the central directory" : undefined; +} + +function entryFault(central: CentralEntry, local: LocalHeader): string | undefined { + if (central.fault !== undefined || local.fault !== undefined) return central.fault ?? local.fault; + if ((central.flags | local.flags) & 0x41) return "entry is encrypted"; + if ((central.flags & 0x8) !== (local.flags & 0x8)) return "local header and central directory disagree on the data descriptor flag"; + if (central.method !== local.method) return "local header and central directory disagree on the method"; + if (central.method !== 0 && central.method !== 8) return `compression method ${central.method} is not stored or deflate`; + const type = (central.externalAttrs >>> 16) & S_IFMT; + if (central.madeBy >> 8 !== UNIX_HOST || (type !== S_IFREG && type !== S_IFDIR)) { + return "entry lacks Unix attributes of a regular file or directory"; + } + return undefined; +} + +async function* rawData(src: RandomAccessSource, start: number, length: number): AsyncGenerator { + for (let at = 0; at < length; at += CHUNK) yield await readAt(src, start + at, Math.min(CHUNK, length - at)); +} + +/** Content of an entry, inflated when deflated, with its CRC-32 and size checked at the end. */ +async function* content(src: RandomAccessSource, central: CentralEntry, dataStart: number, verify: boolean): AsyncGenerator { + const raw = rawData(src, dataStart, central.csize); + const data = central.method === 8 ? decompress(raw, "deflate-raw") : raw; + let crc = 0; + let size = 0; + for await (const chunk of data) { + crc = crc32(chunk, crc); + size += chunk.length; + yield chunk; + } + if (verify && (crc !== central.crc || size !== central.usize)) throw readFailed("zip entry data does not match its CRC-32 or size"); +} + +async function readEntries(src: RandomAccessSource, collector: EntryCollector, limits: TreeLimits): Promise { + const dir = await readDirectoryEnd(src); + if (dir.entries > limits.maxEntries) { + throw treeError(ERROR_CODES.limitExceeded, "", `archive has ${dir.entries} entries, more than ${limits.maxEntries}`); + } + const central = (await readCentralDirectory(src, dir)).sort((a, b) => a.localOffset - b.localOffset); + let archiveFault: string | undefined; + let pos = 0; + for (let i = 0; i < central.length; i++) { + const c = central[i]!; + collector.present(); + const name = decodeName(c.name); + if (c.localOffset !== pos) archiveFault ??= `bytes before or between local entries at offset ${pos}`; + const local = await readLocalHeader(src, c.localOffset, dir.cdOffset); + if (local === null || !sameBytes(local.name, c.name)) { + archiveFault ??= `no local entry ${JSON.stringify(name.path)} at offset ${c.localOffset}`; + collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: "", size: 0, sha256: "", kind: "special", reason: archiveFault }); + continue; + } + const dataEnd = local.dataStart + c.csize; + const nextStart = central[i + 1]?.localOffset ?? dir.cdOffset; + let fault = entryFault(c, local); + let descriptor: Sizes | null = null; + if (dataEnd > dir.cdOffset) { + archiveFault ??= `entry ${JSON.stringify(name.path)} data overruns the central directory`; + fault ??= archiveFault; + } else if (c.flags & 0x8) { + const length = nextStart - dataEnd; + descriptor = [12, 16, 20, 24].includes(length) ? parseDescriptor(await readAt(src, dataEnd, length)) : null; + pos = descriptor === null ? dataEnd : nextStart; + } else { + pos = dataEnd; + } + fault ??= sizesDisagree(local, c, descriptor); + const type = (c.externalAttrs >>> 16) & S_IFMT; + const base = { path: name.path, utf8Valid: name.utf8Valid, ...(fault === undefined ? {} : { reason: fault }) }; + if (type === S_IFDIR && fault === undefined) { + collector.add({ ...base, mode: "", size: 0, sha256: "", kind: "directory" }); + continue; + } + if (dataEnd > dir.cdOffset) { + collector.add({ ...base, mode: "", size: 0, sha256: "", kind: "special" }); + continue; + } + // Header agreement comes first; only agreeing entries are checked against their CRC-32. + const hashed = await collector.hashFile(name.path, content(src, c, local.dataStart, fault === undefined)); + collector.add({ ...base, mode: headerMode(c.externalAttrs >>> 16), ...hashed, kind: "regular" }); + } + if (pos !== dir.cdOffset) archiveFault ??= "bytes between the last local entry and the central directory"; + if (archiveFault !== undefined) { + collector.add({ path: "", mode: "", size: 0, sha256: "", kind: "special", reason: `zip archive is not contiguous: ${archiveFault}` }); + } +} + +export interface ZipReadOptions { + /** Test hook: smaller limits. */ + limits?: TreeLimits; +} + +/** + * Reads a zip archive into a validated tree manifest. Throws a + * `SkillTreeError`: unparseable records and corrupt data are + * `tree.read_failed`, header disagreements and non-contiguous entries are + * `tree.unsupported_entry`. + */ +export async function readZipTree(source: Uint8Array | Blob | RandomAccessSource, options: ZipReadOptions = {}): Promise { + const limits = options.limits ?? LIMITS; + const collector = new EntryCollector(limits); + try { + await readEntries(toRandomAccess(source), collector, limits); + } catch (err) { + throw asTreeError(err); + } + return collector.build(); +} diff --git a/packages/skill-tree/src/zip-records.ts b/packages/skill-tree/src/zip-records.ts new file mode 100644 index 0000000..fe0e556 --- /dev/null +++ b/packages/skill-tree/src/zip-records.ts @@ -0,0 +1,200 @@ +/** + * Zip record parsing for the skill-tree zip reader (schemas 2.1): end of + * central directory (with zip64), central directory entries, local headers + * and data descriptors. A record that is missing or cannot be parsed throws + * `tree.read_failed`; disagreements are judged by the reader. + */ +import { readFailed } from "./byte-source"; + +/** Random access to archive bytes, so the central directory can be read first. */ +export interface RandomAccessSource { + readonly size: number; + read(offset: number, length: number): Promise; +} + +export function toRandomAccess(source: Uint8Array | Blob | RandomAccessSource): RandomAccessSource { + if (source instanceof Uint8Array) { + return { size: source.length, read: async (offset, length) => source.subarray(offset, offset + length) }; + } + if (typeof Blob !== "undefined" && source instanceof Blob) { + return { size: source.size, read: async (o, l) => new Uint8Array(await source.slice(o, o + l).arrayBuffer()) }; + } + return source as RandomAccessSource; +} + +export async function readAt(src: RandomAccessSource, offset: number, length: number): Promise { + if (offset < 0 || length < 0 || offset + length > src.size) throw readFailed(`zip read past the end at ${offset}`); + const bytes = await src.read(offset, length); + if (bytes.length !== length) throw readFailed(`zip read returned ${bytes.length} of ${length} bytes`); + return bytes; +} + +const view = (b: Uint8Array) => new DataView(b.buffer, b.byteOffset, b.byteLength); +const u16 = (b: Uint8Array, o: number) => view(b).getUint16(o, true); +const u32 = (b: Uint8Array, o: number) => view(b).getUint32(o, true); +function u64(b: Uint8Array, o: number): number { + const value = view(b).getBigUint64(o, true); + if (value > BigInt(Number.MAX_SAFE_INTEGER)) throw readFailed("zip64 value overflows"); + return Number(value); +} + +export const MAX32 = 0xffffffff; +const SIG_LOCAL = 0x04034b50, SIG_CENTRAL = 0x02014b50, SIG_EOCD = 0x06054b50; +const SIG_EOCD64 = 0x06064b50, SIG_LOCATOR64 = 0x07064b50, SIG_DESCRIPTOR = 0x08074b50; +/** Reading a larger central directory is refused rather than buffered. */ +const MAX_CENTRAL_DIRECTORY_BYTES = 64 * 1024 * 1024; + +export interface Directory { + entries: number; + cdOffset: number; + cdSize: number; +} + +/** Finds the end of central directory record (and the zip64 record when it is used), like Go archive/zip. */ +export async function readDirectoryEnd(src: RandomAccessSource): Promise { + const tailStart = Math.max(0, src.size - (22 + 0xffff)); + const tail = await readAt(src, tailStart, src.size - tailStart); + let at = -1; + for (let i = tail.length - 22; i >= 0; i--) { + if (u32(tail, i) === SIG_EOCD && i + 22 + u16(tail, i + 20) <= tail.length) { + at = i; + break; + } + } + if (at < 0) throw readFailed("zip end of central directory record not found"); + if (u16(tail, at + 4) !== 0 || u16(tail, at + 6) !== 0) throw readFailed("multi-disk zip archives are not supported"); + let dir: Directory = { entries: u16(tail, at + 10), cdSize: u32(tail, at + 12), cdOffset: u32(tail, at + 16) }; + let dirEnd = tailStart + at; + if ((dir.entries === 0xffff || dir.cdSize === MAX32 || dir.cdOffset === MAX32) && dirEnd >= 20) { + const locator = await readAt(src, dirEnd - 20, 20); + if (u32(locator, 0) === SIG_LOCATOR64) { + const offset = u64(locator, 8); + const record = await readAt(src, offset, 56); + if (u32(record, 0) !== SIG_EOCD64) throw readFailed("bad zip64 end of central directory signature"); + dir = { entries: u64(record, 32), cdSize: u64(record, 40), cdOffset: u64(record, 48) }; + dirEnd = offset; + } + } + if (dir.cdOffset + dir.cdSize > dirEnd) throw readFailed("zip central directory overlaps its end record"); + if (dir.cdSize > MAX_CENTRAL_DIRECTORY_BYTES) throw readFailed("zip central directory is too large"); + return dir; +} + +export interface Sizes { + crc: number; + csize: number; + usize: number; +} + +export interface CentralEntry extends Sizes { + name: Uint8Array; + madeBy: number; + flags: number; + method: number; + externalAttrs: number; + localOffset: number; + /** Set when a 0xFFFFFFFF field has no zip64 extra value. */ + fault?: string; +} + +/** Replaces 0xFFFFFFFF fields, in order, with the zip64 extra (0x0001) values. */ +function applyZip64(extra: Uint8Array, fields: number[]): string | undefined { + let values: Uint8Array | undefined; + for (let p = 0; p + 4 <= extra.length; ) { + const id = u16(extra, p); + const len = u16(extra, p + 2); + if (p + 4 + len > extra.length) throw readFailed("zip extra field overruns its record"); + if (id === 0x0001) values = extra.subarray(p + 4, p + 4 + len); + p += 4 + len; + } + let next = 0; + for (let i = 0; i < fields.length; i++) { + if (fields[i] !== MAX32) continue; + if (values === undefined || next + 8 > values.length) return "a 0xFFFFFFFF field has no zip64 extra value"; + fields[i] = u64(values, next); + next += 8; + } + return undefined; +} + +export async function readCentralDirectory(src: RandomAccessSource, dir: Directory): Promise { + const cd = await readAt(src, dir.cdOffset, dir.cdSize); + const entries: CentralEntry[] = []; + let p = 0; + for (let i = 0; i < dir.entries; i++) { + if (p + 46 > cd.length || u32(cd, p) !== SIG_CENTRAL) throw readFailed("bad zip central directory record"); + const nameLen = u16(cd, p + 28), extraLen = u16(cd, p + 30), commentLen = u16(cd, p + 32); + const end = p + 46 + nameLen + extraLen + commentLen; + if (end > cd.length) throw readFailed("zip central directory record overruns the directory"); + const fields = [u32(cd, p + 24), u32(cd, p + 20), u32(cd, p + 42)]; // usize, csize, offset + const fault = applyZip64(cd.subarray(p + 46 + nameLen, p + 46 + nameLen + extraLen), fields); + entries.push({ + name: cd.subarray(p + 46, p + 46 + nameLen), + madeBy: u16(cd, p + 4), + flags: u16(cd, p + 8), + method: u16(cd, p + 10), + crc: u32(cd, p + 16), + usize: fields[0]!, + csize: fields[1]!, + localOffset: fields[2]!, + externalAttrs: u32(cd, p + 38), + ...(fault === undefined ? {} : { fault }), + }); + p = end; + } + return entries; +} + +export interface LocalHeader extends Sizes { + name: Uint8Array; + flags: number; + method: number; + /** Offset of the entry data. */ + dataStart: number; + fault?: string; +} + +/** Reads the local header at `offset`, or returns null when no local header signature is there. */ +export async function readLocalHeader(src: RandomAccessSource, offset: number, limit: number): Promise { + if (offset + 30 > limit) return null; + const fixed = await readAt(src, offset, 30); + if (u32(fixed, 0) !== SIG_LOCAL) return null; + const nameLen = u16(fixed, 26), extraLen = u16(fixed, 28); + if (offset + 30 + nameLen + extraLen > limit) return null; + const rest = await readAt(src, offset + 30, nameLen + extraLen); + const fields = [u32(fixed, 22), u32(fixed, 18)]; // usize, csize + const fault = applyZip64(rest.subarray(nameLen), fields); + return { + name: rest.subarray(0, nameLen), + flags: u16(fixed, 6), + method: u16(fixed, 8), + crc: u32(fixed, 14), + usize: fields[0]!, + csize: fields[1]!, + dataStart: offset + 30 + nameLen + extraLen, + ...(fault === undefined ? {} : { fault }), + }; +} + +/** Parses a data descriptor whose length (12, 16, 20 or 24) the contiguity rule fixed; null when malformed. */ +export function parseDescriptor(bytes: Uint8Array): Sizes | null { + const signed = bytes.length === 16 || bytes.length === 24; + if (signed && u32(bytes, 0) !== SIG_DESCRIPTOR) return null; + const b = signed ? bytes.subarray(4) : bytes; + if (b.length === 12) return { crc: u32(b, 0), csize: u32(b, 4), usize: u32(b, 8) }; + if (b.length === 20) return { crc: u32(b, 0), csize: u64(b, 4), usize: u64(b, 12) }; + return null; +} + +const CRC_TABLE = Uint32Array.from({ length: 256 }, (_, n) => { + let c = n; + for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; + return c >>> 0; +}); + +/** Incremental CRC-32 (IEEE): pass the previous value to continue. */ +export function crc32(data: Uint8Array, previous = 0): number { + let c = ~previous >>> 0; + for (const byte of data) c = CRC_TABLE[(c ^ byte) & 0xff]! ^ (c >>> 8); + return ~c >>> 0; +} diff --git a/packages/skill-tree/test/identity-vectors.test.ts b/packages/skill-tree/test/identity-vectors.test.ts new file mode 100644 index 0000000..640f817 --- /dev/null +++ b/packages/skill-tree/test/identity-vectors.test.ts @@ -0,0 +1,132 @@ +import { describe, expect, it } from "vitest"; +import { + IDENTITY_PATTERN, + SkillTreeError, + checkAlias, + checkDirectoryAlias, + checkPublisher, + directoryAliasKey, + frontmatterExposure, + kitIdentity, + skillFileExposure, + trustOf, + validateIdentity, +} from "../src/index"; +import { fixtureBytes } from "./vector-helpers"; + +interface IdentityVectors { + schema: string; + spec: string; + notes: string[]; + pattern: string; + kitMapping: Array<{ kit: string; dir: string; identity?: string; portableAlias?: string; error?: string }>; + valid: string[]; + invalid: Array<{ value: string; error: string }>; + provenance: Array<{ + identity: string; + provider: string; + origin?: string; + verified?: boolean; + overlay?: boolean; + expect: { trust?: string; error?: string }; + }>; + aliases: Array<{ identity: string; alias: string; error: string | null }>; + directoryAliases: Array<{ identity: string; alias: string; error: string | null; groupKey?: string }>; + directoryAliasCollisions: Array<{ aliases: string[]; collide: boolean }>; + exposure: Array<{ frontmatter?: string; file?: string; exposure: string; warning: boolean }>; +} + +const v = JSON.parse(fixtureBytes("vectors/identity-v1-vectors.json").toString("utf8")) as IdentityVectors; + +/** The contract code a call throws, or null when it succeeds. */ +function codeOf(run: () => unknown): string | null { + try { + run(); + return null; + } catch (err) { + if (err instanceof SkillTreeError) return err.code; + throw err; + } +} + +describe("identity-v1 vectors (vendored unedited from AgentKit)", () => { + it("is the expected vector file with every section", () => { + expect(v.schema).toBe("agentkit.identity-vectors/v1"); + // RegExp.source escapes "/", so compare the compiled patterns. + expect(new RegExp(v.pattern).source).toBe(IDENTITY_PATTERN.source); + for (const section of [v.kitMapping, v.valid, v.invalid, v.provenance, v.aliases, v.directoryAliases, v.directoryAliasCollisions, v.exposure]) { + expect(section.length).toBeGreaterThan(0); + } + }); + + it("maps kit skill directories", () => { + for (const c of v.kitMapping) { + if (c.error !== undefined) expect(codeOf(() => kitIdentity(c.dir)), c.dir).toBe(c.error); + else expect(kitIdentity(c.dir), c.dir).toEqual({ identity: c.identity, alias: c.portableAlias }); + } + }); + + it("validates identities", () => { + for (const id of v.valid) expect(codeOf(() => validateIdentity(id)), id).toBeNull(); + for (const c of v.invalid) { + expect(codeOf(() => validateIdentity(c.value)), c.value).toBe(c.error); + expect(codeOf(() => checkPublisher(c.value, "kit")), c.value).toBe(c.error); + } + }); + + it("derives trust or rejects provenance in contract order", () => { + for (const c of v.provenance) { + const p = { provider: c.provider, origin: c.origin ?? "", verified: c.verified ?? false, overlay: c.overlay ?? false }; + const label = `${c.identity} ${JSON.stringify(p)}`; + if (c.expect.error !== undefined) expect(codeOf(() => trustOf(c.identity, p)), label).toBe(c.expect.error); + else expect(trustOf(c.identity, p), label).toBe(c.expect.trust); + } + }); + + it("checks invocation aliases", () => { + for (const c of v.aliases) expect(codeOf(() => checkAlias(c.identity, c.alias)), `${c.identity} ${c.alias}`).toBe(c.error); + }); + + it("checks directory aliases and their group keys", () => { + for (const c of v.directoryAliases) { + expect(codeOf(() => checkDirectoryAlias(c.identity, c.alias)), `${c.identity} ${c.alias}`).toBe(c.error); + if (c.error === null) expect(directoryAliasKey(c.alias)).toBe(c.groupKey); + } + for (const c of v.directoryAliasCollisions) { + const [a = "", b = ""] = c.aliases; + expect(directoryAliasKey(a) === directoryAliasKey(b), c.aliases.join(" ")).toBe(c.collide); + } + }); + + it("derives exposure from frontmatter and whole skill files", () => { + for (const c of v.exposure) { + expect((c.frontmatter === undefined) !== (c.file === undefined)).toBe(true); + const got = c.frontmatter !== undefined ? frontmatterExposure(c.frontmatter) : skillFileExposure(c.file ?? ""); + expect(got, JSON.stringify(c.frontmatter ?? c.file)).toEqual({ exposure: c.exposure, warning: c.warning }); + } + }); +}); + +describe("identity rules beyond the vectors", () => { + it("never folds look-alikes into reserved aliases", () => { + for (const alias of ["aK-plan", "аk-plan", "plan-é", "ık-plan", "/аk:plan"]) { + expect(codeOf(() => checkAlias("@evil/plan", alias)), alias).toBe("identity.invalid"); + expect(codeOf(() => checkAlias("@agentkit/plan", alias)), alias).toBe("identity.invalid"); + } + }); + + it("reserves ak- and ak: segments after leading / and $", () => { + for (const alias of ["$AK:plan", "/AK:plan", "$ak-plan", "x/$ak-plan", "core/$$AK-plan", "a/b/Ak:c"]) { + expect(codeOf(() => checkAlias("@acme/plan", alias)), alias).toBe("identity.reserved_alias"); + } + for (const alias of ["a$ak:plan", "x/bak-plan", "akx/plan", "ak/plan"]) { + expect(codeOf(() => checkAlias("@acme/plan", alias)), alias).toBeNull(); + } + }); + + it("checks the provider before the reserved publisher", () => { + expect(codeOf(() => trustOf("@agentkit/plan", { provider: "npm" }))).toBe("identity.invalid"); + expect(codeOf(() => trustOf("@agentkit/plan", { provider: "skillx", verified: true }))).toBe("identity.reserved_publisher"); + expect(codeOf(() => checkPublisher("@agentkit2/plan", "skillx"))).toBeNull(); + }); +}); diff --git a/packages/skill-tree/test/path-fuzz.test.ts b/packages/skill-tree/test/path-fuzz.test.ts new file mode 100644 index 0000000..a937304 --- /dev/null +++ b/packages/skill-tree/test/path-fuzz.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it } from "vitest"; +import { decodeName } from "../src/entry-collector"; +import { buildTree, frontmatterExposure, validatePath } from "../src/index"; +import { errorCodeOf } from "./vector-helpers"; + +const PATH_CODES = new Set(["tree.unsafe_path", "tree.non_nfc_path"]); + +/** Deterministic xorshift32, so a failure reproduces from the printed seed. */ +function rng(seed: number): () => number { + let s = seed >>> 0 || 1; + return () => { + s ^= s << 13; + s ^= s >>> 17; + s ^= s << 5; + return (s >>> 0) / 0x100000000; + }; +} + +const ALPHABET = ["a", "A", "/", ".", "..", "~1", " ", "\\", ":", "\u0000", "é", "é", "K", "​", "\ud800", "CON", "ß", "\u{1f600}", ".ak-tmp.", "$"]; + +describe("path validation never throws", () => { + it("classifies random byte names", () => { + const next = rng(0x5eed); + for (let i = 0; i < 20_000; i++) { + const bytes = Uint8Array.from({ length: Math.floor(next() * 40) }, () => Math.floor(next() * 256)); + const name = decodeName(bytes); + const result = validatePath(name.path); + if (result !== null && !PATH_CODES.has(result.code)) expect.fail(`seed 0x5eed #${i}: ${result.code}`); + } + }); + + it("classifies random token names and agrees with buildTree", async () => { + const next = rng(0xc0ffee); + for (let i = 0; i < 5_000; i++) { + const path = Array.from({ length: 1 + Math.floor(next() * 6) }, () => ALPHABET[Math.floor(next() * ALPHABET.length)]).join(""); + const result = validatePath(path); + if (result !== null && !PATH_CODES.has(result.code)) expect.fail(`${JSON.stringify(path)}: ${result.code}`); + const entry = { path, mode: "100644", size: 1, sha256: "0".repeat(64), kind: "regular" as const }; + const code = await errorCodeOf(() => buildTree([entry])); + if (result !== null) expect(code, JSON.stringify(path)).toBe(result.code); + // A valid path still fails as a whole tree only when it is noise (empty tree). + else expect(code === null || code === "tree.empty", JSON.stringify(path)).toBe(true); + } + }); +}); + +describe("frontmatter exposure never throws", () => { + it.each([ + ["", "AUTO", false], + ["user-invocable: false", "INTERNAL", false], + ["disable-model-invocation: TRUE", "EXPLICIT", false], + // A quoted value is a string, not a boolean: it is ignored without a warning. + ["user-invocable: 'false'", "AUTO", false], + ["user-invocable: !!bool false", "AUTO", true], + ["user-invocable: &a false", "AUTO", true], + ["user-invocable: false\nuser-invocable: true", "AUTO", true], + ["- a\n- b", "AUTO", true], + ["key: [unclosed", "AUTO", true], + ] as const)("%j", (text, exposure, warning) => { + expect(frontmatterExposure(text)).toEqual({ exposure, warning }); + }); + + it("handles random input", () => { + const next = rng(0xfeed); + const pieces = ["user-invocable", "disable-model-invocation", ":", " ", "\n", "true", "false", "!!", "&", "*", "'", '"', "[", "{", "- ", "#"]; + for (let i = 0; i < 5_000; i++) { + const text = Array.from({ length: Math.floor(next() * 12) }, () => pieces[Math.floor(next() * pieces.length)]).join(""); + const got = frontmatterExposure(text); + expect(["AUTO", "EXPLICIT", "INTERNAL"]).toContain(got.exposure); + } + }); +}); diff --git a/packages/skill-tree/test/provenance.test.ts b/packages/skill-tree/test/provenance.test.ts new file mode 100644 index 0000000..c38bb59 --- /dev/null +++ b/packages/skill-tree/test/provenance.test.ts @@ -0,0 +1,104 @@ +/** + * Pins the vendored fixtures and keeps the generated Unicode tables in sync + * with their pinned inputs (the AgentKit CaseFolding file and the Go tables + * dump), so table drift fails here instead of silently changing digests. + */ +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; +import { UNICODE_VERSION, caseFoldEntries, combiningClass, isAssigned, isFormat, nfc, nfd } from "../src/unicode-15"; +import { fixtureBytes, sha256 } from "./vector-helpers"; + +const PINS: Record = { + "vectors/skill-tree-v1-vectors.json": "8eb46f1b8bec49cace740b75614f28f8fb4a6fc266fecfcd7e3d6892f28f3172", + "vectors/identity-v1-vectors.json": "1ab9e013c229d78871abd60e3cd3bf26fcfd0e6067d98dcdd79b4f6bcc1daefb", + "ucd/CaseFolding-15.0.0.txt": "cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7", +}; +const GO_TABLES_SHA256 = "baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5"; +const MAX_CP = 0x10ffff; + +interface GoTables { + unicodeVersion: string; + normVersion: string; + assigned: Array<[number, number]>; + format: Array<[number, number]>; + combiningClass: Array<[number, number]>; + composites: number[]; +} + +const goBytes = readFileSync(fileURLToPath(new URL("../scripts/unicode-15.0.0-go.json", import.meta.url))); +const go = JSON.parse(goBytes.toString("utf8")) as GoTables; + +function rangeSet(ranges: Array<[number, number]>): Uint8Array { + const set = new Uint8Array(MAX_CP + 1); + for (const [lo, hi] of ranges) set.fill(1, lo, hi + 1); + return set; +} + +const isSurrogate = (cp: number) => cp >= 0xd800 && cp <= 0xdfff; + +describe("fixture provenance", () => { + it.each(Object.entries(PINS))("%s is the pinned upstream file", (path, pin) => { + expect(sha256(fixtureBytes(path))).toBe(pin); + }); + + it("the Go tables dump is the pinned Unicode 15.0.0 input", () => { + expect(sha256(goBytes)).toBe(GO_TABLES_SHA256); + expect([go.unicodeVersion, go.normVersion, UNICODE_VERSION]).toEqual(["15.0.0", "15.0.0", "15.0.0"]); + }); +}); + +describe("generated tables stay in sync with their inputs", () => { + it("case folding equals CaseFolding.txt statuses C and F", () => { + const want = new Map(); + for (const line of fixtureBytes("ucd/CaseFolding-15.0.0.txt").toString("utf8").split("\n")) { + const fields = line.replace(/#.*/, "").split(";").map((f) => f.trim()); + if (fields.length < 3 || (fields[1] !== "C" && fields[1] !== "F")) continue; + want.set(parseInt(fields[0]!, 16), fields[2]!.split(" ").map((h) => parseInt(h, 16))); + } + expect(want.size).toBeGreaterThan(1400); + expect(new Map(caseFoldEntries())).toEqual(want); + }); + + it("general categories match the Go tables for every code point", () => { + const assigned = rangeSet(go.assigned); + const format = rangeSet(go.format); + for (let cp = 0; cp <= MAX_CP; cp++) { + if (isAssigned(cp) !== (assigned[cp] === 1)) expect.fail(`assigned U+${cp.toString(16)}`); + if (isFormat(cp) !== (format[cp] === 1)) expect.fail(`format U+${cp.toString(16)}`); + } + }); + + it("combining classes match the Go tables", () => { + const want = new Map(go.combiningClass); + for (let cp = 0; cp <= MAX_CP; cp++) { + if (combiningClass(cp) !== (want.get(cp) ?? 0)) expect.fail(`ccc U+${cp.toString(16)}`); + } + }); +}); + +describe("normalization agrees with the runtime on Unicode 15.0.0 characters", () => { + it("NFD and NFC of every assigned code point", () => { + let checked = 0; + for (let cp = 0; cp <= MAX_CP; cp++) { + if (!isAssigned(cp) || isSurrogate(cp)) continue; + const ch = String.fromCodePoint(cp); + if (nfd(ch) !== ch.normalize("NFD")) expect.fail(`NFD U+${cp.toString(16)}`); + if (nfc(ch) !== ch.normalize("NFC")) expect.fail(`NFC U+${cp.toString(16)}`); + checked++; + } + expect(checked).toBeGreaterThan(149_000); + }); + + it("composes, reorders and blocks sequences", () => { + const samples = [ + "é", "Ǻ", "ḍ̇", "q̣̇", "각", "각", + "ą́", "Ą́", "אַּ", "क़", "Å", "Ω", + "ཱི", "̈́", "à̛̀̕", "Ą̊", "ᅡᆨ", "́e", + ]; + for (const s of samples) { + expect(nfd(s), JSON.stringify(s)).toBe(s.normalize("NFD")); + expect(nfc(s), JSON.stringify(s)).toBe(s.normalize("NFC")); + } + }); +}); diff --git a/packages/skill-tree/test/tar-reader.test.ts b/packages/skill-tree/test/tar-reader.test.ts new file mode 100644 index 0000000..ae2826b --- /dev/null +++ b/packages/skill-tree/test/tar-reader.test.ts @@ -0,0 +1,153 @@ +import { once } from "node:events"; +import { createGzip, gzipSync } from "node:zlib"; +import { describe, expect, it } from "vitest"; +import { buildTree, readTarTree, readZipTree } from "../src/index"; +import { tarBytes, tarStream } from "./tar-writer"; +import type { TarSpec } from "./tar-writer"; +import { zipBytes } from "./zip-writer"; +import { errorCodeOf, sha256 } from "./vector-helpers"; + +const enc = new TextEncoder(); +const SKILL = enc.encode("---\nname: demo\ndescription: Demo.\n---\n"); + +function file(name: string, data: Uint8Array | string = "x\n", mode = 0o644): TarSpec { + return { name: enc.encode(name), typeflag: "0", mode, data: typeof data === "string" ? enc.encode(data) : data }; +} + +const skill = file("SKILL.md", SKILL); + +/** Gzips a stream without holding its uncompressed bytes. */ +async function gzipStream(source: AsyncIterable): Promise { + const parts: Buffer[] = []; + const gz = createGzip(); + const drained = (async () => { + for await (const chunk of gz) parts.push(chunk as Buffer); + })(); + for await (const chunk of source) if (!gz.write(chunk)) await once(gz, "drain"); + gz.end(); + await drained; + return Buffer.concat(parts); +} + +async function tarCode(specs: TarSpec[]): Promise { + return errorCodeOf(() => readTarTree(tarStream(specs))); +} + +describe("tar reader rejects unsafe entries", () => { + it.each([ + ["zip-slip parent segment", [file("../evil.md")], "tree.unsafe_path"], + ["nested parent segment", [file("refs/../../evil.md")], "tree.unsafe_path"], + ["absolute path", [file("/etc/passwd")], "tree.unsafe_path"], + ["backslash", [file("refs\\x.md")], "tree.unsafe_path"], + ["Windows reserved name", [file("CON.md")], "tree.unsafe_path"], + ["8.3 short name", [file("PROGRA~1/x.md")], "tree.unsafe_path"], + ["trailing dot", [file("notes.")], "tree.unsafe_path"], + ["NFD name", [file("café.md")], "tree.non_nfc_path"], + ["Kelvin sign (NFC maps it to K)", [file("K.md")], "tree.non_nfc_path"], + ["full case-fold collision", [file("STRASSE.md"), file("straße.md")], "tree.case_collision"], + ["simple case collision", [file("Refs/a.md"), file("refs/b.md")], "tree.case_collision"], + ["symbolic link", [{ name: enc.encode("link"), typeflag: "2", mode: 0o777 }], "tree.unsupported_entry"], + ["hard link", [{ name: enc.encode("hard"), typeflag: "1", mode: 0o644 }], "tree.unsupported_entry"], + ["FIFO", [{ name: enc.encode("pipe"), typeflag: "6", mode: 0o644 }], "tree.unsupported_entry"], + ["contiguous file", [{ ...file("big.bin"), typeflag: "7" }], "tree.unsupported_entry"], + ["sparse PAX file", [{ ...file("sparse.bin"), pax: { "GNU.sparse.major": "1", "GNU.sparse.minor": "0" } }], "tree.unsupported_entry"], + ["setuid file", [file("run.sh", "#!/bin/sh\n", 0o4755)], "tree.unsupported_entry"], + ["group-writable file", [file("w.md", "x\n", 0o664)], "tree.unsupported_entry"], + ] as const)("%s", async (_name, specs, code) => { + expect(await tarCode([skill, ...specs])).toBe(code); + }); + + it("rejects a tree with no files", async () => { + expect(await tarCode([{ name: enc.encode("empty/"), typeflag: "5", mode: 0o755 }])).toBe("tree.empty"); + }); +}); + +describe("tar reader fails closed on damaged archives", () => { + it("rejects a truncated archive", async () => { + const bytes = await tarBytes([skill, file("refs/a.md", new Uint8Array(4000).fill(97))]); + expect(await errorCodeOf(() => readTarTree(bytes.subarray(0, 2048)))).toBe("tree.read_failed"); + }); + + it("rejects a header with a bad checksum", async () => { + const bytes = await tarBytes([skill]); + bytes[0] = bytes[0]! ^ 0x01; + expect(await errorCodeOf(() => readTarTree(bytes))).toBe("tree.read_failed"); + }); + + it("rejects a corrupt gzip stream", async () => { + const gz = gzipSync(await tarBytes([skill])); + gz[gz.length - 6] = gz[gz.length - 6]! ^ 0xff; + expect(await errorCodeOf(() => readTarTree(gz))).toBe("tree.read_failed"); + }); + + it("accepts an archive without the end-of-archive blocks", async () => { + const manifest = await readTarTree(await tarBytes([skill], false)); + expect(manifest.files.map((f) => f.path)).toEqual(["SKILL.md"]); + }); +}); + +describe("tar reader enforces limits while streaming", () => { + it("stops reading a file once it exceeds the per-file limit", async () => { + let pulled = 0; + const source = (async function* () { + for await (const chunk of tarStream([skill, { ...file("bomb.bin"), data: undefined, fill: { size: 64 << 20, byte: 0 } }])) { + pulled += chunk.length; + yield chunk; + } + })(); + expect(await errorCodeOf(() => readTarTree(source, { limits: { maxEntries: 10, maxFiles: 10, maxFileSize: 4 << 20, maxTreeSize: 8 << 20 } }))).toBe( + "tree.limit_exceeded", + ); + expect(pulled).toBeLessThan(8 << 20); + }); + + it("stops inflating a gzip bomb at the default limit", async () => { + // 512 MiB of zeros inflates from ~0.5 MB; the reader must stop near the 32 MiB file limit. + const gz = await gzipStream(tarStream([skill, { ...file("bomb.bin"), data: undefined, fill: { size: 512 << 20, byte: 0 } }])); + let consumed = 0; + const source = (async function* () { + for (let at = 0; at < gz.length; at += 1024) { + const chunk = gz.subarray(at, at + 1024); + consumed += chunk.length; + yield chunk; + } + })(); + expect(await errorCodeOf(() => readTarTree(source))).toBe("tree.limit_exceeded"); + expect(consumed).toBeLessThan(gz.length / 2); + }, 120_000); + + it("rejects more files than the file limit", async () => { + const specs = Array.from({ length: 5 }, (_, n) => file(`f${n}.md`)); + const limits = { maxEntries: 100, maxFiles: 4, maxFileSize: 1024, maxTreeSize: 4096 }; + expect(await errorCodeOf(() => readTarTree(tarStream(specs), { limits }))).toBe("tree.limit_exceeded"); + }); +}); + +describe("one tree, one digest", () => { + const files = [ + { name: "SKILL.md", data: SKILL, mode: 0o644 }, + { name: "scripts/run.sh", data: enc.encode("#!/bin/sh\necho hi\n"), mode: 0o755 }, + { name: "refs/été.md", data: enc.encode("summer\n"), mode: 0o644 }, + { name: "refs/z.md", data: new Uint8Array(70_000).fill(122), mode: 0o644 }, + ]; + + it("tar, tar.gz, zip and presented entries agree in any order", async () => { + const specs = files.map((f) => file(f.name, f.data, f.mode)); + const tar = await tarBytes(specs); + const reversed = await tarBytes([...specs].reverse()); + const zip = zipBytes(files.map((f, i) => ({ name: enc.encode(f.name), data: f.data, unixMode: 0o100000 | f.mode, method: i % 2 === 0 ? 8 : 0 }))); + const presented = buildTree( + files.map((f) => ({ path: f.name, mode: f.mode === 0o755 ? "100755" : "100644", size: f.data.length, sha256: sha256(f.data), kind: "regular" as const })), + ); + const digests = [ + (await readTarTree(tar)).digest, + (await readTarTree(reversed)).digest, + (await readTarTree(gzipSync(tar))).digest, + (await readTarTree(new Blob([gzipSync(tar)]).stream())).digest, + (await readZipTree(zip)).digest, + presented.digest, + ]; + expect(new Set(digests).size).toBe(1); + expect(digests[0]).toMatch(/^sha256:[0-9a-f]{64}$/); + }); +}); diff --git a/packages/skill-tree/test/tar-writer.ts b/packages/skill-tree/test/tar-writer.ts new file mode 100644 index 0000000..8ec6e2a --- /dev/null +++ b/packages/skill-tree/test/tar-writer.ts @@ -0,0 +1,94 @@ +/** + * Minimal streaming ustar/PAX writer for tests. Content can be given as bytes + * or as a size and fill byte, so limit vectors stream without large buffers. + */ +export interface TarSpec { + name: Uint8Array; + typeflag: string; + mode: number; + data?: Uint8Array; + fill?: { size: number; byte: number }; + /** PAX records for an `x` header before this entry, or the records of a `g` entry. */ + pax?: Record; +} + +const enc = new TextEncoder(); + +function octal(value: number, width: number): Uint8Array { + return enc.encode(value.toString(8).padStart(width - 1, "0") + "\0"); +} + +export function paxData(records: Record): Uint8Array { + const parts: Uint8Array[] = []; + for (const [key, raw] of Object.entries(records)) { + const value = typeof raw === "string" ? enc.encode(raw) : raw; + const body = enc.encode(` ${key}=`).length + value.length + 1; + let len = body + 1; + while (String(len).length + body !== len) len = String(len).length + body; + parts.push(enc.encode(`${len} ${key}=`), value, enc.encode("\n")); + } + return concat(parts); +} + +export function concat(parts: readonly Uint8Array[]): Uint8Array { + const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0)); + let at = 0; + for (const p of parts) { + out.set(p, at); + at += p.length; + } + return out; +} + +export function tarHeader(name: Uint8Array, typeflag: string, mode: number, size: number): Uint8Array { + const block = new Uint8Array(512); + block.set(name.subarray(0, 100), 0); + block.set(octal(mode, 8), 100); + block.set(octal(0, 8), 108); + block.set(octal(0, 8), 116); + block.set(octal(size, 12), 124); + block.set(octal(0, 12), 136); + block[156] = typeflag.charCodeAt(0); + block.set(enc.encode("ustar\u000000"), 257); + block.fill(0x20, 148, 156); + const sum = block.reduce((n, b) => n + b, 0); + block.set(octal(sum, 7), 148); + block[155] = 0x20; + return block; +} + +const pad = (size: number) => new Uint8Array((512 - (size % 512)) % 512); + +async function* fillChunks(size: number, byte: number): AsyncGenerator { + const block = new Uint8Array(1 << 20).fill(byte); + for (let left = size; left > 0; left -= block.length) yield block.subarray(0, Math.min(left, block.length)); +} + +/** Streams a tar archive of `specs`, closed by two zero blocks unless `trailer` is false. */ +export async function* tarStream(specs: readonly TarSpec[], trailer = true): AsyncGenerator { + for (const spec of specs) { + if (spec.typeflag === "g") { + const data = paxData(spec.pax ?? {}); + yield concat([tarHeader(spec.name, "g", 0o644, data.length), data, pad(data.length)]); + continue; + } + const records: Record = { ...(spec.pax ?? {}) }; + if (spec.name.length > 100 && records.path === undefined) records.path = spec.name; + if (Object.keys(records).length > 0) { + const data = paxData(records); + yield concat([tarHeader(enc.encode("PaxHeader"), "x", 0o644, data.length), data, pad(data.length)]); + } + const size = spec.data?.length ?? spec.fill?.size ?? 0; + yield tarHeader(spec.name, spec.typeflag, spec.mode, size); + if (spec.data !== undefined) yield spec.data; + else if (spec.fill !== undefined) yield* fillChunks(spec.fill.size, spec.fill.byte); + yield pad(size); + } + if (trailer) yield new Uint8Array(1024); +} + +export async function tarBytes(specs: readonly TarSpec[], trailer = true): Promise { + const parts: Uint8Array[] = []; + for await (const part of tarStream(specs, trailer)) parts.push(part.slice()); + return concat(parts); +} diff --git a/packages/skill-tree/test/tree-vectors.test.ts b/packages/skill-tree/test/tree-vectors.test.ts new file mode 100644 index 0000000..fd8ceef --- /dev/null +++ b/packages/skill-tree/test/tree-vectors.test.ts @@ -0,0 +1,127 @@ +import { describe, expect, it } from "vitest"; +import { SkillTreeError, buildTree, readTarTree, readZipTree, serializeTree } from "../src/index"; +import type { TreeManifest } from "../src/index"; +import { tarStream } from "./tar-writer"; +import type { TarSpec } from "./tar-writer"; +import { zipBytes } from "./zip-writer"; +import type { ZipSpec } from "./zip-writer"; +import { fileBytes, loadTreeVectors, rawName, synthPath, vectorEntries } from "./vector-helpers"; +import type { TreeVector, VectorFile } from "./vector-helpers"; + +const doc = loadTreeVectors(); +const vectors = doc.vectors; + +const VECTOR_KEYS = new Set(["id", "description", "files", "synthesize", "archiveOnly", "expect"]); +const FILE_KEYS = new Set(["path", "rawPathBase64", "mode", "headerMode", "type", "paxRecords", "content", "contentBase64"]); +const SYNTH_KEYS = new Set(["pathPattern", "count", "size", "fill", "mode", "type"]); + +async function outcome(run: () => TreeManifest | Promise): Promise<{ digest?: string; error?: string; manifest?: TreeManifest }> { + try { + const manifest = await run(); + return { digest: manifest.digest, manifest }; + } catch (err) { + if (err instanceof SkillTreeError) return { error: err.code }; + throw err; + } +} + +function expectOutcome(got: { digest?: string; error?: string }, v: TreeVector): void { + if (v.expect.error !== undefined) expect(got.error, v.id).toBe(v.expect.error); + else expect(got, v.id).toMatchObject({ digest: v.expect.digest }); +} + +/** Archive mode of a vector entry: header modes as given, mode classes as octal, "" as an invalid mode. */ +function archiveMode(f: { mode?: string; headerMode?: string }): number { + if (f.headerMode !== undefined) return parseInt(f.headerMode, 8); + return f.mode === undefined || f.mode === "" ? 0o777 : parseInt(f.mode, 8); +} + +const TAR_TYPES: Record = { + "": "0", file: "0", directory: "5", symlink: "2", "archive-hardlink": "1", + "pax-global": "g", "tar-nul": "\0", cont: "7", fifo: "6", device: "3", +}; +const HEADER_ONLY = new Set(["1", "2", "3", "4", "5", "6"]); + +/** The vector as a tar stream, or undefined when tar cannot present it (walker-only types, NUL names). */ +function tarSpecs(v: TreeVector): TarSpec[] | undefined { + const specs: TarSpec[] = []; + for (const f of v.files ?? []) { + const typeflag = TAR_TYPES[f.type ?? ""]; + const name = rawName(f); + if (typeflag === undefined || name.includes(0) || (typeflag !== "g" && f.paxRecords?.path !== undefined)) return undefined; + const pax = f.paxRecords; + // Header-only types (links, devices, directories, FIFOs) carry no data, as Go's tar writer enforces. + const data = typeflag === "g" || HEADER_ONLY.has(typeflag) ? undefined : fileBytes(f); + specs.push({ name, typeflag, mode: archiveMode(f), data, ...(pax ? { pax } : {}) } as TarSpec); + } + for (const s of v.synthesize ?? []) { + const typeflag = TAR_TYPES[s.type ?? ""]; + if (typeflag === undefined) return undefined; + for (let n = 0; n < s.count; n++) { + specs.push({ name: new TextEncoder().encode(synthPath(s, n)), typeflag, mode: archiveMode({ mode: s.mode ?? "100644" }), fill: { size: s.size, byte: s.fill } }); + } + } + return specs; +} + +const ZIP_TYPES: Record = { "": 0o100000, file: 0o100000, directory: 0o040000 }; +const MAX_ZIP_VECTOR_BYTES = 8 << 20; + +/** Zip external mode: directories always carry the directory type bits; files keep the vector mode. */ +function zipMode(f: VectorFile, type: number): number { + const mode = archiveMode(f); + if (type === 0o040000) return type | (mode & 0o7777); + return (mode & 0o170000) === 0 ? type | mode : mode; +} + +/** The vector as a zip archive, or undefined when zip cannot present it. */ +function zipSpecs(v: TreeVector): ZipSpec[] | undefined { + const specs: ZipSpec[] = []; + for (const f of v.files ?? []) { + const type = ZIP_TYPES[f.type ?? ""]; + if (type === undefined || f.paxRecords !== undefined) return undefined; + specs.push({ name: rawName(f), data: type === 0o040000 ? new Uint8Array(0) : fileBytes(f), unixMode: zipMode(f, type), method: specs.length % 2 === 0 ? 8 : 0 }); + } + for (const s of v.synthesize ?? []) { + const type = ZIP_TYPES[s.type ?? ""]; + if (type === undefined || s.size * s.count > MAX_ZIP_VECTOR_BYTES) return undefined; + for (let n = 0; n < s.count; n++) { + specs.push({ name: new TextEncoder().encode(synthPath(s, n)), data: new Uint8Array(s.size).fill(s.fill), unixMode: zipMode({ mode: s.mode ?? "100644" }, type) }); + } + } + return specs; +} + +describe("skill-tree-v1 vectors (vendored unedited from AgentKit)", () => { + it("is the expected vector file and the harness models every field", () => { + expect(doc).toMatchObject({ schema: "agentkit.skill-tree-vectors/v1", contract: "agentkit.skill-tree/v1", unicode: "15.0.0" }); + expect(vectors.length).toBeGreaterThan(0); + for (const v of vectors) { + for (const key of Object.keys(v)) expect(VECTOR_KEYS.has(key), `${v.id}.${key}`).toBe(true); + for (const f of v.files ?? []) for (const key of Object.keys(f)) expect(FILE_KEYS.has(key), `${v.id} file.${key}`).toBe(true); + for (const s of v.synthesize ?? []) for (const key of Object.keys(s)) expect(SYNTH_KEYS.has(key), `${v.id} synth.${key}`).toBe(true); + expect(Object.keys(v.expect).every((k) => ["digest", "serialization", "error"].includes(k)), v.id).toBe(true); + } + }); + + it.each(vectors.map((v) => [v.id, v] as const))("buildTree: %s", async (_id, v) => { + const got = await outcome(() => buildTree(vectorEntries(v))); + expectOutcome(got, v); + if (got.manifest !== undefined) { + if (v.expect.serialization !== undefined) expect(serializeTree(got.manifest.files)).toBe(v.expect.serialization); + expect(got.manifest).toMatchObject({ schema: "agentkit.skill-tree/v1", modeSource: "recorded" }); + } + }); + + it.each(vectors.map((v) => [v.id, v] as const))("tar reader agrees: %s", async (_id, v) => { + const specs = tarSpecs(v); + if (specs === undefined) return; + expectOutcome(await outcome(() => readTarTree(tarStream(specs))), v); + }, 120_000); + + it.each(vectors.map((v) => [v.id, v] as const))("zip reader agrees: %s", async (_id, v) => { + const specs = zipSpecs(v); + if (specs === undefined) return; + expectOutcome(await outcome(() => readZipTree(zipBytes(specs))), v); + }, 60_000); +}); diff --git a/packages/skill-tree/test/vector-helpers.ts b/packages/skill-tree/test/vector-helpers.ts new file mode 100644 index 0000000..e7dde23 --- /dev/null +++ b/packages/skill-tree/test/vector-helpers.ts @@ -0,0 +1,162 @@ +/** + * Loads the vendored AgentKit conformance vectors and turns tree vectors into + * presented entries the same way the AgentKit Go harness does. + */ +import { createHash } from "node:crypto"; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { decodeName } from "../src/entry-collector"; +import { SkillTreeError } from "../src/errors"; +import { tarEntryKind } from "../src/tar-reader"; +import { headerMode } from "../src/tree"; +import type { EntryKind, TreeEntry } from "../src/tree"; + +export function fixtureBytes(relative: string): Buffer { + return readFileSync(fileURLToPath(new URL(`../fixtures/${relative}`, import.meta.url))); +} + +export function sha256(data: Uint8Array | string): string { + return createHash("sha256").update(data).digest("hex"); +} + +/** The contract code `run` fails with, or null when it succeeds. Other errors propagate. */ +export async function errorCodeOf(run: () => unknown): Promise { + try { + await run(); + return null; + } catch (err) { + if (err instanceof SkillTreeError) return err.code; + throw err; + } +} + +export interface VectorFile { + path?: string; + rawPathBase64?: string; + mode?: string; + headerMode?: string; + type?: string; + paxRecords?: Record; + content?: string; + contentBase64?: string; +} + +export interface VectorSynth { + pathPattern: string; + count: number; + size: number; + fill: number; + mode?: string; + type?: string; +} + +export interface TreeVector { + id: string; + description: string; + files?: VectorFile[]; + synthesize?: VectorSynth[]; + archiveOnly?: boolean; + expect: { digest?: string; serialization?: string; error?: string }; +} + +export interface TreeVectorFile { + schema: string; + contract: string; + spec: string; + unicode: string; + notes: string[]; + vectors: TreeVector[]; +} + +export function loadTreeVectors(): TreeVectorFile { + return JSON.parse(fixtureBytes("vectors/skill-tree-v1-vectors.json").toString("utf8")) as TreeVectorFile; +} + +/** Entry types as the AgentKit harness maps them; walker-only types read as files or specials. */ +const VECTOR_KINDS: Record = { + "": "regular", + file: "regular", + "fs-hardlink": "regular", + "reparse-other": "regular", + symlink: "symlink", + "reparse-name-surrogate": "symlink", + "archive-hardlink": "hardlink", + "reparse-af-unix": "special", + "reparse-wsl": "special", + device: "special", + fifo: "special", + socket: "special", + directory: "directory", + "pax-global": "metadata", + cont: "special", +}; + +export function vectorKind(type: string | undefined, path: string): EntryKind { + if (type === "tar-nul") return tarEntryKind("\0", path); + const kind = VECTOR_KINDS[type ?? ""]; + if (kind === undefined) throw new Error(`vector entry ${path} has unknown type ${type}`); + return kind; +} + +export function rawName(f: VectorFile): Uint8Array { + if (f.rawPathBase64 === undefined) return new TextEncoder().encode(f.path ?? ""); + if ((f.path ?? "") !== "") throw new Error(`vector entry ${f.path} sets both path and rawPathBase64`); + return Buffer.from(f.rawPathBase64, "base64"); +} + +export function fileBytes(f: VectorFile): Uint8Array { + if (f.contentBase64 !== undefined) return Buffer.from(f.contentBase64, "base64"); + if (f.content !== undefined) return new TextEncoder().encode(f.content); + throw new Error(`vector file ${f.path} has no content`); +} + +/** The entry mode: a mode string as given, or a header mode in octal mapped to its class. */ +export function vectorMode(f: VectorFile): string { + if (f.headerMode === undefined) return f.mode ?? ""; + if ((f.mode ?? "") !== "") throw new Error(`vector entry ${f.path} sets both mode and headerMode`); + return headerMode(parseInt(f.headerMode, 8)); +} + +export function synthPath(s: VectorSynth, n: number): string { + return s.pathPattern.replaceAll("{n}", String(n).padStart(5, "0")); +} + +const fillDigests = new Map(); + +/** sha256 of `size` bytes of value `fill`, without holding them in memory. */ +export function fillDigest(size: number, fill: number): string { + const key = `${size}/${fill}`; + const cached = fillDigests.get(key); + if (cached !== undefined) return cached; + const hash = createHash("sha256"); + const block = Buffer.alloc(64 * 1024, fill); + for (let left = size; left > 0; left -= block.length) hash.update(block.subarray(0, Math.min(left, block.length))); + const digest = hash.digest("hex"); + fillDigests.set(key, digest); + return digest; +} + +export function vectorEntries(v: TreeVector): TreeEntry[] { + const entries: TreeEntry[] = []; + for (const f of v.files ?? []) { + const name = decodeName(rawName(f)); + const data = fileBytes(f); + entries.push({ + path: name.path, + utf8Valid: name.utf8Valid, + mode: vectorMode(f), + size: data.length, + sha256: sha256(data), + kind: vectorKind(f.type, name.path), + ...(f.paxRecords === undefined ? {} : { paxRecords: f.paxRecords }), + }); + } + for (const s of v.synthesize ?? []) { + const kind = vectorKind(s.type, s.pathPattern); + const digest = fillDigest(s.size, s.fill); + for (let n = 0; n < s.count; n++) { + entries.push({ path: synthPath(s, n), mode: s.mode ?? "100644", size: s.size, sha256: digest, kind }); + } + } + return entries; +} diff --git a/packages/skill-tree/test/zip-reader.test.ts b/packages/skill-tree/test/zip-reader.test.ts new file mode 100644 index 0000000..d626f60 --- /dev/null +++ b/packages/skill-tree/test/zip-reader.test.ts @@ -0,0 +1,95 @@ +import { describe, expect, it } from "vitest"; +import { readZipTree } from "../src/index"; +import type { RandomAccessSource } from "../src/index"; +import { zipBytes } from "./zip-writer"; +import type { ZipOptions, ZipSpec } from "./zip-writer"; +import { errorCodeOf } from "./vector-helpers"; + +const enc = new TextEncoder(); + +function entry(name: string, data = "x\n", extra: Partial = {}): ZipSpec { + return { name: enc.encode(name), data: enc.encode(data), unixMode: 0o100644, ...extra }; +} + +const skill = entry("SKILL.md", "---\nname: demo\ndescription: Demo.\n---\n", { method: 8 }); +const baseline = await readZipTree(zipBytes([skill, entry("refs/a.md", "a\n".repeat(500), { method: 8 })])); + +function zipCode(specs: ZipSpec[], options?: ZipOptions): Promise { + return errorCodeOf(() => readZipTree(zipBytes(specs, options))); +} + +describe("zip reader accepts every valid layout", () => { + it.each([12, 16, 20, 24] as const)("data descriptor of %i bytes", async (descriptor) => { + const got = await readZipTree(zipBytes([skill, entry("refs/a.md", "a\n".repeat(500), { method: 8, descriptor })])); + expect(got.digest).toBe(baseline.digest); + }); + + it("stored and deflated entries hash the same content", async () => { + const got = await readZipTree(zipBytes([{ ...skill, method: 0 }, entry("refs/a.md", "a\n".repeat(500))])); + expect(got.digest).toBe(baseline.digest); + }); + + it("reads through a random-access source and a Blob", async () => { + const bytes = zipBytes([skill, entry("refs/a.md", "a\n".repeat(500), { method: 8 })]); + const source: RandomAccessSource = { size: bytes.length, read: async (offset, length) => bytes.slice(offset, offset + length) }; + expect((await readZipTree(source)).digest).toBe(baseline.digest); + expect((await readZipTree(new Blob([new Uint8Array(bytes)]))).digest).toBe(baseline.digest); + }); + + it("records executable files", async () => { + const got = await readZipTree(zipBytes([skill, entry("run.sh", "#!/bin/sh\n", { unixMode: 0o100755 })])); + expect(got.files.find((f) => f.path === "run.sh")?.mode).toBe("100755"); + }); +}); + +describe("zip reader rejects unsafe or unsupported entries", () => { + it.each([ + ["zip-slip", [entry("../evil.md")], "tree.unsafe_path"], + ["absolute path", [entry("/evil.md")], "tree.unsafe_path"], + ["case collision", [entry("Refs/a.md"), entry("refs/b.md")], "tree.case_collision"], + ["symbolic link", [entry("link", "/etc", { unixMode: 0o120777 })], "tree.unsupported_entry"], + ["setuid file", [entry("run.sh", "x", { unixMode: 0o104755 })], "tree.unsupported_entry"], + ["non-Unix host attributes", [entry("a.md", "x", { madeByHost: 0 })], "tree.unsupported_entry"], + ["encrypted entry", [entry("a.md", "x", { flags: 0x1 })], "tree.unsupported_entry"], + ["central CRC disagrees with the local header", [entry("a.md", "x", { centralCrc: 0x12345678 })], "tree.unsupported_entry"], + ] as const)("%s", async (_name, specs, code) => { + expect(await zipCode([skill, ...specs])).toBe(code); + }); + + it("rejects an entry whose data does not match its CRC", async () => { + const bytes = zipBytes([skill, entry("a.md", "hello\n")]); + const at = Buffer.from(bytes).indexOf("hello\n"); + bytes[at] = 0x48; + expect(await errorCodeOf(() => readZipTree(bytes))).toBe("tree.read_failed"); + }); + + it("rejects deflate data that is corrupt", async () => { + const bytes = zipBytes([skill, entry("a.md", "z".repeat(4096), { method: 8 })]); + const local = Buffer.from(bytes).indexOf("a.md") + 4; + bytes.fill(0xff, local, local + 6); + expect(await errorCodeOf(() => readZipTree(bytes))).toBe("tree.read_failed"); + }); +}); + +describe("zip reader rejects archive-level ambiguity", () => { + it("rejects bytes before the first local entry", async () => { + expect(await zipCode([skill], { prefix: enc.encode("#!/bin/sh\nexit 0\n") })).toBe("tree.unsupported_entry"); + }); + + it("rejects bytes between the entries and the central directory", async () => { + expect(await zipCode([skill], { gap: new Uint8Array(32) })).toBe("tree.unsupported_entry"); + }); + + it("rejects truncated and non-zip input", async () => { + const bytes = zipBytes([skill]); + expect(await errorCodeOf(() => readZipTree(bytes.subarray(0, bytes.length - 10)))).toBe("tree.read_failed"); + expect(await errorCodeOf(() => readZipTree(enc.encode("not a zip archive")))).toBe("tree.read_failed"); + expect(await errorCodeOf(() => readZipTree(new Uint8Array(0)))).toBe("tree.read_failed"); + }); + + it("enforces the per-file limit on inflated size", async () => { + const limits = { maxEntries: 10, maxFiles: 10, maxFileSize: 1024, maxTreeSize: 4096 }; + const bytes = zipBytes([skill, entry("big.bin", "0".repeat(1 << 20), { method: 8 })]); + expect(await errorCodeOf(() => readZipTree(bytes, { limits }))).toBe("tree.limit_exceeded"); + }); +}); diff --git a/packages/skill-tree/test/zip-writer.ts b/packages/skill-tree/test/zip-writer.ts new file mode 100644 index 0000000..b0b2271 --- /dev/null +++ b/packages/skill-tree/test/zip-writer.ts @@ -0,0 +1,78 @@ +/** + * Minimal zip writer for tests, with knobs for the layouts the reader must + * accept (stored, deflate, data descriptors with and without signature, + * zip64 descriptors) and the defects it must reject. + */ +import { deflateRawSync } from "node:zlib"; +import { crc32 } from "../src/zip-records"; +import { concat } from "./tar-writer"; + +export interface ZipSpec { + name: Uint8Array; + data: Uint8Array; + /** Unix mode including type bits, e.g. 0o100644 or 0o040755. */ + unixMode: number; + method?: 0 | 8; + /** Data descriptor layout; omitted means no descriptor (flag bit 3 clear). */ + descriptor?: 12 | 16 | 20 | 24; + /** Overrides written into the central directory only. */ + centralCrc?: number; + flags?: number; + madeByHost?: number; +} + +export interface ZipOptions { + prefix?: Uint8Array; + /** Bytes inserted between the last entry and the central directory. */ + gap?: Uint8Array; +} + +function le(width: 2 | 4 | 8, value: number): Uint8Array { + const out = new Uint8Array(width); + const view = new DataView(out.buffer); + if (width === 2) view.setUint16(0, value, true); + else if (width === 4) view.setUint32(0, value, true); + else view.setBigUint64(0, BigInt(value), true); + return out; +} + +function descriptorBytes(kind: 12 | 16 | 20 | 24, crc: number, csize: number, usize: number): Uint8Array { + const sig = kind === 16 || kind === 24 ? [le(4, 0x08074b50)] : []; + const sizes = kind === 20 || kind === 24 ? [le(8, csize), le(8, usize)] : [le(4, csize), le(4, usize)]; + return concat([...sig, le(4, crc), ...sizes]); +} + +export function zipBytes(specs: readonly ZipSpec[], options: ZipOptions = {}): Uint8Array { + const locals: Uint8Array[] = []; + const centrals: Uint8Array[] = []; + let offset = options.prefix?.length ?? 0; + for (const spec of specs) { + const method = spec.method ?? 0; + const body = method === 8 ? new Uint8Array(deflateRawSync(spec.data)) : spec.data; + const crc = crc32(spec.data); + const flags = (spec.flags ?? 0) | (spec.descriptor !== undefined ? 0x8 : 0) | 0x800; + const zeroInLocal = spec.descriptor !== undefined; + const local = concat([ + le(4, 0x04034b50), le(2, 20), le(2, flags), le(2, method), le(2, 0), le(2, 0x21), + le(4, zeroInLocal ? 0 : crc), le(4, zeroInLocal ? 0 : body.length), le(4, zeroInLocal ? 0 : spec.data.length), + le(2, spec.name.length), le(2, 0), spec.name, body, + spec.descriptor !== undefined ? descriptorBytes(spec.descriptor, crc, body.length, spec.data.length) : new Uint8Array(0), + ]); + centrals.push(concat([ + le(4, 0x02014b50), le(2, ((spec.madeByHost ?? 3) << 8) | 20), le(2, 20), le(2, flags), le(2, method), + le(2, 0), le(2, 0x21), le(4, spec.centralCrc ?? crc), le(4, body.length), le(4, spec.data.length), + le(2, spec.name.length), le(2, 0), le(2, 0), le(2, 0), le(2, 0), le(4, (spec.unixMode << 16) >>> 0), + le(4, offset), spec.name, + ])); + locals.push(local); + offset += local.length; + } + const gap = options.gap ?? new Uint8Array(0); + const cd = concat(centrals); + const cdOffset = offset + gap.length; + const end = concat([ + le(4, 0x06054b50), le(2, 0), le(2, 0), le(2, specs.length), le(2, specs.length), + le(4, cd.length), le(4, cdOffset), le(2, 0), + ]); + return concat([options.prefix ?? new Uint8Array(0), ...locals, gap, cd, end]); +} diff --git a/packages/skill-tree/tsconfig.json b/packages/skill-tree/tsconfig.json new file mode 100644 index 0000000..d1e852f --- /dev/null +++ b/packages/skill-tree/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "lib": ["ES2022", "DOM"], + "types": ["node"], + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "verbatimModuleSyntax": true, + "isolatedModules": true, + "noUncheckedIndexedAccess": true, + "resolveJsonModule": true + }, + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/skill-tree/vitest.config.ts b/packages/skill-tree/vitest.config.ts new file mode 100644 index 0000000..f082446 --- /dev/null +++ b/packages/skill-tree/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +/** Lets `pnpm --filter @skillx/skill-tree test` run the package suite on its own; the root config also includes it. */ +export default defineConfig({ + test: { + include: ["test/**/*.test.ts"], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc3528c..bf18901 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: devDependencies: vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + version: 4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) apps/web: dependencies: @@ -22,7 +22,7 @@ importers: version: link:../../packages/skill-identity better-auth: specifier: ^1.2.0 - version: 1.4.18(drizzle-kit@0.31.9)(drizzle-orm@0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 1.4.18(drizzle-kit@0.31.9)(drizzle-orm@0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)) drizzle-orm: specifier: ^0.41.0 version: 0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11) @@ -47,16 +47,16 @@ importers: devDependencies: '@cloudflare/vite-plugin': specifier: ^1.13.5 - version: 1.23.1(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))(workerd@1.20260205.0)(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0)) + version: 1.23.1(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))(workerd@1.20260205.0)(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0)) '@cloudflare/workers-types': specifier: ^4.20250204.0 version: 4.20260210.0 '@react-router/dev': specifier: ^7.10.0 - version: 7.13.0(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0)) + version: 7.13.0(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0))(yaml@2.9.1) '@tailwindcss/vite': specifier: ^4.1.13 - version: 4.1.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 4.1.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)) '@types/node': specifier: ^22.19.10 version: 22.19.10 @@ -77,10 +77,10 @@ importers: version: 5.9.3 vite: specifier: ^7.1.7 - version: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + version: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)) wrangler: specifier: ^4.63.0 version: 4.63.0(@cloudflare/workers-types@4.20260210.0) @@ -105,7 +105,7 @@ importers: version: 22.19.10 tsup: specifier: ^8.0.0 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3) + version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.9.1) typescript: specifier: ^5.6.0 version: 5.9.3 @@ -118,6 +118,19 @@ importers: packages/skill-identity: {} + packages/skill-tree: + dependencies: + yaml: + specifier: ^2.9.1 + version: 2.9.1 + devDependencies: + '@types/node': + specifier: ^22.19.10 + version: 22.19.10 + typescript: + specifier: ^5.9.2 + version: 5.9.3 + packages: '@babel/code-frame@7.29.0': @@ -2716,6 +2729,11 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} @@ -2945,12 +2963,12 @@ snapshots: optionalDependencies: workerd: 1.20260205.0 - '@cloudflare/vite-plugin@1.23.1(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))(workerd@1.20260205.0)(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0))': + '@cloudflare/vite-plugin@1.23.1(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))(workerd@1.20260205.0)(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0))': dependencies: '@cloudflare/unenv-preset': 2.12.0(unenv@2.0.0-rc.24)(workerd@1.20260205.0) miniflare: 4.20260205.0 unenv: 2.0.0-rc.24 - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) wrangler: 4.63.0(@cloudflare/workers-types@4.20260210.0) ws: 8.18.0 transitivePeerDependencies: @@ -3437,7 +3455,7 @@ snapshots: '@poppinss/exception@1.2.3': {} - '@react-router/dev@7.13.0(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0))': + '@react-router/dev@7.13.0(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-router@7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))(wrangler@4.63.0(@cloudflare/workers-types@4.20260210.0))(yaml@2.9.1)': dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 @@ -3467,8 +3485,8 @@ snapshots: semver: 7.7.4 tinyglobby: 0.2.15 valibot: 1.2.0(typescript@5.9.3) - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) - vite-node: 3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) + vite-node: 3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) optionalDependencies: typescript: 5.9.3 wrangler: 4.63.0(@cloudflare/workers-types@4.20260210.0) @@ -3638,12 +3656,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))': + '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) '@types/chai@5.2.3': dependencies: @@ -3699,13 +3717,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) '@vitest/pretty-format@4.0.18': dependencies: @@ -3768,7 +3786,7 @@ snapshots: baseline-browser-mapping@2.9.19: {} - better-auth@1.4.18(drizzle-kit@0.31.9)(drizzle-orm@0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)): + better-auth@1.4.18(drizzle-kit@0.31.9)(drizzle-orm@0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)): dependencies: '@better-auth/core': 1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0) '@better-auth/telemetry': 1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)) @@ -3787,7 +3805,7 @@ snapshots: drizzle-orm: 0.41.0(@cloudflare/workers-types@4.20260210.0)(gel@2.2.0)(kysely@0.28.11) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - vitest: 4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vitest: 4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) better-call@1.1.8(zod@4.3.6): dependencies: @@ -4568,12 +4586,13 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6): + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.9.1): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.6.1 postcss: 8.5.6 + yaml: 2.9.1 postcss@8.5.6: dependencies: @@ -4829,7 +4848,7 @@ snapshots: tslib@2.8.1: optional: true - tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3): + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(typescript@5.9.3)(yaml@2.9.1): dependencies: bundle-require: 5.1.0(esbuild@0.27.3) cac: 6.7.14 @@ -4840,7 +4859,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(yaml@2.9.1) resolve-from: 5.0.0 rollup: 4.57.1 source-map: 0.7.6 @@ -4926,13 +4945,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2): + vite-node@3.2.4(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) transitivePeerDependencies: - '@types/node' - jiti @@ -4947,18 +4966,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) transitivePeerDependencies: - supports-color - typescript - vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2): + vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -4971,11 +4990,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 + yaml: 2.9.1 - vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2): + vitest@4.0.18(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -4992,7 +5012,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.3.1(@types/node@22.19.10)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.9.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.10 @@ -5050,6 +5070,8 @@ snapshots: yallist@3.1.1: {} + yaml@2.9.1: {} + youch-core@0.3.3: dependencies: '@poppinss/exception': 1.2.3 diff --git a/vitest.config.ts b/vitest.config.ts index 5f0154b..29f07f7 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -24,6 +24,7 @@ export default defineConfig({ "packages/cli/src/**/*.test.ts", "packages/contracts/src/**/*.test.ts", "packages/skill-identity/**/*.test.ts", + "packages/skill-tree/test/**/*.test.ts", ], }, }); From 8ef77690e027f0d17cec15ce0dd54546028d9001 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 13 Oct 2026 10:18:29 +0700 Subject: [PATCH 2/5] ci(skill-tree): typecheck and test the skill tree package on pull requests The repository has no pull request CI yet, so run the package typecheck and its conformance suite when the package, the lockfile or the test config change. Refs #54 --- .github/workflows/skill-tree-ci.yml | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/skill-tree-ci.yml diff --git a/.github/workflows/skill-tree-ci.yml b/.github/workflows/skill-tree-ci.yml new file mode 100644 index 0000000..dc3d10d --- /dev/null +++ b/.github/workflows/skill-tree-ci.yml @@ -0,0 +1,46 @@ +name: Skill tree CI + +on: + pull_request: + paths: + - "packages/skill-tree/**" + - "pnpm-lock.yaml" + - "vitest.config.ts" + - ".github/workflows/skill-tree-ci.yml" + push: + branches: [main] + paths: + - "packages/skill-tree/**" + - "pnpm-lock.yaml" + - "vitest.config.ts" + - ".github/workflows/skill-tree-ci.yml" + +permissions: + contents: read + +concurrency: + group: skill-tree-ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Typecheck + run: pnpm --filter @skillx/skill-tree typecheck + + - name: Test (AgentKit conformance vectors and negative cases) + run: pnpm exec vitest run packages/skill-tree/test From 95dfb49a20c99ec83ab9eaaeef4c5e9bcd942565 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 13 Oct 2026 10:52:28 +0700 Subject: [PATCH 3/5] fix(skill-tree): align tar, zip and NFC handling with the Go reference - NFC/NFD follow x/text stream-safe processing: a run of more than 30 non-starters gets a CGJ, so such a path is non-NFC; composition ports reorderBuffer.compose; counts and differential vectors come from Go - header modes outside a safe, non-negative 7-digit octal value are rejected before the type bits are cleared - zip entries with header faults or non-regular types are unsupported without inflating their data or counting toward file and byte limits - tar reads stay within a total byte budget covering non-regular data and PAX/GNU extension chains - GNU sparse files apply GNU.sparse.name, size and realsize and validate their maps as Go does; malformed maps fail with tree.read_failed - numeric and PAX parsing match Go: NUL-cut octal, negative base-256, signed and zero-padded PAX lengths, PAX times, all header numerics - an empty GNU long name clears an earlier one; PAX records live in a prototype-free object; non-safe sizes fail the limit step - collision keys fold each path once; vector harness asserts reader coverage --- packages/skill-tree/.gitattributes | 1 + packages/skill-tree/package.json | 3 + .../skill-tree/scripts/dump-go-unicode.go | 133 +++++++++ .../skill-tree/scripts/gen-unicode-tables.mjs | 3 +- .../stream-safe-15.0.0-go-vectors.json | 1 + .../skill-tree/scripts/unicode-15.0.0-go.json | 2 +- packages/skill-tree/src/byte-source.ts | 13 +- packages/skill-tree/src/collision.ts | 18 +- packages/skill-tree/src/entry-collector.ts | 35 ++- packages/skill-tree/src/tar-header.ts | 252 +++++++++++++----- packages/skill-tree/src/tar-reader.ts | 91 +++++-- packages/skill-tree/src/tar-sparse.ts | 167 ++++++++++++ packages/skill-tree/src/tree.ts | 28 +- packages/skill-tree/src/unicode-15-tables.ts | 3 +- packages/skill-tree/src/unicode-15.ts | 140 +++++++--- packages/skill-tree/src/zip-reader.ts | 18 +- packages/skill-tree/test/path-fuzz.test.ts | 14 + packages/skill-tree/test/provenance.test.ts | 47 +++- packages/skill-tree/test/tar-reader.test.ts | 215 ++++++++++++++- packages/skill-tree/test/tree-rules.test.ts | 42 +++ packages/skill-tree/test/tree-vectors.test.ts | 29 +- packages/skill-tree/test/zip-reader.test.ts | 19 ++ 22 files changed, 1100 insertions(+), 174 deletions(-) create mode 100644 packages/skill-tree/scripts/stream-safe-15.0.0-go-vectors.json create mode 100644 packages/skill-tree/src/tar-sparse.ts create mode 100644 packages/skill-tree/test/tree-rules.test.ts diff --git a/packages/skill-tree/.gitattributes b/packages/skill-tree/.gitattributes index 35fee4c..9bb8071 100644 --- a/packages/skill-tree/.gitattributes +++ b/packages/skill-tree/.gitattributes @@ -1,3 +1,4 @@ # Pinned inputs are hashed byte for byte; never convert their line endings. fixtures/** -text scripts/unicode-15.0.0-go.json -text +scripts/stream-safe-15.0.0-go-vectors.json -text diff --git a/packages/skill-tree/package.json b/packages/skill-tree/package.json index 607a537..4fc376b 100644 --- a/packages/skill-tree/package.json +++ b/packages/skill-tree/package.json @@ -8,6 +8,9 @@ ".": "./src/index.ts" }, "types": "./src/index.ts", + "engines": { + "node": ">=21.2" + }, "scripts": { "typecheck": "tsc --noEmit", "test": "vitest run", diff --git a/packages/skill-tree/scripts/dump-go-unicode.go b/packages/skill-tree/scripts/dump-go-unicode.go index 9a51c56..aa1df8f 100644 --- a/packages/skill-tree/scripts/dump-go-unicode.go +++ b/packages/skill-tree/scripts/dump-go-unicode.go @@ -10,13 +10,20 @@ // Run it from the AgentKit apps/cli module, which pins x/text: // // cd /apps/cli && go run /packages/skill-tree/scripts/dump-go-unicode.go > /packages/skill-tree/scripts/unicode-15.0.0-go.json +// +// With -vectors it writes the stream-safe normalization vectors instead +// (scripts/stream-safe-15.0.0-go-vectors.json). package main import ( + "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" + "math/rand" "os" "runtime" + "strings" "unicode" "unicode/utf8" @@ -34,6 +41,40 @@ type dump struct { // one-step pair for a primary composite, the full decomposition otherwise. Decompositions [][]rune `json:"decompositions"` Composites []rune `json:"composites"` + // StreamSafe lists [code point, leading, trailing] non-starter counts + // that x/text norm uses for Stream-Safe Text Processing: a run of more + // than 30 non-starters gets a U+034F CGJ inserted, so a path holding one + // is not NFC. The counts are unexported, so they are measured. + StreamSafe [][3]rune `json:"streamSafe"` +} + +const ( + cgj = "͏" + probeMark = "̅" // a non-starter that never composes + maxNonStarters = 30 +) + +// overflows reports whether NFD inserts a CGJ into s. +func overflows(s string) bool { + return strings.Count(norm.NFD.String(s), cgj) > strings.Count(s, cgj) +} + +// nonStarters measures how many non-starters r adds before (lead) or after +// (trail) itself: k marks plus r overflow exactly when k+count > 30. +func nonStarters(r rune, lead bool) rune { + count := rune(0) + for k := maxNonStarters; k >= maxNonStarters-3; k-- { + marks := strings.Repeat(probeMark, k) + s := string(r) + marks + if lead { + s = marks + string(r) + } + if !overflows(s) { + break + } + count = rune(maxNonStarters + 1 - k) + } + return count } func addRange(ranges [][2]rune, r rune) [][2]rune { @@ -62,7 +103,96 @@ func compositePair(r rune, full []rune) ([2]rune, bool) { return [2]rune{}, false } +// vectorAlphabet mixes starters, starters with trailing non-starters, marks of +// several classes, multi-mark decompositions, Jamo and Indic vowels that +// combine backwards, a CGJ and "/". Vector inputs are letters indexing it. +var vectorAlphabet = []rune{ + 'a', 'e', '/', 0x00E1, 0x01D6, 0x034F, 0x0B47, 0x1100, 0xAC00, 0xAC01, // starters + 0x0300, 0x0301, 0x0305, 0x0316, 0x0344, 0x0345, 0x0F73, 0x3099, // non-starters + 0x0B3E, 0x1161, 0x11A8, 0xFF9E, // combine backwards or compatibility marks +} + +const vectorStarters = 10 + +type streamSafeVector struct { + In string `json:"in"` + IsNFC bool `json:"isNfc"` + NFD string `json:"nfd"` + NFC string `json:"nfc"` + Strict bool `json:"nfcEqual"` +} + +func shortHash(s string) string { + sum := sha256.Sum256([]byte(s)) + return hex.EncodeToString(sum[:8]) +} + +// writeVectors prints differential vectors for the stream-safe NFC and NFD +// behaviour: deterministic inputs with long non-starter runs, each with +// norm.NFC.IsNormalString and short hashes of NFD.String and NFC.String. +func writeVectors() { + rng := rand.New(rand.NewSource(15)) + letter := func(i int) byte { return "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i] } + var out struct { + Alphabet []rune `json:"alphabet"` + Cases []streamSafeVector `json:"cases"` + } + out.Alphabet = vectorAlphabet + for n := 0; n < 800; n++ { + var in []byte + if n%2 == 1 { + // Canonically ordered runs (U+0316 then U+0305) around the 30 limit, + // so the NFC verdict turns on the run length alone. + for seg := rng.Intn(2) + 1; seg > 0; seg-- { + in = append(in, letter(rng.Intn(vectorStarters))) + low := rng.Intn(4) + for k := 26 + rng.Intn(9); k > 0; k-- { + if low > 0 { + in = append(in, letter(13)) // U+0316 + low-- + } else { + in = append(in, letter(12)) // U+0305 + } + } + } + } + for seg := rng.Intn(3) + 1; n%2 == 0 && seg > 0; seg-- { + for k := rng.Intn(3); k > 0; k-- { + in = append(in, letter(rng.Intn(len(vectorAlphabet)))) + } + for k := 24 + rng.Intn(14); k > 0; k-- { + i := vectorStarters + rng.Intn(len(vectorAlphabet)-vectorStarters) + if rng.Intn(12) == 0 { + i = rng.Intn(len(vectorAlphabet)) + } + in = append(in, letter(i)) + } + } + var s strings.Builder + for _, c := range in { + s.WriteRune(vectorAlphabet[c-'A']) + } + str := s.String() + out.Cases = append(out.Cases, streamSafeVector{ + In: string(in), + IsNFC: norm.NFC.IsNormalString(str), + NFD: shortHash(norm.NFD.String(str)), + NFC: shortHash(norm.NFC.String(str)), + Strict: norm.NFC.String(str) == str, + }) + } + enc := json.NewEncoder(os.Stdout) + if err := enc.Encode(out); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + func main() { + if len(os.Args) > 1 && os.Args[1] == "-vectors" { + writeVectors() + return + } d := dump{UnicodeVersion: unicode.Version, NormVersion: norm.Version, GoVersion: runtime.Version()} for r := rune(0); r <= unicode.MaxRune; r++ { if unicode.In(r, unicode.L, unicode.M, unicode.N, unicode.P, unicode.S, unicode.Z, unicode.Cc, unicode.Cf, unicode.Co, unicode.Cs) { @@ -79,6 +209,9 @@ func main() { if ccc := props.CCC(); ccc != 0 { d.CombiningClass = append(d.CombiningClass, [2]rune{r, rune(ccc)}) } + if lead, trail := nonStarters(r, true), nonStarters(r, false); lead != 0 || trail != 0 { + d.StreamSafe = append(d.StreamSafe, [3]rune{r, lead, trail}) + } if r >= 0xAC00 && r <= 0xD7A3 { continue // Hangul syllables are algorithmic. } diff --git a/packages/skill-tree/scripts/gen-unicode-tables.mjs b/packages/skill-tree/scripts/gen-unicode-tables.mjs index 16fbe60..d189407 100644 --- a/packages/skill-tree/scripts/gen-unicode-tables.mjs +++ b/packages/skill-tree/scripts/gen-unicode-tables.mjs @@ -28,7 +28,7 @@ const INPUTS = { }, goTables: { path: "scripts/unicode-15.0.0-go.json", - sha256: "baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5", + sha256: "0d0155948ceea434fa241b59937db1a41689fa2ccb8231d35d96a2c56f57b52b", }, }; @@ -123,6 +123,7 @@ export const COMBINING_CLASSES = "${encodeValueRanges(tables.combiningClass)}"; export const CANONICAL_DECOMPOSITIONS = "${encodeMap(tables.decompositions.map(([cp, ...m]) => [cp, m]))}"; export const PRIMARY_COMPOSITES = "${encodeList(tables.composites)}"; export const CASE_FOLDING = "${encodeMap(foldEntries)}"; +export const STREAM_SAFE = "${encodeMap(tables.streamSafe.map(([cp, lead, trail]) => [cp, [lead, trail]]))}"; `; const target = join(root, "src", "unicode-15-tables.ts"); diff --git a/packages/skill-tree/scripts/stream-safe-15.0.0-go-vectors.json b/packages/skill-tree/scripts/stream-safe-15.0.0-go-vectors.json new file mode 100644 index 0000000..19917f6 --- /dev/null +++ b/packages/skill-tree/scripts/stream-safe-15.0.0-go-vectors.json @@ -0,0 +1 @@ +{"alphabet":[97,101,47,225,470,847,2887,4352,44032,44033,768,769,773,790,836,837,3955,12441,2878,4449,4520,65438],"cases":[{"in":"MPSUVKNKRSLLMRNPSPMMSVRKNKTOUQ","isNfc":false,"nfd":"fcd828103302c9d1","nfc":"fcd828103302c9d1","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"32901240080e1f4b","nfc":"32901240080e1f4b","nfcEqual":false},{"in":"PQSQUMQSNOSQORHRUTLPVRMMQKMPONMOLVULPNKKNSORUONRUTRQQTVOLONTTMRKPOKSPRRUONOQUVOSRKVUUUQSPRORMQUHLNR","isNfc":false,"nfd":"bbc926e26f50dc17","nfc":"bbc926e26f50dc17","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"fafdf7784a3ad038","nfc":"331129e452f8a0df","nfcEqual":false},{"in":"VMUVSSKQKPQVVMQSLRMMSMTTVRTVUPVSKSKTRNUMNQLOROQUSSQONMRUTVPS","isNfc":false,"nfd":"3098e9677c4daaf6","nfc":"3098e9677c4daaf6","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"cb65e755c52053f8","nfc":"211a1ef9c54360a3","nfcEqual":false},{"in":"SNOSRPQVLQTVURSLRPRMPGLVTQRVRUOVKTVMUPLSPNKMLLVMHRVTOLUUVKV","isNfc":false,"nfd":"00ce451cdbbfeb00","nfc":"00ce451cdbbfeb00","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMGNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b8d7c20e519046a3","nfc":"97f0596df770d0b2","nfcEqual":true},{"in":"DAPTJKMPARTMEJTSOPJLTPKLSVRODROMFQOKNKRRLLENUPVVPRRNONKBSNPSSOQLUK","isNfc":false,"nfd":"6ec037d08af549c5","nfc":"d6e8281bbb9300fc","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"01a92892fea716cd","nfc":"01a92892fea716cd","nfcEqual":false},{"in":"UEPTPNNUMUQSOVNVOPLVMNTKLOSVLKTOOVQQLVL","isNfc":false,"nfd":"5c38d98dd6e73f3e","nfc":"54bace6ac706627f","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"cc6286300846fff6","nfc":"734623d4e0197f4e","nfcEqual":true},{"in":"APMNSKNRRKLQLKMPQMKVRMMTHPRLFRPNQMKPNTLNONPGPRKVBUPKMSSURLSUTKTPJUMKLSPOGQUVQQRQSTKMULTHLPRSNVRJVRKPTMVNPVRE","isNfc":false,"nfd":"4e2b4a223b54039c","nfc":"97fa0a895c02bf1e","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"504cd1cd0cc5d6c4","nfc":"504cd1cd0cc5d6c4","nfcEqual":true},{"in":"TSPRKRLRMPPUKRMQUUOTLNOLOKQ","isNfc":false,"nfd":"a902ec1e6788cf6e","nfc":"a902ec1e6788cf6e","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"7b3d81774d2e9d50","nfc":"7b3d81774d2e9d50","nfcEqual":false},{"in":"TKTMLMMUULLOQTSTTTNURMLUUVJNRGRRMSOSLPOPVNNVNQMTRKNRMUKVPUSPQNMOQTSQTNGTSVQMVTRTMMUPQUKKNSPRRSOTKQTSV","isNfc":false,"nfd":"e6236367c0a80c8f","nfc":"efd28b1a803b1745","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"506c52ade03498e2","nfc":"506c52ade03498e2","nfcEqual":false},{"in":"QNNLUQSSMEMKQOFPRQOLETVTNKUSFQUOVRLNLK","isNfc":false,"nfd":"8ebe6c5f0fe7757d","nfc":"34c1d687a1754f92","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"afe7859a0f5d1875","nfc":"afe7859a0f5d1875","nfcEqual":false},{"in":"GVSRRRGSKUPUKMPOSRRSMKURMTRUK","isNfc":false,"nfd":"afe5c24fd12e1d43","nfc":"21d4083e83992346","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b0626aff5236286d","nfc":"b0626aff5236286d","nfcEqual":true},{"in":"ASTSKSMNLTPRPOSSUSKGNPQVLANRSQQVK","isNfc":false,"nfd":"f5df56c22e5660e0","nfc":"f5df56c22e5660e0","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b0f30b0bfe931db7","nfc":"d98ea1d01c74561b","nfcEqual":false},{"in":"QNSQMLPOTVEVTUQTRLORPPTSPNMMULTRLPPVQ","isNfc":false,"nfd":"23e37f790aa251fd","nfc":"47f1bd6c85a38a8b","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c27ef26315654b20","nfc":"0d08e97e43c3ad3f","nfcEqual":false},{"in":"CFOLVMQSTPMSSBNRQOPTSOLTOSLR","isNfc":false,"nfd":"0891dc8d87f5b4ec","nfc":"c23d215cbf381548","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMJNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"fcaca60c051139b6","nfc":"9967475ec726f287","nfcEqual":false},{"in":"VLMURPLKVUPLOVTTBTPVSNGQNOSGMPQO","isNfc":false,"nfd":"8b815b6cb0bee0a9","nfc":"8b815b6cb0bee0a9","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e45dcaafc09b3757","nfc":"e45dcaafc09b3757","nfcEqual":true},{"in":"POTFULNVUTQRVTSUNULVOKNPMGVPTKL","isNfc":false,"nfd":"1525951dc553618f","nfc":"1525951dc553618f","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"28d4cc83a1cdc7ee","nfc":"28d4cc83a1cdc7ee","nfcEqual":false},{"in":"PKKRMOVURQVOLRNUMTKKVUPMTQV","isNfc":false,"nfd":"6b4a713729aeaf64","nfc":"6b4a713729aeaf64","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"32b72bdca53c581c","nfc":"f8734c3eaf7d6fb0","nfcEqual":false},{"in":"KMTQOKOOTTOQQPUSUSURVQUTULPOPPUTLMLLVKQQTVTMLSOEQSNVRTMSQPROVPLKVMTTOFSTVU","isNfc":false,"nfd":"b9bf087bfdd9b845","nfc":"18f10c94a80fcf96","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"86cca2cda6cdf1fb","nfc":"86cca2cda6cdf1fb","nfcEqual":true},{"in":"QUNPPOMLNSTTPRPLQQMPLOLQURPTVNTNTSOOMT","isNfc":false,"nfd":"a7eab63c08dc3b94","nfc":"a7eab63c08dc3b94","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1a6f6c6737f7d6bf","nfc":"1a6f6c6737f7d6bf","nfcEqual":false},{"in":"VKRLPSMQQORTPRKFOQPSSSLMLPSOKNPLMVSOSGPNULLPKSPTUVTOTLNUNSMUROVLLMTSKKUN","isNfc":false,"nfd":"ce3d111a9029fef9","nfc":"ce3d111a9029fef9","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a54c785e376ebe63","nfc":"a54c785e376ebe63","nfcEqual":false},{"in":"OIMSKOPKLONQUOSIONLQNSQLPURKSLSPNVURSSGTVTLKUDRPQLPNVNNNUTQNOPQQOKMLOLVQQVSNOVVPQUSPKRRMKQVSVVMTNSQSUTVLOO","isNfc":false,"nfd":"f6a6e789a7aff87c","nfc":"ecb558646bf9569c","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1b8156ea2c23bc92","nfc":"511c2b0eee04f071","nfcEqual":false},{"in":"QOSORTRNKOOVMTVVRRSMMNKVPKQ","isNfc":false,"nfd":"5a1bd42b4a374ae1","nfc":"5a1bd42b4a374ae1","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"dab0a280cd782d4f","nfc":"dab0a280cd782d4f","nfcEqual":false},{"in":"BJLRVMOBSUKSTKQOKVTSPRNSVATQKRRVPNPSPRVOOQKQTLOFSTHNPRRAQTVSKOTTEPSPVKVKTQTMQLLQPKTTULTTPTPVVMUQP","isNfc":false,"nfd":"e570029a425455d1","nfc":"76781936e1dce74b","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMMMMMDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"57757c74501209a4","nfc":"86aa6f4e04203b5a","nfcEqual":false},{"in":"QJLRVVPOUQNRRMLPPPVPLQJOKUONPRSUVLSTPMNTUQVKLTUUMTSQPEMMUSSQFSLMKQSDDRSPKKUTKVNRMLHMRUTTOSNSPR","isNfc":false,"nfd":"43b7152dac4e2c2a","nfc":"69e987793d88fa0d","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMENNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"5fce95e75101375a","nfc":"f3a92da6e0351eb1","nfcEqual":true},{"in":"KUUVVUVROMNKMLLRNLTKNPMRVLNALSOQNSRVOPUOTLIPNVQPURPVUMPNKLOOHOVKSDVPLONKUQUUKQUUMORNRQVHNOQMLUNRKLVMN","isNfc":false,"nfd":"2f4e7d59e7243740","nfc":"8d37ad26b4be2bf9","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ec42dfa967e8c4e2","nfc":"ec42dfa967e8c4e2","nfcEqual":false},{"in":"NUVQRSQSRVNVTUORPLKTDRRMKT","isNfc":false,"nfd":"d10eb438c5953ffb","nfc":"a1c45114960b7d24","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6ddc95949a3b7bee","nfc":"6ddc95949a3b7bee","nfcEqual":false},{"in":"VTVTUMSMRNOQAVULPPSQKKRNNMKVPPTRUURPLQKPSLTKOPNQQMKRSMNMSMQEOODSFVMUQOKMSURVOBVOONSKMMONRVTVQLOOQ","isNfc":false,"nfd":"d80963385c4301e5","nfc":"fef09c36d2caf8dc","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0fb34ba806c8aa5a","nfc":"0fb34ba806c8aa5a","nfcEqual":false},{"in":"RPVOPMOQOSRSMQRLQKMVSRRQRLSTUTKUSSRKNVSRVKLVMTQNMPRVQRKMPLLRLPLUQMKVTNULTSLUNPSMURVUKTUVRKLTOVQTGL","isNfc":false,"nfd":"c4db566f77f98300","nfc":"c4db566f77f98300","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"16502577c5d28bdd","nfc":"243a8031585ade10","nfcEqual":true},{"in":"MUSSVBRQSMQVQKQVKOMLJUPQTRVUNKVRQRSAKROLNNMSVUUTOSOSOMVKPMLORUKVIQCVKRMTMTOTNQRVTSSKTMVPTQUOOQOPKNK","isNfc":false,"nfd":"c80850d6474f0be1","nfc":"ac7036286b647d05","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a40a05cc1c015bf7","nfc":"866807fb43539d96","nfcEqual":false},{"in":"PTQQUOPTMKVVUQKKRVVQVSKLRTMKMUNPQMVOVOQSRQNOQMQSVRNVP","isNfc":false,"nfd":"08109b12f8c89b03","nfc":"08109b12f8c89b03","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"f3446ccf22dedb26","nfc":"e2ea25f3bf887b47","nfcEqual":false},{"in":"UKRNOMUKLLPGTRQUVTMALVNNPUPVNKMMUFSMQOJMVQPTRQURURRGUV","isNfc":false,"nfd":"13c716613dac4702","nfc":"e2784102fea6114d","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a54b2c1dd72f8b63","nfc":"0f3be6332eae0d75","nfcEqual":true},{"in":"QDNPRVRMRPLNSQMMSPSTVQUQHKKPNNTPKQRKAMRUOTRSOVPSQLOSQPNKRLPQTQTO","isNfc":false,"nfd":"f76852d2e741973a","nfc":"7bbdc167d24ee607","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"8888b769fe0b6668","nfc":"1e633d671035ddf1","nfcEqual":false},{"in":"VOUVSTMPUNUPOOOQURPQPMNMNRRRUSTNTMRLVVTSSMUONUOVVNMSNTUTUTSMQOPTUQTPQOATTSKQTKULOVRMSKSKQTOHL","isNfc":false,"nfd":"7376f1d62ec549b6","nfc":"7376f1d62ec549b6","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e2480ce0e0be6eaa","nfc":"e2480ce0e0be6eaa","nfcEqual":false},{"in":"RVLQKLRKVRKPRNKVUVRRQPSUMNOVUQTNLPVMPPNVRSRLOKRKUVRKRQKFSMRMLKKQVMOLQQPHQOSUMRLFMPRLROPRSQKONRPPSLNTMLSKPT","isNfc":false,"nfd":"cff4e6f12dd23019","nfc":"cff4e6f12dd23019","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"638182ae1e97e5d8","nfc":"7f6b24352f3195b1","nfcEqual":true},{"in":"KQNVPMTKQNVTRLQNORKRVUNSNUMULUQMOFOTVKMUNAVUTUVMKMPKKOBVPPK","isNfc":false,"nfd":"bf09b4f26719049e","nfc":"bf09b4f26719049e","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c5bd5bfaba01580f","nfc":"c5bd5bfaba01580f","nfcEqual":true},{"in":"RNTLVUKQPKVMMUMRVQOQRRUUUURMPTLNVSITULTJOVMKTQLKRVUSKNSSPUMS","isNfc":false,"nfd":"74911756e39f12b0","nfc":"faefb57afcc021f3","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"886de1673e94471e","nfc":"886de1673e94471e","nfcEqual":false},{"in":"SOMPNSKUNQKQNQMTTTLPPMSLVKUOTLLUVTOLUSMKKUNMMUUPULVLPUNMOVUM","isNfc":false,"nfd":"a8c2b4b235786bbb","nfc":"a8c2b4b235786bbb","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6b586e12ab7a981c","nfc":"6b586e12ab7a981c","nfcEqual":true},{"in":"TBOOQFUVLOSTKSSVNMSMMMMUPVNSSUENMOQOSOUVNSVDMRLSRTUPMSTONO","isNfc":false,"nfd":"684df0c3a896eeb3","nfc":"2b1de62fec25bbcf","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"76b8ba63c38507b6","nfc":"6dfbfbdb85ae3c08","nfcEqual":false},{"in":"UQSKQRVMNTTKSOVMTRORLLRPMN","isNfc":false,"nfd":"85700768a2a11d43","nfc":"85700768a2a11d43","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e4d3295204b21f8e","nfc":"7e70528f6eaa1ea8","nfcEqual":false},{"in":"CPTNVOTVPMSUSTJKMONQKRNPUNQUTPKPPTMTGNTQRVVVTSKLQUQMMOOOUNKPKNNMMMTNRMPNKSKPTNUKSQMRQPOKQVUVMRD","isNfc":false,"nfd":"d5ea72608f8dc95f","nfc":"60c4f6894709960c","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"f77a0b2965042899","nfc":"20674ea7c36ead91","nfcEqual":false},{"in":"MCKNTQSOJMVKPSSKFROOSKPNOMSTTISLTFVRPLL","isNfc":false,"nfd":"1cbe1864a45f92cc","nfc":"82190bd571386d2c","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"173f890cf051c47e","nfc":"2559f4bccdfb9a3a","nfcEqual":false},{"in":"QQRORQIKTSUPPMTDIRVPTVSNURBRSMPOLQSMUMKSOKRQOOLNQPRTLQKKORNQRUOQOQMVPNMPQQKOKJMPSTLMUMQSTLSVAO","isNfc":false,"nfd":"9257d4f9150da21b","nfc":"feb35ed3503a98cc","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8a73b6ca9e572b06","nfc":"cf738a99dc411549","nfcEqual":true},{"in":"VVLBORQVKQCLSSSSVNOTPQOLSQSKMCNLTRGVUNMPQKTSTTQUNTTPLVMOUNLUQVOPKQFRSMMTSLOVQPONKRHOUVTPVPVTMKSU","isNfc":false,"nfd":"fe2d05cf47847f61","nfc":"28a3ac44393a843f","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"91db2725c3162eb8","nfc":"9d385618580d1bda","nfcEqual":false},{"in":"FSLSTNSANNQRQVOKNVVVOUQOKMVKTMORSSQSKMUTQTMKVUSOMLRJCRSCSKQEBMQUUKNCRTMNRKURMLSMUSRPOTUOUTMQNNLOTSLRM","isNfc":false,"nfd":"68c7bd96250055e6","nfc":"8c0f5d123f97d894","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"0155f2f473fc8336","nfc":"0155f2f473fc8336","nfcEqual":true},{"in":"VTUIILSUTSRKTNSSMQPOKOVVVMVMVLRVRSMRRJONSKQMLCOVQTRPTNMTVKQPVOROMMOUQROTUP","isNfc":false,"nfd":"4234e7a35ba48559","nfc":"a435e5431382cc40","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5b3782efb77a44e3","nfc":"7ad3f496d64dbbcf","nfcEqual":false},{"in":"TQRPLKFKRLUVSQOGMKSKMKRKLMLNNLSVLLKOS","isNfc":false,"nfd":"50a8d44fb6223b6c","nfc":"50a8d44fb6223b6c","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c495b7e6da69ff95","nfc":"c495b7e6da69ff95","nfcEqual":false},{"in":"IPKQOQUQPUKTVTNMNRSKTPNTVOMORMVRMKRLNKRSOPLPOQOMTLNVNNTKNNTMUDVKUNVRUJMK","isNfc":false,"nfd":"c2f077a2d787e400","nfc":"51d2c467f4002889","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6e82911944cec2ea","nfc":"6e82911944cec2ea","nfcEqual":true},{"in":"PSULUNTULTNTVTNOLQTCLNUOVCRORRLODMVQMOCRPQPMRNTUUORRUKTPOSRBMRLNLLOTTVFVTOUNRAQSROMKQ","isNfc":false,"nfd":"2276d0ef572e9e5b","nfc":"bf5e8bd17001bd49","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ce0691aa4d8dc4f9","nfc":"67d9a1dd26926dd0","nfcEqual":false},{"in":"SDTVMNKPVQUOKLRFUQRMQTVRNMNLUELNVPSLT","isNfc":false,"nfd":"0316427e353077e2","nfc":"de96a3662a7e1acd","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"3ae1f04271e061c3","nfc":"99154acde5f8ba1e","nfcEqual":false},{"in":"GNTPUCOSKONSLVSTSPOVVQTLSRLKTTTVNPPT","isNfc":false,"nfd":"5ddf132bd411fa28","nfc":"5ddf132bd411fa28","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMBMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"400f92c282240bfe","nfc":"400f92c282240bfe","nfcEqual":true},{"in":"LUUURTMKPVLMPTMPTMLUNOVOODSDMNQVONQNP","isNfc":false,"nfd":"7081851aad16e8be","nfc":"4abde784b9ad854c","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"93cf5beebdceefa8","nfc":"93cf5beebdceefa8","nfcEqual":false},{"in":"VMKTSLQLGVNIVSPOSLASSLVPSSSPKORPLQNSSMQQVOOUNQOOAUMTPARLTMLURSSDRNPMVUKTLMTKPMKPULVRV","isNfc":false,"nfd":"ed611fd9e1e77f75","nfc":"11b9c598fb9df6f8","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ec42dfa967e8c4e2","nfc":"ec42dfa967e8c4e2","nfcEqual":false},{"in":"DQPSOOKVLMTOQNLGVHRCQRKURSNNNTQMUMTRGMNQUOLKKSSMKMNVRRROKURSOTDU","isNfc":false,"nfd":"22ac0ac92c5eda66","nfc":"4c40294afbced9f3","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0ef839f0b1f5f816","nfc":"0c61830c644ef266","nfcEqual":false},{"in":"COMVOPPMKMVQLVQVPQMMRTKMLU","isNfc":false,"nfd":"1816f53317cd96c8","nfc":"1816f53317cd96c8","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMGNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"279080a2f86bbbf1","nfc":"f0461e901aabf775","nfcEqual":false},{"in":"FKKTNLQOUQNTPUQVTVNSVMPOLKQMVLQJJNTSNQPNVOKDSLPTLUKLPSMVNNPNORNVNNRPKQCSNSOSJNTSIVNNONFQLQKPKKMNQNMONSKRQKNN","isNfc":false,"nfd":"4df3121446cee128","nfc":"60b87f4c650e5cad","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e7f351aa477ba85a","nfc":"e7f351aa477ba85a","nfcEqual":true},{"in":"PPQVLMULKRSQVSQUSQOQPTVTTRLOLLTT","isNfc":false,"nfd":"3696b34981829d24","nfc":"3696b34981829d24","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"969a0207ad6c5eff","nfc":"969a0207ad6c5eff","nfcEqual":false},{"in":"ICALMLQSMURIQOMUPSRKLOPFMVNSQRKKKKSTQRNOKHVLLRQQPVOOMTVTVRNRMTNSV","isNfc":false,"nfd":"cbab1466b1b97d63","nfc":"6942a8f73969f4e4","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e0deb3447c45ed39","nfc":"e0deb3447c45ed39","nfcEqual":false},{"in":"RSTLMPLSPPRKQKQUKRUNLNVQ","isNfc":false,"nfd":"eaedf2ce7564fe6f","nfc":"eaedf2ce7564fe6f","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b522d212719f824a","nfc":"87aa196559cf25b0","nfcEqual":true},{"in":"QSKRMLVMKTVLROSRRKVLLSMSS","isNfc":false,"nfd":"349dfc35926f1d75","nfc":"349dfc35926f1d75","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0686bbaf4abcc7f0","nfc":"89ba41cecbc98191","nfcEqual":false},{"in":"CUKKUQRSQOUNVFMMBMSKKROUTFAKRKLUPKOROUURUOQOPSKRMLVMOPPSIVTPST","isNfc":false,"nfd":"1610a4d4ccbbc2d5","nfc":"0f461fc902287fda","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ec42dfa967e8c4e2","nfc":"ec42dfa967e8c4e2","nfcEqual":false},{"in":"KTMPTLDMNOUNRRLTSSVLMTMTLSPQQVUMLMRKLQCVTLRAVUKGUMUSNUTPVVVUOMSQOLRR","isNfc":false,"nfd":"adeae1b453183f66","nfc":"f6976cbc442853a8","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"3606bafedbfb25c4","nfc":"8b1eab3c10d3ba13","nfcEqual":false},{"in":"MPLBVRMTVLNMRTNHSQSMTUTTSRSTLPTUMMRN","isNfc":false,"nfd":"961fca356aa613f1","nfc":"961fca356aa613f1","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b0e0730f0afeeb6b","nfc":"b0e0730f0afeeb6b","nfcEqual":true},{"in":"NVKRMPUUMQUKPOVSPTVUTURPOTRVRPMTQLUPVLUMTLMSVRVUVKT","isNfc":false,"nfd":"df75dc4dfcafecf1","nfc":"df75dc4dfcafecf1","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMJNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"58572fa31aa6f164","nfc":"e1597b3f12ce41bf","nfcEqual":true},{"in":"QKTKTOMVKMOPLVSPMULVLKLNPTNMSPNPMPCPCTRRVVMPQAMUVQVLPTTVVTRNQSKP","isNfc":false,"nfd":"aad029a5c1c1aa7b","nfc":"aad029a5c1c1aa7b","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"2b90f924d8a7e524","nfc":"f29f26bdbd3fcc9c","nfcEqual":false},{"in":"RBNNNQQUMPTNVONMLKTSKPMPQRLPUTPS","isNfc":false,"nfd":"afb4bb17cce20986","nfc":"afb4bb17cce20986","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"82a1112701b7d4ad","nfc":"9a5d974e5c3379bc","nfcEqual":false},{"in":"LCTPNUVUOOORVNKTPONKLTMVRMUTFFERFKQVTPNOQQQTKMONMQQLMRUKVRMTTEQLVAQOPKTKPLRKKLSTNLULQSSTSOU","isNfc":false,"nfd":"ca122ab7e17f49da","nfc":"6d401caa5a3a110c","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"ca9ef4adf80925c8","nfc":"ca9ef4adf80925c8","nfcEqual":true},{"in":"IJULQOULVQNROQUTNVQRNPTQNSVMKSRVKNMVPTNKNTNTPKPKRONSNOPM","isNfc":false,"nfd":"f77f4076ee6f390c","nfc":"d428dc90a1e86348","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e9767215b87b83bb","nfc":"dfcd79c0b0763955","nfcEqual":true},{"in":"ALMVKFPPONQOPNUVVPSMNKRMPLSLSTQMTNVQVLKKKVKORLQMUVVPETLLNUUKQUVPOOKU","isNfc":false,"nfd":"848b89ee7ddf8e58","nfc":"2348c7900a34d27a","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6ca9562ec82455c3","nfc":"6ca9562ec82455c3","nfcEqual":true},{"in":"PRSNTMRSLLVQRSPLMQLRUMJRVURRCJRSUTTRKSUQSSKSHLMMMUNVOSNNKSKLTTUQNTLVPMSNUQRRKUUUVNRSVKP","isNfc":false,"nfd":"3eb07c60233fec1a","nfc":"b1172da29dcca8c8","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"10209e4152dae277","nfc":"10209e4152dae277","nfcEqual":true},{"in":"PAKUQOVUORKPRQOSONLRPRPLLLULMFPQPUVVROQOTMQNOTUQMKUSTVHQPSTUN","isNfc":false,"nfd":"e58ac496cbcb4edc","nfc":"a6a178d54123cc4f","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0861562ace09f073","nfc":"684421c10f0a2e87","nfcEqual":false},{"in":"JUIRLMKVNTTMQVRVLSTMBONQM","isNfc":false,"nfd":"16b9ba5611a6adff","nfc":"5fc11d9ebdf21f97","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e5ebf0159ce300ec","nfc":"e5ebf0159ce300ec","nfcEqual":false},{"in":"RNTRKKTQTUQOVMTRPMVVTPQKKSVMO","isNfc":false,"nfd":"456c7fa8dac55ccb","nfc":"456c7fa8dac55ccb","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"28b6664c107d212d","nfc":"3e11a96cc23169f3","nfcEqual":false},{"in":"UNGORKVLPMRPPUVSRVLOFLKMVQKLVRUSPSFPVMLVKSMNKOPNVQPKMRPTORRTNSVLUQONPK","isNfc":false,"nfd":"eb586576c2b70e1a","nfc":"eb586576c2b70e1a","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1ab1e37155f0482e","nfc":"8b22b0de73d5503a","nfcEqual":false},{"in":"IGQKONVKFFQRSLRERSNLKQUSRDPNVMTOQNKNLQV","isNfc":false,"nfd":"586e40e9e5ea4d3b","nfc":"fc9840b6f84298e6","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c1d881c62bd3a529","nfc":"031488e58bbe1eff","nfcEqual":false},{"in":"OQKNRQOSQMLRKQRQTUTSQKVPS","isNfc":false,"nfd":"38119530a46dd8f3","nfc":"38119530a46dd8f3","nfcEqual":false},{"in":"ANMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6271dd3b68e4189f","nfc":"6271dd3b68e4189f","nfcEqual":false},{"in":"AHTVKVOOUUMKMPMNDNNSKTKSMUULMNSFUKQTMOQEVTNSOUUKRSNRTIUREL","isNfc":false,"nfd":"2bdb9416f9a836db","nfc":"32a20048ee1dccdd","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b220901498f8a28f","nfc":"ae2dace2e9c7b64c","nfcEqual":true},{"in":"RQTNUKUSKNPCQMRNSVVKOOLLUOMLQOLPFDPTRTPNSNNTVSPUOPOMTQPUTOOPQVL","isNfc":false,"nfd":"9edeb274e3f1bb3b","nfc":"861f82f18fd42c9f","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"dac53168b1ff16eb","nfc":"660b8ecf1bea5794","nfcEqual":false},{"in":"HNOPQKONTKORKSLPLNENONSTLUOSLSVNUMTKSCKUQQSLROTPVMQOOLPQSTUPMVQLLMQMQMRQPLOPSUUVVUUVVTUSKRTPVJSVMVKTMBQOK","isNfc":false,"nfd":"adcee180585d0f72","nfc":"27355600064d7f01","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"aeb46e01259027ad","nfc":"aeb46e01259027ad","nfcEqual":false},{"in":"LPSQPOVSVLTOKRPLLHPKVQNOPOSQRULNVMNOQLUMOLTPOKKKKKRTVRLCLNSPMOL","isNfc":false,"nfd":"09f14ce8e3ba7740","nfc":"09f14ce8e3ba7740","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"aa97ccfa57c98b20","nfc":"aa97ccfa57c98b20","nfcEqual":false},{"in":"TNSUULPSULTLPQPTKVNPCQKNKKQQORVPMVUSMLOVTKKUUUNSVINKRSQTNONH","isNfc":false,"nfd":"2b8eb6b677be7beb","nfc":"5bb15f6aff1f9e91","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c054c53ea3294c02","nfc":"0b1e6d78fd4b4dd4","nfcEqual":false},{"in":"AQQOQMVULQHRPQNKNLTMRVGVNVKMTPOMTVJ","isNfc":false,"nfd":"f5702110ffb492e5","nfc":"b6ac9d74ee9a6595","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"9a041d8dbad57696","nfc":"9a041d8dbad57696","nfcEqual":true},{"in":"SINOVPUOKOOPPLPOLMMVPKLMLTLU","isNfc":false,"nfd":"8c14827612891fbb","nfc":"07f79ee652150809","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"408dba7b43e7476d","nfc":"408dba7b43e7476d","nfcEqual":true},{"in":"JATOTKUNVMKQVOOUOMOVSTUKPPVSSNTRV","isNfc":false,"nfd":"445f7e338fb874e5","nfc":"b95186fbccd7523a","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bb9e527a4cf2db36","nfc":"bb9e527a4cf2db36","nfcEqual":false},{"in":"PNTTSLKMOTCROSQVOPRMSTLKNVSULKSTLLVOUSRORNMVDPMLRUMUKLVMSRPLLPSNULPKLOMTSPLMNDSQKR","isNfc":false,"nfd":"f16fa7e25500b0f5","nfc":"5fdb3eb8ec9357af","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c733133c7354b47f","nfc":"0120d8f34f013882","nfcEqual":false},{"in":"IKNQSTRVPVLEUONNUUULSMPTKPVLVNVPTULVRLMONSQUKQPSQOTMOKOMLMNVRVUNKNPNROSTSPDUKOMKUKMMTHMKASOSRVUEVV","isNfc":false,"nfd":"45d0f67df735c571","nfc":"4d81b175ac245d66","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMGNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9e9bc53f45dc291b","nfc":"e9239358b286dab8","nfcEqual":false},{"in":"VQKUNSQOLPVMVSVUQTUNFKLPRPULMLOOKUUOUCFVPPLTOQSNNKMPSSTOQOMPNLVPPMURKSKRSTOO","isNfc":false,"nfd":"41f02bfd73ddfb3f","nfc":"41f02bfd73ddfb3f","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6380b80021ac12bd","nfc":"6380b80021ac12bd","nfcEqual":false},{"in":"LOUOUFVLUQKRMMTPPNOKKTLLONLQU","isNfc":false,"nfd":"00f6c4713630a2b2","nfc":"00f6c4713630a2b2","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c17d378080107940","nfc":"c17d378080107940","nfcEqual":false},{"in":"LQKQTNOLSUKVNPLMVRNSVVERPPLSUUULVNOOUTLOOQSRKTTTMMLTKMTPPPPMUTLMNPUSIRKNKUTUNNQSRSQASPMKNNMLVDLMNLM","isNfc":false,"nfd":"67785814371802f4","nfc":"c358cd56fb2a3667","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1343597895951130","nfc":"95124b87f80875fc","nfcEqual":false},{"in":"HPROKKTSUKKSLVKPSMNSURSRONEQPURVTTUTQGNMOTMTTSVRNKSOPQOUTSTNROSUNVODNOMUQ","isNfc":false,"nfd":"7abadaa4e608ac3e","nfc":"a960c3029eb56e16","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"638c78e904e9cba6","nfc":"492290c734ab0d5b","nfcEqual":false},{"in":"DTMOPOQNOVKROMKDKSLVLRMOLNSVPLSNPOVUTK","isNfc":false,"nfd":"e41d6c5b4264761b","nfc":"1d012ccfa45f5543","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"9e30ef72b18b8287","nfc":"9e30ef72b18b8287","nfcEqual":true},{"in":"ELSMTSUVLRUUEMVVTSORMVUSMQOMOVRPQQUTTEONVMQMVSMQVGNQKULETULUNRU","isNfc":false,"nfd":"6314a7931e19d39e","nfc":"fbd063fcf7bf333a","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMDNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"38ace8b5be1221ca","nfc":"0bb35cac826f7a5e","nfcEqual":true},{"in":"LQRNUSQTOVTUQPPKVVHSKKKRUVSNSOVTMQEPNOOLTLURMPNNRRNKNVSQOQKSGNONLP","isNfc":false,"nfd":"1ed867e99bfb1965","nfc":"d2ca3a82b79a0eb4","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"259219ae5da4a872","nfc":"f1a9451c12883c9c","nfcEqual":true},{"in":"FTTULQPUSVQTSKRNMQQNTPLOKQQTTKNTLSQTNSQKLSNLKMARTNLRTMNOOOBOKOUORQSTOVUMOSOVSRMKVURPSOPSRROSLRP","isNfc":false,"nfd":"059815b8cdd04efd","nfc":"58bca359defc5796","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"42e1b8b94ed968af","nfc":"39e47eecf9dd166e","nfcEqual":false},{"in":"NRUNVKTKSPSMKUOLSNTMUNUPNNVMKMMLUQIOTRKROANOTKMPTMLOQTMPNLUPKQQNLMUVMVOMNRUPPTPSUNOQUSTVKRSTKUSRNUMQ","isNfc":false,"nfd":"1d70ea7f5e7b4a5b","nfc":"666b54fe032f086b","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"3ae1f04271e061c3","nfc":"99154acde5f8ba1e","nfcEqual":false},{"in":"RKLQSOUVTNPVMMMLUMVNKKNOTLKOVURNLLQKMBQLIPOQVVONOTLFBOTRKNNSPULOVPTLUUNKKT","isNfc":false,"nfd":"e9bc98a2397295aa","nfc":"d5cb0416ede3aebc","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"33fd626eebfcba46","nfc":"33fd626eebfcba46","nfcEqual":true},{"in":"EVSSSKMQVLMMTOQLRRKRMURROVVOUMSLNSP","isNfc":false,"nfd":"6ef633f14dbc6969","nfc":"7f26ef67d3393299","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"173468f938afc946","nfc":"2e88c57a149fd411","nfcEqual":false},{"in":"IKKUOQKMQQRNMSLKSNPOUVOOPTLRLQRKVDLUTNLQMQUOQALMPTQVOOROSNPUULULOKSUNPS","isNfc":false,"nfd":"74dda61ddc64ec80","nfc":"bb8db9b593765f92","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"fb518c7f7c483edc","nfc":"fb518c7f7c483edc","nfcEqual":true},{"in":"UTUPVPPQTKRROMPKUPNSTRUKNKRUTRMSKBEQVDNQNQSSTKUOHNKMKQSTFKMMMVPHVPMSRKVSMPLPKQMSOUPVRQUUPNLNKULOTQVULRVSK","isNfc":false,"nfd":"2bbf4925b0add1c7","nfc":"9b3ec74359a4dcb3","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"af8265b060ba8953","nfc":"43851d49599c02b6","nfcEqual":true},{"in":"TNQTKUQVUTVSKKQNMSRUPFOMOTVNQTURQQSQLEJBNMSVONPLTLNLVUOUNRMNSUONVPSVOULTSUOIPNMPNNVRNMLRMPKUTKVQ","isNfc":false,"nfd":"a3deea96b82e0ddd","nfc":"a294a8af1e5e378e","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"28b6664c107d212d","nfc":"3e11a96cc23169f3","nfcEqual":false},{"in":"GVUVQTMOLLVUPTOVQKLTPKPSURULQNSRVKKLKMUKLSGPQTKPFPJLMPMSQVHNVLQMLQQRTPTHNHRUMMNOURPULTNLLVVNUKNRSOR","isNfc":false,"nfd":"e34f00a448f7292c","nfc":"d8861b8ae2e9c732","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e80f650bb2db4b82","nfc":"e80f650bb2db4b82","nfcEqual":false},{"in":"RKIOQNPQUOSTNPUPASRLLRVPLKTUNUOVRQNPSOJUOOOTMLOQORPJOLLMUTNUNVSMRONPRSOTNTLSEUPLMMPVUUR","isNfc":false,"nfd":"9cda6ba789bbf8f0","nfc":"30914cef28d27327","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e1e801f79ddfbc0c","nfc":"aea0288777dbd63b","nfcEqual":false},{"in":"VUAOTSMPOLVTVTVKSSMSSOSQLNTKSTRDHQUQUMLPTVRKQGUMUOLOOUTNMPSKQRLOQRUKOPNTLLVSNPVTKQRRVM","isNfc":false,"nfd":"48f4436cda4c8f08","nfc":"ed5aa40c8e22dfa1","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b2bcd1c6571cd447","nfc":"b2bcd1c6571cd447","nfcEqual":false},{"in":"SOQIVPKQQSLOLRKMTLUQLPUPPTLCCLSTLKVSMTQTVNLQUSJUOORORPUMLTNOADISUMQRGQRTMPRLQTLSOLOVRMTUMTKM","isNfc":false,"nfd":"3725c4a851e21105","nfc":"8f380b1e64b1a213","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"95b64238b52f358a","nfc":"b5b1a2a0c9ba7c09","nfcEqual":true},{"in":"DDURVQTHRQRVPSTLPUMNLSLTQULRQMPPNKMTL","isNfc":false,"nfd":"a2786538d635a027","nfc":"316d8d67c64c47f3","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e7699f68e17668d1","nfc":"9b0b14e3a373e0bb","nfcEqual":false},{"in":"ORUNPMQRPPODNNNVLOPPRQUSTALULLQNLINNNOOOPNONKMQNLSVIPKRPQKOQV","isNfc":false,"nfd":"a3751ff58d5a6724","nfc":"7149ff91049023a6","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e45dcaafc09b3757","nfc":"e45dcaafc09b3757","nfcEqual":true},{"in":"KPKMPNRQKROOUKQNQTLQURCBRTPSKRUCMUUMRTOMKORNOTRLVPMUMMATRPSQPOUTENUSQM","isNfc":false,"nfd":"5afc0c2427871955","nfc":"f82004bae4334675","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"d12a5d9dd6f73712","nfc":"d12a5d9dd6f73712","nfcEqual":false},{"in":"USNOSMRVNVKQRLMUMJRNUKULQNRPKTQQOIVLRPQONKQMLUVRVQMKVSLKUQTQKKPMUUVUKVUVMKPOTUVPSUSRMOSTP","isNfc":false,"nfd":"0a976d957929e48e","nfc":"839eb399ade59889","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c17d378080107940","nfc":"c17d378080107940","nfcEqual":false},{"in":"UMPSMSTKQQVRVPRRUQTQSLUSLVPSKMUNASMTVVRMUMVMOKPTOULTMSQKCKPV","isNfc":false,"nfd":"b0ba8e812994a9d4","nfc":"b0ba8e812994a9d4","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"eab8d65c287c47ce","nfc":"eab8d65c287c47ce","nfcEqual":true},{"in":"MLBUPVTENUPNOTQPKPANKRRRON","isNfc":false,"nfd":"39892621af99efa5","nfc":"4ae6c812892dd64f","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"16c3b4ff81d612c7","nfc":"16c3b4ff81d612c7","nfcEqual":true},{"in":"DCKUQNRRRVNOLTPMLEVUKKQQLLLPPQNFKURRPNOONSMTOOOPLPPVKOMVSPMVONPKUNPSVTKNTRUTQMLONVPPPUPORNMOMRKQOMNHMPL","isNfc":false,"nfd":"a0164577b7e9f314","nfc":"cdd95495ad2b740c","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"61141583d28a9bdd","nfc":"768182b400ed10aa","nfcEqual":false},{"in":"AVQRTNOSRTNOMUSVNPKSOVROPVTTPLOVKURNLTNNMKNQQQRRKRPNRNSMMHQVRBMSLMVTPQPOSIKUTTUVTVLOMNPORMNQKUKMS","isNfc":false,"nfd":"b07bab437cb05fa2","nfc":"9c60ed6002878c6a","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c6c11de82aa119c3","nfc":"c6c11de82aa119c3","nfcEqual":true},{"in":"SQNOTVOOUVKMKPOKTPNRNMRTPQLJSVQVVTKTLQPKVLVQPLRRTRLNPNLRN","isNfc":false,"nfd":"309b06db5988b73e","nfc":"76ffd31a167199f4","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b64dba1ea87052c9","nfc":"0b8f375d9209a477","nfcEqual":false},{"in":"LRVPPMLRROKSMKTKQPATKSOMVEMOLRQPNKKNSNQRVTQNRPGSKRPMSUOVMSMMMSLVOLVOKELKNOQMUTTQMLTUKVPKTU","isNfc":false,"nfd":"1d39f3b2671817f0","nfc":"8951051752c6fa90","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0622cb270411ec9e","nfc":"0622cb270411ec9e","nfcEqual":false},{"in":"BVULKOPRUOOLKNQURMPMLQVONCKPSORQMLQUUSNKTKQUNOVTSLKPPHKLCQ","isNfc":false,"nfd":"094e60de55e92e69","nfc":"094e60de55e92e69","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"18fc7a509ae11575","nfc":"16a60865cc0c918e","nfcEqual":false},{"in":"OTRMMOUUKPIQSTMTSORTVRPSLMVM","isNfc":false,"nfd":"4084495d23b2c22c","nfc":"e119e352ad432643","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMBMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"d79f49a9194eef44","nfc":"d79f49a9194eef44","nfcEqual":true},{"in":"UROKTTVNLTRMOTSTDVLSRRQUOMQODOKLNTKOPPPSRMSUUSQNTVNRPKRTMLVSKPNMAVRNNRVKRPNTKOOPUMTUOMNVKVLQNKOQQSM","isNfc":false,"nfd":"5f6157eab80415e7","nfc":"3e8d868c8ca6d837","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a30426dfd43ba6ff","nfc":"ba96d8b8d2fbdd03","nfcEqual":false},{"in":"GMPKRUSSDRUSMLVPOTOSVLSFKRMRNOKORLTSTTCVUOTVLKPMKMMKVHSNK","isNfc":false,"nfd":"e9dfb092ba595894","nfc":"3e7b8d61fe7602f0","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6cc4df7f2a5bac18","nfc":"6cc4df7f2a5bac18","nfcEqual":true},{"in":"QDVTPQVUKONQTSSKKPNPCSMUKRJMLRGKOKPTURU","isNfc":false,"nfd":"7de66486c5783f9a","nfc":"5ea0bed988b31041","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"262d3f2fd4fd5f36","nfc":"262d3f2fd4fd5f36","nfcEqual":true},{"in":"TBOUOTQKROVMNLSNMSVPLOSVORUQKRMLNPRMNQLQLRRRMUTORURSRQSUMLTHUASMQJV","isNfc":false,"nfd":"d3a59360dee68654","nfc":"17c6e05324041a1a","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a895caf5fd2ead26","nfc":"55408b6a1a3b2bd9","nfcEqual":true},{"in":"LKPTVSKTQSQNSMNNMPULOVLPKULVRLMBTNTORQLPQUMKPISPMQNKNNLNMSTOSKRORR","isNfc":false,"nfd":"311ca31654d4e96a","nfc":"38c455c99b003a0e","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"25088140e02f1f8a","nfc":"25088140e02f1f8a","nfcEqual":true},{"in":"VPVNUNVSMNLNQVMUUUSMPLLPMUKKOOSDUUTQPT","isNfc":false,"nfd":"2e48ffa10c94f6ab","nfc":"f27603f05dab1428","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"58aa5ba7a7b8567c","nfc":"0727d6230c5c67db","nfcEqual":false},{"in":"KUKKKKQMNQLOSTUMVTNTAPUVLLJN","isNfc":false,"nfd":"9894555b6534258f","nfc":"d98d137d3d0c9852","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c6c11de82aa119c3","nfc":"c6c11de82aa119c3","nfcEqual":true},{"in":"PJUVSLNQLVMKBTOKNTUQNPRMMKTLNP","isNfc":false,"nfd":"fc83778b5ec63d0e","nfc":"2ef9d2aac0ea2eb2","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"ae0016cb965166aa","nfc":"ae0016cb965166aa","nfcEqual":true},{"in":"GQVNKTLNILTOSKTOMEKUVRSOKT","isNfc":false,"nfd":"decf4411f2e1d4e9","nfc":"b76b6ae8dc26ea2c","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"16c19f8e97c175e5","nfc":"ae4c436c651ef63a","nfcEqual":true},{"in":"KSPTLSKRRKSRSRSRUPPMKKESLTRPMOMV","isNfc":false,"nfd":"a9be9cf975a439f6","nfc":"1150693f6d9c21d0","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"44cd5c61966f206a","nfc":"7dff00b2d4f260aa","nfcEqual":false},{"in":"OSHFTTKKKVNSRUUSSOVQNRATNVRPHVKQOTRQLFMPMRMRSQKUTTMVKLUVVMURVSMRORLMPKSPKVSOKVLUKORROMPSSVLSOSKN","isNfc":false,"nfd":"df3d2adf059f6bcd","nfc":"df3d2adf059f6bcd","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"2b69b5ab26288c26","nfc":"0d3e10be969555d5","nfcEqual":true},{"in":"BKNPUNNSVLMLSQOKLOMQKOVOMSKSLRNSOUSVMOORPRTSROQOQEONDTNRLGNTSPUNNENRMKKSVTVPMNRUMNNPUK","isNfc":false,"nfd":"6b759f7a7f253689","nfc":"e352fbb68dc99ffa","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a1c233babc8badab","nfc":"5aa557928999395e","nfcEqual":false},{"in":"EPMSNLQRLMVNPONLLPQLOTLOLKRSOHGSVKUVPRNQLVSVALRSUNSSTPSRKSVVQUMNNPNPULQQCSNLPOLUOVTTLRORMOVKVASPOOMMVQKO","isNfc":false,"nfd":"ab5bd22d64e3b0d5","nfc":"444cc7d3ce0ebd52","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4dec7457edaa955a","nfc":"4dec7457edaa955a","nfcEqual":false},{"in":"HUVVURSTRSLBSQPLMUVNRTOOKPMROSSKIUSTUMKVSPVTTLKCKNNVTPUOVMO","isNfc":false,"nfd":"18491e98816cdc6c","nfc":"32f556f5ade77b51","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a24fa7b896615b14","nfc":"a7c52eaeaf0c2709","nfcEqual":false},{"in":"RQRMMTNMOKNKPMVSVSMQSKRKPMMPLVOLNPLMULUKKTGNVAOUOSNVTQQPSOTTNMVQHSVQCHKSRQPLRKLRVPLRSOPOUTTVVKUTKRTN","isNfc":false,"nfd":"4479c79501c0dacb","nfc":"a05f15daca8dd68e","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c7a29342093593c4","nfc":"5c496914a84c413c","nfcEqual":true},{"in":"PDURPUVUMVRRPSRPKMPNUTQULNTTLPTLDSRQMRLTSSQNQTSQNQFTRTVNLTPUL","isNfc":false,"nfd":"a0dfd7281456da52","nfc":"0c1bab4a9854154b","nfcEqual":false},{"in":"ANMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"9e0a87c9a93ceade","nfc":"9e0a87c9a93ceade","nfcEqual":true},{"in":"JVQQAOTKUUVKSKMRLVOOQONLNTPPTPKTKULPKMTLTOLRMKRQMUOSOVPVLPPRUSNL","isNfc":false,"nfd":"41f57586aeeeb8ba","nfc":"dcbb49e0f2bef088","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"8247e7824fb4211c","nfc":"8247e7824fb4211c","nfcEqual":false},{"in":"CTKLOLMUTUPLUMQUSNMQNOKUPKSTEULOTVSPUPURMKSRKSKPKTLVMPL","isNfc":false,"nfd":"af0602236efd8e19","nfc":"de7ed3b903f90a6a","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"363d183871e4ada5","nfc":"363d183871e4ada5","nfcEqual":false},{"in":"ORULUPPDTKJPROMPPUTPQNKVOPMOQL","isNfc":false,"nfd":"baf17b9bfa5bfa39","nfc":"087f1529c2bc46ad","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a7d4bcec0ac07b9b","nfc":"a7d4bcec0ac07b9b","nfcEqual":true},{"in":"MNNNOPRSNLSVPLNOLLMTTMLQKDQTPHSVTUSNQUPOUQUVRVNSRTRSOVRNUVVSRAUSULOKNRVMUOTPONTPSUPBPSKRLMMNMMMSTM","isNfc":false,"nfd":"4954e34aebf504b5","nfc":"8cf521836f987d1e","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b8f4759b80ab8c53","nfc":"950d60abc04c305b","nfcEqual":false},{"in":"IUNVSKMUVKSQROMHKPSKVUSSMSFMNVLRSN","isNfc":false,"nfd":"dd02ba30f2843e76","nfc":"9c19b7162251d614","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"748ae57fb62c1431","nfc":"748ae57fb62c1431","nfcEqual":true},{"in":"GRSUOLSVNORPVNUVQMQUMVGRRQTOMUSKSSLMORRAKNTMOSRQRMKVIRVGTPGMTQVL","isNfc":false,"nfd":"20e312282185a984","nfc":"f236d13afdb35f2a","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"73e2f729d1500860","nfc":"73e2f729d1500860","nfcEqual":false},{"in":"QKPTRUNNQUQNSNKVSLLOHPPVTRQRPMRTMVTVOULRNLTTOURSQPVTOLQKURVLNOLLRNULUULU","isNfc":false,"nfd":"64063e8bbb27e199","nfc":"64063e8bbb27e199","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4e7a411c058d8fe3","nfc":"4e7a411c058d8fe3","nfcEqual":false},{"in":"FBKSSPOKNUUPORLOVPNUPGNPMMMLUONPUHPQTUPAUNTVLMVVUTVORNMQLUOQPOGDTVMKTLPLVRONUKLRQOQVLTQQSPN","isNfc":false,"nfd":"c5594b33556a8ec3","nfc":"78fd2797c0e6b4ce","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"df5924af2c3932cc","nfc":"df5924af2c3932cc","nfcEqual":false},{"in":"KAVUPRKUUMNVOPSPUPMLRQRTTNNQULLLUNUVSSRUTUMPTLKVOPTMMVQVVKPTTMQT","isNfc":false,"nfd":"689bbb62a134a74d","nfc":"689bbb62a134a74d","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"895df7990dc7da3e","nfc":"b893c631a89f5244","nfcEqual":true},{"in":"VFSMMMVRNNRKMKUMKQUMPTSQLPULNRUCTQQRNKLRPRQVRLSNQTVNKLVTPSHPKBOLNUKPQTTTMUSSNLLMKRSMVMPRTKPUOMOQ","isNfc":false,"nfd":"7f91e56c37260eee","nfc":"f2a151868efb948b","nfcEqual":false},{"in":"ANMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"f8fcc47dab52d39a","nfc":"f8fcc47dab52d39a","nfcEqual":false},{"in":"TKQPKNRQTPLRKRLNSUQPLLMPQKULKSRSLRCSUOQUQVOROTLPRRKSOPSOUTUSNSVRTLPPPTQBRVSRSMVTVOSRKUQRRMSUNUNRLMU","isNfc":false,"nfd":"bd0b67c48d1dd272","nfc":"bd0b67c48d1dd272","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMBNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6f244e82fa967246","nfc":"6f244e82fa967246","nfcEqual":true},{"in":"SKNTSPMRVQPHNMQUTNOUKKOOLUQCUTKKTKUVVONQTLTMOUKTUHUMNQRRQSMRSLRTMNKTKVHSQQOPSKSUIMHQPL","isNfc":false,"nfd":"4ccd2692beaeb396","nfc":"dd1e25396186ec23","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ec42dfa967e8c4e2","nfc":"ec42dfa967e8c4e2","nfcEqual":false},{"in":"IMOUMLPRLVUVTLKTLOOQPLMSPSTVMMRSQPVPSLOPOKRTMSOKNRQRUVURVU","isNfc":false,"nfd":"5141a3e16dd0b8a0","nfc":"05266cb98596dfee","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"32633eeb93fdf02d","nfc":"8b061515399b9f50","nfcEqual":false},{"in":"UINNILOMQQOQTTPTTMQKTURPTINQUNMPJVSULMUTPERKLLSUMLULUUVQVN","isNfc":false,"nfd":"e626d21bde972337","nfc":"00e47b907251c73d","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"36bdc84dddcc7585","nfc":"f2639559f33789b5","nfcEqual":false},{"in":"QPSMSPGKVVRMOOPOQRTVUONNCLVQQVVOSVSUTLLTUOVLTLMRSNOJVNLVVTMNVMPMLNPN","isNfc":false,"nfd":"a75cb58aacf0e63c","nfc":"cf8f0b2ed680a3e1","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"98c3a1fa8224686b","nfc":"75bdc7f9a47da383","nfcEqual":true},{"in":"PQNSQPVKNLOSMLNVTMNNPQPQKPUMNKVKPODDLGOMKNFPNPLQKMQNOOPOLCRPMUSRRPTRTRLOUKPLMSQTNLQNMQPMVQSV","isNfc":false,"nfd":"508aa0f8aac54845","nfc":"2dd437334294737b","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c0e32c033f162c82","nfc":"c0e32c033f162c82","nfcEqual":false},{"in":"MPQCOOUVKPGPTUUGRMTNUVRVKRUMPVNKLTNJMMTSOSQTVRUVTPLUOGRUNUKUKLNMUESKRSSVMKUMLRLTLPPCTMMKVTOSMLRK","isNfc":false,"nfd":"c396404f2740e5dd","nfc":"a944a65ec05cc2f1","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"dfa6efe56aa49848","nfc":"dfa6efe56aa49848","nfcEqual":true},{"in":"VMSPTMPSQVJUNTRTRQLULPNUVULLUV","isNfc":false,"nfd":"65b072b9ff95f3e8","nfc":"57c01ccccaa5fe6b","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"8fbb50919bcc911d","nfc":"cb133155f7df12bb","nfcEqual":false},{"in":"STPLMSOOQQMVNKVNTLTPOMKLMSHNHPMRSTPRPUSQPVVLRNEPKKLDKMKTQMPMPNVTRMRUPSKVSNVONTNMKSSQUUHVVQSRE","isNfc":false,"nfd":"d363826b8b5e98a7","nfc":"1e10e56253ec3be8","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"d3ccf9cff46f802d","nfc":"d3ccf9cff46f802d","nfcEqual":false},{"in":"RKPQULVNTKKSQVTVOQTUJPPLKNSSUNTONLUQSMPVOTRQRNQKOLSLSPSVRQSTTRTVUOSULMKRQKLSUNVMRVEVUMP","isNfc":false,"nfd":"ab25f183d5e46029","nfc":"f2cc39a970b6ca92","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ea86eb918eb26d33","nfc":"ea86eb918eb26d33","nfcEqual":false},{"in":"GQSMNSPOTNKGVNLMOLKOLRONLSSKSTSKLOUCLTLNPVUOVLPUQLTPQRPNAULUSQOTRRSKKVPLVUSOUOUIQRMSNTOA","isNfc":false,"nfd":"f7d61f0da81b3d51","nfc":"9f43f40e1188f894","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"93cf5beebdceefa8","nfc":"93cf5beebdceefa8","nfcEqual":false},{"in":"SUSQRVSPLKLTOTKHRRNNKOLLPLE","isNfc":false,"nfd":"8020b51116d40b04","nfc":"a0e84b800fd29082","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5e3731aa3b998be8","nfc":"5e3731aa3b998be8","nfcEqual":false},{"in":"GKONLSOKVISOSMQLLVQSQVQNTKR","isNfc":false,"nfd":"7840ce608cdaf1f7","nfc":"a7798c6f455e4257","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"45fd3dbc3a976e9c","nfc":"454c2d86dbf52f3d","nfcEqual":false},{"in":"OKLRHUKSVQQLPPTNOOKLRQTOEHUTQKKSRQRVUP","isNfc":false,"nfd":"af4c5bea93983db6","nfc":"4930c65e6ae231ac","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"506c52ade03498e2","nfc":"506c52ade03498e2","nfcEqual":false},{"in":"DHMTSPLQURQKURVUOMKTSSVNSPSUKNRVRKNQVQRURLTPLOKVMQSNVLRRSTUNTNVLUPLSVSN","isNfc":false,"nfd":"cee2b5054c4568d7","nfc":"1274ce135765a7fb","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b394a2a62335ba72","nfc":"b394a2a62335ba72","nfcEqual":false},{"in":"NOPMRKRPPKLOBLBQANURNNLRVRPMVPJNT","isNfc":false,"nfd":"eb3aa5c7458178ce","nfc":"7d8074ba66075ecf","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"83a962da2feafc30","nfc":"84b953ff9504d9cc","nfcEqual":true},{"in":"PAUKRLNSKPQVULKKPSSTSVNTNUNPSNQKTVQLVQMMLRSKQOTVKTHLPSUNKOLOLORLUVPRLNONVTOMVTTMNVNNNSLUSTTLMNSTTV","isNfc":false,"nfd":"289fce9a6c9a9ae3","nfc":"289fce9a6c9a9ae3","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"11e156d39bf96413","nfc":"11e156d39bf96413","nfcEqual":false},{"in":"FTMPTGMUQLVUSKLVMNRSUSUMKUPOPVKLTVKRSOTVSUKKNQVTVUSOOUVUOLKPBIEKUMJSPLRKMOUPVSLVQULPSQKTRSN","isNfc":false,"nfd":"ea979650589f5371","nfc":"c30cfdb8c1337dc6","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c614b149b8a3a16d","nfc":"c614b149b8a3a16d","nfcEqual":false},{"in":"PSPTLKPPUTTPOVLQVKKSMNDTUUVOTLERKOKODNPQSOPMLQOUSMLQNQLGNKVPIOTQQSSTMQPNLRLQTLNTNRUQV","isNfc":false,"nfd":"62a85f75defa32e1","nfc":"7a951c709aba1baa","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ef039e6e6fcc3d6b","nfc":"ef039e6e6fcc3d6b","nfcEqual":false},{"in":"JDMTNJGPVOVUTTRPSQNKTTTNMUUKUVLSRPORNLNKORKOSLNPVPNOULSUOUSVQNTQLOKLNAVMTSRUVNTMDUMQOFPVQTLTRVLO","isNfc":false,"nfd":"c90e1c9a9694bd67","nfc":"e3859460084a2a50","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9da1f265cc558b21","nfc":"48386e7704de24ea","nfcEqual":false},{"in":"TUVTPSOMUKOOTSAPROKLRVUKQNUTLKRSTNRNUOKHPSOVOOTLPTKNSPNSTNMVSLLNQQLUPSPNMPURUSKLRRMMP","isNfc":false,"nfd":"4105c22af727bda8","nfc":"169832bdce91c668","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMGNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"0903fdab3b81dec9","nfc":"0903fdab3b81dec9","nfcEqual":true},{"in":"PQPNMRNPUSRLRTSQPPUNMMULQTTMLRKMKOIUOTURBKNUNMRONOVMMQTQLNQQNPVPLORSENUMSOKVVVPLKTQVIPOIVPS","isNfc":false,"nfd":"8bb9951fcf8bf459","nfc":"cc0ce55e37101fbc","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"354910de1a088650","nfc":"c050f5db91607cd9","nfcEqual":true},{"in":"LVTQQPHUUOPMPUMPLNUPLMNTQSLSNUVTTDUNVKOVNKULSKNULNQEMKRKRLNOSO","isNfc":false,"nfd":"1776c35771f64046","nfc":"c53da10480a7a0a3","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"886de1673e94471e","nfc":"886de1673e94471e","nfcEqual":false},{"in":"SPVKNSNOOOPTPKUPMTMKTKQOSTSSMH","isNfc":false,"nfd":"2ab415bc9831f381","nfc":"2ab415bc9831f381","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6b21e24d70072d59","nfc":"6b21e24d70072d59","nfcEqual":false},{"in":"MBNTVMSRVPNUQLNURNOOPUSKSQMLTTQQPUPAQOORNQSSSSMUNTNRELLMPUPTNTVOVKOTRPKQUMPUPOJKKTBPPMVOULQRMPVPLU","isNfc":false,"nfd":"460acebde3c1603e","nfc":"9aa1f6919189c280","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4bcabe9ebcdbc5e5","nfc":"4bcabe9ebcdbc5e5","nfcEqual":false},{"in":"BTKPVKTLRKQKAKPSQLIRTMQMOKNPJMMUOLRKTPVNSSNRPUKNOULTQQMLOTLBQNTKHKPTMQUROUOKKSOPUQRNNVKRRNUKKOV","isNfc":false,"nfd":"7f1eab76ea6b8972","nfc":"57ee98c7f217b50c","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6cfe68c27855bd79","nfc":"6cfe68c27855bd79","nfcEqual":false},{"in":"KCSVMNVRRRMQMPKTNMORKLPOLRKMOQUNKPKORLKBVKQIKSSQTMQTSTMUVRQTPV","isNfc":false,"nfd":"8a031d80cae2b268","nfc":"e167b9fc60c5338f","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"f276ce2ff11d8a3e","nfc":"9d5951b5a279be5a","nfcEqual":true},{"in":"MROVRQRTSSRRKTMQUSOSPUPRURSSQOMLPENPOTKKRTTRRPLSKLOVOJQLNVMUQ","isNfc":false,"nfd":"4c5c56afaf31c7a8","nfc":"beb7595ddc3072d4","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"87a5dc2bea25aa02","nfc":"d1d8932c08e649cf","nfcEqual":false},{"in":"UUTKVMPLQUMTVKSMRNTPNNTQSUQMHTRUUNQOSOKLURLQMLSSRSLRLRVKVUNVUOURMTRTQRMUTMSUQVMKMKNUTUBKPTVQNQRVMOQPPPKFTNQ","isNfc":false,"nfd":"a99d14152f008ad0","nfc":"44ef516ed283fe09","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"86ed731053c19625","nfc":"322e61f4784cdf94","nfcEqual":false},{"in":"GCOMOQCSTOMCRNNLVNPTTPIPRQRQRNUULNNNLTQKMNSQTKNLKOVMOUROQT","isNfc":false,"nfd":"c14a5482dcd30b62","nfc":"5d7a0fde97df33ca","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a7fddefe8d71ae64","nfc":"a7fddefe8d71ae64","nfcEqual":false},{"in":"PLPSTMNTQOQERROVQNKTTKNKKKQQ","isNfc":false,"nfd":"9c6d901eef2abb00","nfc":"939fc325c2128b22","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1c5be75d5a167b17","nfc":"d915fb3f15cc5c0c","nfcEqual":false},{"in":"OMOROOTKQPNMUKPLULVMLMSNONUUTSRTQOUCLSQMIQNOUURTKDVIPTSMMILRVSGOKRQITLTKULOQKKTRVLUKLPJTSQLOOSKMROLONKOTUQLT","isNfc":false,"nfd":"632a2fb66f31960f","nfc":"4c1dec1a0863e08b","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b522d212719f824a","nfc":"87aa196559cf25b0","nfcEqual":true},{"in":"DRSULSOQTQUPKTVEUMOLLPVLPKSTNCROPOSNSLMLQMPQRRMLMPVMSRPKTTTUKKRLSSTLPU","isNfc":false,"nfd":"e51c28835d6cfc08","nfc":"d91c3a0e291aeea7","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"22fd1249fe4da103","nfc":"854aabe4b0e1228d","nfcEqual":false},{"in":"NHKOSKMRTNQPTSMQRNKKUOMNPTUSUR","isNfc":false,"nfd":"c7745d6f317bf881","nfc":"c7745d6f317bf881","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"4cdd65a95170f8e3","nfc":"fc0b317486cde107","nfcEqual":true},{"in":"PQQKPVTLQMTTTUSSHOVSMTTKLKRKNQUVNRPNVTR","isNfc":false,"nfd":"90c549343c639531","nfc":"90c549343c639531","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"2039167d64d2c729","nfc":"2039167d64d2c729","nfcEqual":false},{"in":"NULLMTQPKOSVVTMKKULVRUNNUFKOULQKNRRKOSVQNQNOPQQNSOKOMTS","isNfc":false,"nfd":"284a2b0c53c73fc1","nfc":"284a2b0c53c73fc1","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a4ea9bcf4e8bd3ea","nfc":"a4ea9bcf4e8bd3ea","nfcEqual":true},{"in":"QBVSMOQRVLLVMMSLMPTNUTNTLOKSUPUSNV","isNfc":false,"nfd":"308abd304aec903a","nfc":"308abd304aec903a","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"16bfb79bb93b023e","nfc":"c18e3204f1b38d0f","nfcEqual":false},{"in":"UQNVKLVSMOOMVPKMVCJTPLUVQKR","isNfc":false,"nfd":"5bb2fa6026f342f5","nfc":"ab70fa2d7c473f1a","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8721591d39df6528","nfc":"8721591d39df6528","nfcEqual":true},{"in":"DPQLOUONTPUPRNPLSFKNKPRSHOKBOMPQKQLUGVRSVPRPKLKMQ","isNfc":false,"nfd":"83fa6fb599a3d333","nfc":"d85d4f2e4d9dd07a","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6823e3d1466dcad6","nfc":"14fc5b9265e8e4f0","nfcEqual":false},{"in":"MLQGNTOSRKTVPNSELMMPNTSQSQSMSTNRKNLQSQRTTQULUVPLKLTKNPTTQSTPV","isNfc":false,"nfd":"539bc0263eb35957","nfc":"e947cc6cb320583e","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"45ab7de69acbe42a","nfc":"b7c4772e335209b3","nfcEqual":false},{"in":"SKKNTSVRNULKQTLKOVNKSROOCQKUJVQNVNSSMVNMSMSUOULTOKUUPKSKMTUSJALQTUVMONPRQPKNQOPSVMMNRMKRCPR","isNfc":false,"nfd":"1ecf1d7205c25c1a","nfc":"8a0a6571f64b1614","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"df81458b8e03e1e9","nfc":"64de7274b364a583","nfcEqual":false},{"in":"KMRUNLTMPQSUOKUOPLMVQKQIPLMOPSVPTORQSTSMLKLMPTVNQHRNMRQMOQPTMTOUVRKVMRSTNOQKNKUVUMQRRRSVQKKQL","isNfc":false,"nfd":"3e05255a362053ef","nfc":"65b3fcec2c022b49","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b828ca977190811f","nfc":"b828ca977190811f","nfcEqual":true},{"in":"BALCMFURLQUUMVHLOORUUKKQPTMOTTSPMNOFRLPRMRSLOVOQKVNUUNTVRMRUV","isNfc":false,"nfd":"e605b53cbd64db9b","nfc":"da8e4518756ff52c","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b39984a96d4a1a5c","nfc":"b39984a96d4a1a5c","nfcEqual":true},{"in":"QVVSORUUSVQVMNUVTNMOMNKVPONMTSBUNKSVQQSPKSULUTQUUPROCKQLOLQRMNKLOTURNUSOOOONLENQRTLNKNLKQMS","isNfc":false,"nfd":"088a3fc57a42a693","nfc":"64e3dba0040697f2","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"662350073e53b7ee","nfc":"662350073e53b7ee","nfcEqual":false},{"in":"CMQMLUHUSPKUVQPKUKUULUNSPVQOVORNQO","isNfc":false,"nfd":"eacda6e02fc15e3e","nfc":"eacda6e02fc15e3e","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e1f6548ecab86ce2","nfc":"9d68af6c4e05f9c2","nfcEqual":false},{"in":"LORKMUKSSLKSOVQSPLRKKPJRURMURO","isNfc":false,"nfd":"66def21547ed4e9e","nfc":"c46769786119dd88","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a64edc0f8dc45f28","nfc":"a64edc0f8dc45f28","nfcEqual":true},{"in":"PNLPRLMOSOOKKLUSRRVRUUKOOKKROOUIKVSUSVSPLOTNNPQQQQRUOLQLKDPNMQLUSLLRTMKPSTTRMNMSLOPNTOVKURMTOT","isNfc":false,"nfd":"fb2950ccfdda7c52","nfc":"4709add65ec8a696","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMFMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6432110723563ac0","nfc":"908736f61b6736f0","nfcEqual":true},{"in":"KQUOBKMVTOLNRPMPQVMNOLNRQVQVVOVTUHPRUQPSQSPKMLNPTUVRRSTNNSRKMOPOPKSV","isNfc":false,"nfd":"dcfb77b985c03abd","nfc":"26bb47ef0b1cf041","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a55998b439e236ca","nfc":"a55998b439e236ca","nfcEqual":false},{"in":"PQFLMNNUKRVJLKSTKQRPGKLPOOLUKVKVKNV","isNfc":false,"nfd":"000e118dc0bfdeec","nfc":"b994c855f2a4e6a2","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"260ff38b277ce454","nfc":"260ff38b277ce454","nfcEqual":true},{"in":"ITTQMKLSMLPRLPVOKQVIQURVUKUPSRMVIUPTMKUPFOQMVMOPEKNRVVPTOQUMRNURPVVKTVVQQAUVRUNVQTQOSNVSNSQQMPKNPO","isNfc":false,"nfd":"71fed82e3dcbcc01","nfc":"1a2e0568cfc6ada7","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"db300176f7c16833","nfc":"89690eeca7b5480a","nfcEqual":true},{"in":"PRPQNPSQMKPQKMULULLLSPMRSTKQMRERKMULNUPMTPTNNARQLTOVKRRKKPNRFLUPMRPROPSNKLLSQKMOPULSVM","isNfc":false,"nfd":"3803227eadbb07f5","nfc":"061538da1d3612d7","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0bd4c7d9cbc89931","nfc":"0bd4c7d9cbc89931","nfcEqual":false},{"in":"LNOLQMKOMUQPVPPUPSPLRTKVPTPMOVUTQRHKPSVURKSRQLMUVBMRQPLLVJRRTLKPRQSNQTOIMQUQMUSLMULQMVNKULONN","isNfc":false,"nfd":"bf306be8f96b34bd","nfc":"63033caa22431bf5","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e6abc39ba0d4bf1c","nfc":"f1b40144c113892e","nfcEqual":true},{"in":"KULMQPMQMPKKPTORTTKQONORV","isNfc":false,"nfd":"ecc9f7642a949d91","nfc":"ecc9f7642a949d91","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"11bc08bef1841141","nfc":"17f769cb09fbdb5b","nfcEqual":false},{"in":"ASKQUSQPVKSRNJTIRRLTSOMRLQKSVNMSRKUTNOQRVOPNLNNOMVPUPQKQTLLMKROOOML","isNfc":false,"nfd":"fc7fe01bfdf39030","nfc":"0ae78dca1a419099","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"1e4c95af590a3d87","nfc":"925cf0879c58feb4","nfcEqual":true},{"in":"PKRMPNPKVLSURNRSNGPPOMNNOPRPLRP","isNfc":false,"nfd":"d67a1409ff27dfa6","nfc":"d67a1409ff27dfa6","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bc67bc13aff96213","nfc":"bc67bc13aff96213","nfcEqual":false},{"in":"RMSTOKUUKLLDPQOSRLKLNKTLKOARNSMQVRNTKRPEKMVSKQMMNQENSSRFPFRVMRSSVSVKP","isNfc":false,"nfd":"eb9909be8a17b210","nfc":"0fe42395c60e5826","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"008f0e97574e39e3","nfc":"316fd3a678b1b534","nfcEqual":false},{"in":"ONOLTNTLQPRMKAKULMOKORPPSPSPMLTSTMNKESSTTNMVUNOQLMTJPTVQLMTN","isNfc":false,"nfd":"1598b25d01a8fe35","nfc":"057f5ba8d7aa8021","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"28b6664c107d212d","nfc":"3e11a96cc23169f3","nfcEqual":false},{"in":"GSRVTVVMKVVRKRMLORRQTRLUMSQDMRKLVSQORTPONLNTVTQURTQLOOVNUQURMMUNVRKNMVTRVUQUNURROVTLVBPOQKKLN","isNfc":false,"nfd":"e5bf2caa0c9e358c","nfc":"a438d1d33210d761","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9078d3998a3d9135","nfc":"f95263daf3d0321c","nfcEqual":false},{"in":"POTOKUUVSQMQRUUSRQLKMEMMRRUQNURGQVLQQUUUTMOMTLOLRONQFPVSNQVULQSR","isNfc":false,"nfd":"fe65d7f75c8442a4","nfc":"335231a049f74c35","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a063573773f5f334","nfc":"b43701e6ad065e8a","nfcEqual":false},{"in":"APLRUQQVLOVNSPETNMMTLTKUUBSKKNSITSLVKTOPQOPRJVUPOVRQSTHOKSTNNMLPQLTLHTLVLMLPKUNPFQNLLOUQMLOU","isNfc":false,"nfd":"b548d0db1ddab137","nfc":"0e8b8a32d76bcb44","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6933bf8cfe3de12a","nfc":"e87c2adc02837afe","nfcEqual":true},{"in":"EEMRQVVVHQQROVVNULSJVOLSUSVNQKENVKOMKURNPOPLQLKVLQQPOQLKSTSVVRRKVVLOLSRVTRNVKRMSNUDTPVTPNTVR","isNfc":false,"nfd":"8a49f56829d047a1","nfc":"44bfab57145d2b61","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b33de1f67dca3117","nfc":"8e66e4d526cdfc5d","nfcEqual":false},{"in":"VATVRUTOKNQSMOSTMSSKOMKSUQRMNRJSORLNLTRTMKKKUSMOVPPUSVLSQRKUV","isNfc":false,"nfd":"7b8bd85a5c4df83b","nfc":"137bd159df0b4efe","nfcEqual":false},{"in":"HMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"4fbce0f97eefbc0e","nfc":"4fbce0f97eefbc0e","nfcEqual":true},{"in":"FSULNTPQSOTVILNQSREOULMNNNSLOMRLK","isNfc":false,"nfd":"bbbfc94b21adb359","nfc":"8183e8a05ff2cbc3","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1af57a2d821f45c9","nfc":"2d8714abcd75997d","nfcEqual":false},{"in":"TOKSSKMSSVNQPPTTPPQONVVVMPLMMUOSLVURROOVPNMUOROUUTLSMTKPLPSKUKSRPUMFBMKKVMUOQPNSVSQVPVQKSRLVLVMPRR","isNfc":false,"nfd":"deea5a84733a6452","nfc":"deea5a84733a6452","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"0fa14836915f6e53","nfc":"0fa14836915f6e53","nfcEqual":true},{"in":"KLNLVANABOSRSTKLOLUTQOLHQNUVURBAKOVPKSQOTDMRRUTRVVKKLRNUTDMKQUVUEQOINMHETUOQUJSPKNNKTMRPTTOSQNLRR","isNfc":false,"nfd":"f436ac262f42d491","nfc":"ffc5f3e40c440f3e","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"c76313607490c1aa","nfc":"a8eb732af92075ad","nfcEqual":false},{"in":"DRNQPNMQUVNKUPQUGNMVUSTVEMERTTPQLROQMMVKTOKLUOLKTISLKVNPVUSS","isNfc":false,"nfd":"ccd5d25863e9718f","nfc":"d30ddd12ad905140","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"55070f56373b6930","nfc":"6be5ec242393fb57","nfcEqual":false},{"in":"LQKLKLLTUOUKNQMPRLKPTTKRKTNUMTM","isNfc":false,"nfd":"66826d8ac70b39e7","nfc":"66826d8ac70b39e7","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"20bf2c94fdd1136d","nfc":"018ae19cd84c1e5a","nfcEqual":false},{"in":"PSSSRQMKQQKLPSUQQSONOKNSNSOMOSVRLSMUNKVPRPJMMNPMNVKNRKKTRSGAPUTOTRUTSTQOVQROLKORNLNSMK","isNfc":false,"nfd":"ff2dd04ccdcc9001","nfc":"e64830a2057e3c29","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b39984a96d4a1a5c","nfc":"b39984a96d4a1a5c","nfcEqual":true},{"in":"DGLRSSTLTUSSNOKUTPSNRUTNINTSRVUKSOKSNUNSRTRVPKKVLKPPRSVKORLSP","isNfc":false,"nfd":"3ff4267842719692","nfc":"a45d24b7f24a975f","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"58cdd22d4a70d13b","nfc":"58cdd22d4a70d13b","nfcEqual":true},{"in":"AUKOOMLUVKOQVORUPVQVONEKSROKLNNPVRNMUTMKPKHMFNRTLTTNONQRKRPNPLKRKPKNKVTTUMCOSLMNROPUOQRRTSLRTRSSVNKQPVOR","isNfc":false,"nfd":"9bb5f76cc8ed3f03","nfc":"bf34673b3a77c612","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"713696b933a59d51","nfc":"713696b933a59d51","nfcEqual":true},{"in":"AIVPTQKAVNMROOSOVKQBSVPQQSOQVEKUTTMVPLQUKLTQSMLPRRUQOQOKULPLKTLRRRKT","isNfc":false,"nfd":"8c95c35dd6192049","nfc":"c3b7b3b50e1740e2","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"49a5e544ce1dc691","nfc":"dd76e17d9f1321b2","nfcEqual":true},{"in":"MRLQLNVUVOONRRTOVPSTLOTRRLTMOKLMVQNUMHULUSNLSLOKOTNMHROVOESOSMTPROLMRONRPOMSVKKQUUPFSTSRMUTOTNLSUQULPQLSQPRTQO","isNfc":false,"nfd":"a25e0d448d38b019","nfc":"2c3dae8d5f256269","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"afe7859a0f5d1875","nfc":"afe7859a0f5d1875","nfcEqual":false},{"in":"EEPHKVQLQUSSSLMCVOMKPSUKSTLPUMMRTUTLLMGQMTNSUMRVKLONMLPMSUOVVURVLLMKODBVRPTVTKTTPQASQSLUSMUKEUUONBRRPO","isNfc":false,"nfd":"31ed2556546b15e2","nfc":"aff8332a216d1043","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"68469f6d218e6f59","nfc":"60b5d6190217781b","nfcEqual":false},{"in":"LTOPTNKPVKTTSTVRSLTUUMUQUUQLSRUSMRVLSOUSMOLOQMTKSKTNKSKOTOPMREQUSVTKUMLUQKULVVOUKUOTKRVNVN","isNfc":false,"nfd":"601bc737739f0ec3","nfc":"c0fe3c6f74d814d1","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"9cb5ab628c8ab7f8","nfc":"9cb5ab628c8ab7f8","nfcEqual":true},{"in":"KLMKTSVPVDNPNTVSLPMUVQSPVMQPLSQ","isNfc":false,"nfd":"0b7fe7ff038fe834","nfc":"333f783f743f060e","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"281d1a51fd998d0e","nfc":"281d1a51fd998d0e","nfcEqual":true},{"in":"GONVSLRMNLNKKTNMTQUNOLQPVKURJUKUUNLSLCSIQQROKNPBMTOQTMQVRUKRR","isNfc":false,"nfd":"7d38fe3438c8083b","nfc":"3436222fa989c01a","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"2cac181d3f4fc794","nfc":"2cac181d3f4fc794","nfcEqual":false},{"in":"TKNUSVVNNPNNMKDOUSVVOMVQSMRNRBTPPVNULMOLONTQSVTLLMPNRSUMPPTPPMNPKKM","isNfc":false,"nfd":"34a7f24532e8016f","nfc":"0f1d62affef78915","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b6bef1dff6fa6a8b","nfc":"5736833f8893bd35","nfcEqual":true},{"in":"BQPVQMUUMOLLMTTVTLTNTLUVKUCLT","isNfc":false,"nfd":"98610b2fa7230598","nfc":"98610b2fa7230598","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b522d212719f824a","nfc":"87aa196559cf25b0","nfcEqual":true},{"in":"LBOQTRTONSKTMMTVKLLTNNMMNUOTRSLAKSVUTVEPNLTSVVKGPSVKLLOALSKNRUOTVGTP","isNfc":false,"nfd":"45a5c8fa92038ea5","nfc":"78596081626aabbe","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"93921c9a60b88084","nfc":"93921c9a60b88084","nfcEqual":true},{"in":"BLUUKONUVQLROMSNKLLRKSNKMPP","isNfc":false,"nfd":"5e3d92991d16b439","nfc":"fc1a5b60dc48122e","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b8ae2d86f0836e98","nfc":"844e552373fd5768","nfcEqual":false},{"in":"OHSOUVSKTOVONSLLSQRLTMUMVUOVUKLUOTUUPNSPOKUOUQRMRNPUROURVTMOOOVKFVQTNLKLNUTLNQUQSKSLVUTTNMNUTTGUON","isNfc":false,"nfd":"43e1a2ebaf4576d5","nfc":"43e1a2ebaf4576d5","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1257c15451766e77","nfc":"ef4b4e3be6239a25","nfcEqual":false},{"in":"FKVPOTNSVVONURQMTMRMVUQUTRPNTMJOTNKPSLNVRQRRQTKRNMSOLMVKVLVNQN","isNfc":false,"nfd":"c937c6351cfc698f","nfc":"a62aea4395b389ba","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"76df052d4cd93cd8","nfc":"9e25a2e9d6678aa2","nfcEqual":false},{"in":"QENOQKKRSUMSSUKMOUPSTSNQTFSNUMPLNSQRRNVLRSSOKMPQSLRKJMRRKPSNQBTSSTUQUKRLTS","isNfc":false,"nfd":"ac22cf0c026e492f","nfc":"fd4470b39d26b007","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"abd64f7b936262f5","nfc":"e323f2f32a9c4698","nfcEqual":true},{"in":"MTKTOKRPRLQUOVQVEOVQSMLOVPRONLUNOKKQMVVUBKQLNUTKOTLUQSRMPHUTUM","isNfc":false,"nfd":"060c330ccbb923b9","nfc":"f741223c56633651","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"11e77f7f6ecde430","nfc":"11e77f7f6ecde430","nfcEqual":true},{"in":"GCSVUMUSSIMPQVVTMPONMUUNMRMRMIRNVVNMUVOVQPKNPVSPPUKKRPLUQSRNKVN","isNfc":false,"nfd":"49c1359a7446e18a","nfc":"f56a81cb0e20c0de","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a4bba782dca07069","nfc":"a4bba782dca07069","nfcEqual":true},{"in":"KSLLNSMTSOPRTSRVPUTSKLKVUKRKURRTNMVPULQKVUMSRTUQKKNPVKQKMUSUUUPUNTVKGVT","isNfc":false,"nfd":"ee3a57dee8bab714","nfc":"ee3a57dee8bab714","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4eb39f4f946716e0","nfc":"7e1bed9f8daced2b","nfcEqual":false},{"in":"MOKOKKQPLSQSNSNTVTUNNQPKSSUOHFUPSQKOLLPTKKOSKKRULRLPTPUUAKQPDEUSKVTRQUQSUSRTVTMLNPLPRSKSOKMPMUNSP","isNfc":false,"nfd":"b37ddac2bb63b1df","nfc":"94fa7f231e121602","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9a4884d9b419c287","nfc":"ce89cc6ccee1f989","nfcEqual":false},{"in":"SQJLSSNKQNOUTQQTMUVNVMOTTMRPOLRKSOSUVP","isNfc":false,"nfd":"517c028e2213451d","nfc":"ff245ba09858ec26","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"171389f347bc1490","nfc":"171389f347bc1490","nfcEqual":false},{"in":"CFVQVROMMVOVKPKSKOQKNDKRNTMFMVNNSUTSLQTRVROLTREVKVNLVUOLSRUL","isNfc":false,"nfd":"b8642faa91a81901","nfc":"8bddc96b5e8a04dd","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bbfab3a669c79365","nfc":"2d61055d1c6c81d6","nfcEqual":false},{"in":"UONLQUURPQMRTVVTNPUPUPNPMUTPMVVSPJUMRLRRMPRKLKTLPPRQAMTOLLKVRLKUKV","isNfc":false,"nfd":"2b792f2d5527163c","nfc":"db2341a2ee4d44b1","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"662350073e53b7ee","nfc":"662350073e53b7ee","nfcEqual":false},{"in":"JNQOPKSOHUVMLMSVNPPRONQLLMVSPVTGSNKNUKTTLMUQRRORVLMNKKPRVUVKUPOPTNQMVVSUOTPNSDVNUNTTPTTMSTPTOIQNOP","isNfc":false,"nfd":"6892645117d7608c","nfc":"f8c936ce7b93731a","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e2661d5d498e5965","nfc":"9e204ae55b73a3e7","nfcEqual":false},{"in":"FMPLKMULNREUQOPUQPTNKNFSMR","isNfc":false,"nfd":"7f6dad7098ed1dc2","nfc":"ad0bad90fa4fd2f8","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"51772489be280219","nfc":"51772489be280219","nfcEqual":false},{"in":"VVMTUSLTRKNVRRLKTSMPPRKVOPNPUTMOMMO","isNfc":false,"nfd":"f2a7059f556f94aa","nfc":"f2a7059f556f94aa","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4c9974f2a1090a5e","nfc":"4c9974f2a1090a5e","nfcEqual":false},{"in":"IQLVLNMNRULRPBONLKLPLMURNJDRVVMUORSLOPMVSMKNRTPUNLMNKTROUPK","isNfc":false,"nfd":"1a4d0672f227d1c8","nfc":"1a2a73a35463843e","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMGNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"eeef4e1b4c5ab484","nfc":"eeef4e1b4c5ab484","nfcEqual":true},{"in":"ATVKNPNSUOVTNOTTVRQSUKOVP","isNfc":false,"nfd":"64c41de0b5d360a6","nfc":"64c41de0b5d360a6","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"381a5f0c5ad36707","nfc":"f490da986a889812","nfcEqual":false},{"in":"OEUCPUPOTNKUQTNTRNMRVUUOQOTMNNR","isNfc":false,"nfd":"c0f2495fe9cf206f","nfc":"1313e73d0d72d5d1","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"df5609c628db4af9","nfc":"dc0bc91c505c0dbd","nfcEqual":false},{"in":"HIKQMNKHKRPOQNRSSSRTTRLNFVNPVRNMKUSQLKMKUOPTVRSQVNTVLOTUTLKTRVPDMLRUMNOSVMNOVRLVSKNRMRPSQVKNLRLSUQNRSVQLQRMN","isNfc":false,"nfd":"9acdf9cf74b0c313","nfc":"1bc75441ff7e5729","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMGNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"38efd269b1345495","nfc":"8cfb4578f64735bc","nfcEqual":true},{"in":"DBLPUSPTQOUTNQVKNLGVVTVMKGRSMNSTLLMSUNSMQRTMSSKURQOMPRTLRUSVNVKORNQROKSPBSRVRLSQKKJSROVOV","isNfc":false,"nfd":"a89c49e6beea011e","nfc":"9f298e5529666ffd","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8f0e2df1fa8c47ec","nfc":"8f0e2df1fa8c47ec","nfcEqual":true},{"in":"NMLJSPORPLPGMKKSOMOPKUSMQRRPQTVUOVKCVSNUQSVSMRUVOLVLRTU","isNfc":false,"nfd":"34ff2e83dd02165c","nfc":"7a313eba66d78c17","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6cda8713b9719e29","nfc":"6cda8713b9719e29","nfcEqual":true},{"in":"AOOUUSTRNPKPVPVKPRMOLSMVKTVNKTMTPHVVRURLMRSPKTKPROLTKROONDU","isNfc":false,"nfd":"0b2f4f576fcd55a8","nfc":"94e95fa74d45eb97","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e74ffea5684e6931","nfc":"e74ffea5684e6931","nfcEqual":false},{"in":"DLTTLTMSUSSKNKUOVMTVTQSMNPNLTMMOPQTVTDSKLLTUROUOVAMNMTRRNKNUQS","isNfc":false,"nfd":"2ac31e085369c948","nfc":"ef137bf72a7c2c90","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"ef6c32b7781c9089","nfc":"182e0a2430dd18d8","nfcEqual":true},{"in":"MVPLTVSUKKPVVKKLNKQSDNPUMVKTUMPPPRLLSKSVQLQFUKTQKSTTONTOLQTQQTPMOSLTSU","isNfc":false,"nfd":"b6d0010aa6457d71","nfc":"8b92f86137619e87","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMMBNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"47a16c0675d02c94","nfc":"47a16c0675d02c94","nfcEqual":false},{"in":"OOOOMQPLQKPTTPSOSQMSGKPKOTRTTQVQLOPLBUUOMOSSOVPMNRMOQUUVTROSOOOMLUSTUQUOPMQLQLVLULQKUPSSKMOQOVNQUOVRTQONN","isNfc":false,"nfd":"ec906d7c2f77b182","nfc":"ec906d7c2f77b182","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"808553493712f95f","nfc":"808553493712f95f","nfcEqual":true},{"in":"DMPOTVGPNTOPLOPQQRQURSKPPLVVVNPJSLOBJNLVQNUOVUTUVLVLVOVNKNVPMPMTTVNPQPTNST","isNfc":false,"nfd":"de6b86ca9abc751a","nfc":"acdc9c8575111c39","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5b7a2fd976c40baf","nfc":"f30f09faf6b8853f","nfcEqual":false},{"in":"EUUOPOVNTSSRTKRLRKRTQLSPPVUVNOPVSOQNEMLOPVQTMCVMNPSQSPVTOPMQUKRR","isNfc":false,"nfd":"ee7809729898ef62","nfc":"4a8b9d8d6eb4f366","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMDMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"fbde3338a2b83723","nfc":"1f7f23f698ebd171","nfcEqual":false},{"in":"EVVMLQPMQSLVTQNUPNLRLEQLRLSTQMMQOVTQRQQFBLLDUNPPCPTRKKOLMNVNQMSPRKTSMVNDMHKUKRNQOVLSKRRLTPSLTSOPQKS","isNfc":false,"nfd":"3ad9917beac08ecd","nfc":"7e70a1f882f08866","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMINNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6b4d70cf24cfd892","nfc":"6c2b4a9d51719768","nfcEqual":false},{"in":"PUKKRKNUPLOVKENVRLRPVMRKRSQRMVMMECTMDNNTOLMSNLMKNRUPTLFRLMURRSKUVSSBKUVVCQVUSQUTOSNPMDONMVMNUQVSSELTTNQ","isNfc":false,"nfd":"6961e84624101205","nfc":"98f3547b08f1be5b","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0077656213c1d5d8","nfc":"e52d822f89bfa64a","nfcEqual":false},{"in":"KOMNUSRNTOTNPSSRKSNUKTVOTNMTLPUQHUBRRORTNOVVLOSMOOQSRKSOLKNMLTLKUUNROSKKNHMSQUVNOPVCTPTUV","isNfc":false,"nfd":"1a73b3c45b035a14","nfc":"cc37fce1a2c67f61","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMJMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"3937d812eb46e61e","nfc":"36c1a4c414ebb6b0","nfcEqual":true},{"in":"ATLQSMQVLROTQVVPQKUOSVUVLRPRSMTOP","isNfc":false,"nfd":"026f84543a33893c","nfc":"026f84543a33893c","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"adc17f4e98e85d13","nfc":"adc17f4e98e85d13","nfcEqual":false},{"in":"QNRROQNRONMMLPOMNOUSRLOKRRLK","isNfc":false,"nfd":"957f9ccfe207e6c5","nfc":"957f9ccfe207e6c5","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"34b9ff9207952c57","nfc":"34b9ff9207952c57","nfcEqual":false},{"in":"NPSPURMOSSTJKMUQVTQKNKKNFRRKPRRRUOPOTMTUESRTTMTMVRUMVPVMKUVLSRUQNSLSOSVAUVRDQVSNQKSLKVQPPSOPRTNOS","isNfc":false,"nfd":"04731d8e5b5f99a2","nfc":"fae863baeaf81354","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e9767215b87b83bb","nfc":"dfcd79c0b0763955","nfcEqual":true},{"in":"CMTPSKMROPRQQTPOVQVLPKLBPQVOSUUVVK","isNfc":false,"nfd":"10974af81dd0a868","nfc":"10974af81dd0a868","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"79d72191b82ecb2d","nfc":"79d72191b82ecb2d","nfcEqual":false},{"in":"QPOVVRMKRTKQNTQMPMRVMOUONQSVPRPNJAQNUNRORNPNKSLMQSOLNQKNRORMIMQRPRQR","isNfc":false,"nfd":"8712ddf0a5a8a8dc","nfc":"e4030f7e76dc8ca7","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"662350073e53b7ee","nfc":"662350073e53b7ee","nfcEqual":false},{"in":"TPTRRNMPCSPOLPKNRUMSMRUN","isNfc":false,"nfd":"ba127841817a2787","nfc":"ba127841817a2787","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4393a5648951af3f","nfc":"bba67ee033345e64","nfcEqual":false},{"in":"MVVRKPSOUTNMNUKNOUMVOVDLNJNLOSRUORSSQUOSSVKUNQVMKRUPTQSQOLNNMRSVSOVRNOPTRAROTMUNLMLLSKP","isNfc":false,"nfd":"217d7d2bf08133ea","nfc":"51ff9874968ae9d8","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"cf01c3689e4f0502","nfc":"cf01c3689e4f0502","nfcEqual":true},{"in":"UVQOTTPVSKOSOKTPKUVCPKURSRHOQRQLLMQSQRLQNNNNRSNPQPQVNVKASMVQOOTNRRVVTO","isNfc":false,"nfd":"1c2b84f68ad48cbd","nfc":"68b9b2ec223e132d","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a938b558187e5a4a","nfc":"a938b558187e5a4a","nfcEqual":true},{"in":"LVEVTRQRMMLMQPLUQTUUKORUURLTKTVMMAQTMJIMVUSPRKQSPVVMOTMMMUONLASRPSQVLQOONGSRSSRMNUKPLSSSFQTUSQRSQPLQVQT","isNfc":false,"nfd":"a9fed7a16907c08a","nfc":"05c29e148549b7b6","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c6d0225485419d07","nfc":"29700b4ffeac3188","nfcEqual":true},{"in":"JKKPRRUKLLNPORQNMMUVSOUUSRRVQQ","isNfc":false,"nfd":"462876a81f55214c","nfc":"8809b274968c738a","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMINNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"38d1b21c07f0d5a3","nfc":"43411c768caa0caf","nfcEqual":false},{"in":"QUVVSRSVLUOMLKVKSUHVKMTSKMPQVVGKPMLNSNKNLBTTPNMNRSNNUENLTPNUNRPQLM","isNfc":false,"nfd":"7c4fc8704b3e3287","nfc":"0af7a44f1b5fa714","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5d85745bba1008b4","nfc":"3ccb1bceac31914f","nfcEqual":false},{"in":"BVPNPMQKOUVNKKMPLFSSVLLULTPMVPNUMTPSKL","isNfc":false,"nfd":"33a24afaec14a15d","nfc":"33a24afaec14a15d","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ec42dfa967e8c4e2","nfc":"ec42dfa967e8c4e2","nfcEqual":false},{"in":"QLTOMRLPISLPOAKTSQSVVMKMLRPBOVCNLNQ","isNfc":false,"nfd":"5fb8387511bfc236","nfc":"db7d729253029fb1","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"790a5389d959e337","nfc":"790a5389d959e337","nfcEqual":false},{"in":"HLURLTPOQSAUSSVLPMKGTVRRUNULNNQPQSRRLNHSJNPKQQUNRMKMSNKVEPPNVTTQVUONPRNNTKMMMMOQKUQUVROTPVOST","isNfc":false,"nfd":"eb993696d0a7f032","nfc":"5972e1b0417f93c4","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"dd953d52f2c3f698","nfc":"dd953d52f2c3f698","nfcEqual":false},{"in":"UPMKNNQDMPMSLKTNSSUKRQRTUQ","isNfc":false,"nfd":"07f761f1fefa6d47","nfc":"d161b5d0470722cf","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"63dff5da48f65636","nfc":"5523749d7b1fb8d3","nfcEqual":false},{"in":"IIPONPUVQMULSKQLAQLOUKMNBPFNRNRTOSVNRVKRKDLJLKRPQVRU","isNfc":false,"nfd":"daef1b8449590a85","nfc":"a5fede91c96c16c6","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"053216266fbbb815","nfc":"053216266fbbb815","nfcEqual":true},{"in":"VUSQQPVRTQSSKMTSLQNVPVMUNTRTOUK","isNfc":false,"nfd":"f83870287c18099b","nfc":"f83870287c18099b","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ead2fe06880165d1","nfc":"94c01bb161eafb06","nfcEqual":false},{"in":"GNLOVATPUNUTVSPSQRRTLKVVQVQ","isNfc":false,"nfd":"fb583277ae41abdd","nfc":"fb583277ae41abdd","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0ef839f0b1f5f816","nfc":"0c61830c644ef266","nfcEqual":false},{"in":"IVPRVSVLTUSTTTKSTUMTSTTPKTSLQUQMLTULFKKMQQKSUROQVNTKEMKNLUVSSN","isNfc":false,"nfd":"2bd7996878e2d00e","nfc":"c8de28feb9ddd198","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"883802076672ba53","nfc":"883802076672ba53","nfcEqual":true},{"in":"RPUNNKQPKRLUSSRRNVONRQRVRNVKSVKGPMPKKRUSSQMVPPTRVSKTSPTNKUUKVSM","isNfc":false,"nfd":"57b3e87d298b74a1","nfc":"57b3e87d298b74a1","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a7e8477ca7cd60f0","nfc":"a7e8477ca7cd60f0","nfcEqual":false},{"in":"OPPNTRPRNOVUKMIVRLRLARVKLTUSONMUMUPMTRJHLPKUTVKTRMPOMQNTKVLVQKKPQTSQOVVONINNTBPRKRTQASQURKRRQFOSEULPPVOKS","isNfc":false,"nfd":"1db30b0909736ec0","nfc":"6344bd401dfbd18e","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9517344174a65fd4","nfc":"9517344174a65fd4","nfcEqual":false},{"in":"RGKQSJROKMVRNQMLQMPVSVPMQSRTOOORNSLMSKSLOOTVRQROQLQPLPQRRQSUOUPSMQMTVVQPLQURGKPKHLKTRROEOFU","isNfc":false,"nfd":"c75187ff130f54ca","nfc":"8fa72afc2df6ced3","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"041f876967794cb3","nfc":"766d420d75563253","nfcEqual":true},{"in":"ULSOKRINMTOVSRUUUUOQLPVSKSRMSLKQVLVP","isNfc":false,"nfd":"1ef9fac91d2af1f5","nfc":"9a55e32c28c4c74a","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"8bc924fc910b3f69","nfc":"34b3f0489bae3636","nfcEqual":false},{"in":"RVNKMMVNMUKNLQRMVRUUCQMP","isNfc":false,"nfd":"5e321fded1bd8bab","nfc":"5e321fded1bd8bab","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"625294472b87edb0","nfc":"705b2ed5bfad4870","nfcEqual":false},{"in":"UPUQMTNMNKNTDLLUKKSROSVMKKUNUUVVKUTLSBJPLMKMUPOSORVMQTVVPPNMKKVRLRUTHQMQRUPRKUUSVVUOSNRQVSRUUOTNVQMS","isNfc":false,"nfd":"bf2b3bb17c087ef0","nfc":"9c413ed2eda37434","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"157c6955c459038a","nfc":"ff5962b6496040c2","nfcEqual":false},{"in":"CTLTPOUTKPROOLOUKVPRRSLPOLOOEVQLSOKNLVRNQLLUQKMVONTMKQUKPAUPRDQNMKNQRSH","isNfc":false,"nfd":"c4917d4f0a8aaf53","nfc":"b95232f62e88d02b","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"94f9bf1c81e2b749","nfc":"4c3511479cd2b060","nfcEqual":true},{"in":"JPNTRMTOLUVRVLRTTQMRLLUQVFPKKMTVVVUN","isNfc":false,"nfd":"1f9b36bec561839a","nfc":"c2e1f585d093a2cb","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"2ee8d3297fa0d8a3","nfc":"445525c3506fb202","nfcEqual":false},{"in":"TTTPRRKSSMTOPTKQNSVSMVNNOPRPHNNVOKIIERLUVLLIUNNKQQOVRUOPJRPKOOQUROMNVTOKUOVLNATPVNTRASIOPPKQKNSOQPMKOOVVPPSQT","isNfc":false,"nfd":"6fd3ddaee7f04d7f","nfc":"5606c54cb337d04b","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6d93fa7e87e28633","nfc":"6d93fa7e87e28633","nfcEqual":false},{"in":"TEBVPNRUMRSMKUMTOOULKKVLONOSOKPPOTFGOOPSMORKSQETROULOCPVOTSU","isNfc":false,"nfd":"922f1ce8b69e7f6a","nfc":"91df6d0dcfae6a91","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"707e8008d5c41cac","nfc":"707e8008d5c41cac","nfcEqual":true},{"in":"HTMNOULUQDVUVRTMQTLVUOUDTSJPQMNLQMSQP","isNfc":false,"nfd":"7c446a8e39453c11","nfc":"5513cd1c0c4fd568","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b517badaf6cc7abb","nfc":"96b2e42fab531b3f","nfcEqual":false},{"in":"LVVTOOSNPSUOPKQMKQVKVLANOQLRERTNVNMOVTKUORURRUQPQKNOKLNPSMRTTHUUQPNSTPMMUKROPEOVQTVSSUKUSPPRPSSS","isNfc":false,"nfd":"b1b93227813a4716","nfc":"0cb55fe9e1caf534","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"15e572660f0b5752","nfc":"15e572660f0b5752","nfcEqual":false},{"in":"MVTNMOQURRRMPCTMQSPLQKMAC","isNfc":false,"nfd":"7631fe96239d6550","nfc":"7631fe96239d6550","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"07f27d219aa3d568","nfc":"07f27d219aa3d568","nfcEqual":true},{"in":"QOSTPRBLKLTBRULRKNJQNLKVOLF","isNfc":false,"nfd":"49c2b30c2098e9ef","nfc":"f69a2778bf618aa2","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMFNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"292bfd57dcf2ca8e","nfc":"292bfd57dcf2ca8e","nfcEqual":false},{"in":"CMLSSVUPKQRVOVKSQTOSRTUROPEORTOVVNVVMU","isNfc":false,"nfd":"7f73a5321f24843c","nfc":"41bfcbc8c6b9e376","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"23826ffa20e729ee","nfc":"23826ffa20e729ee","nfcEqual":false},{"in":"ONTNPMVUNQRQKVMQSKQOLMKPKQLPPLKUKOORULMRUVDPPUOLSTVKPEMQO","isNfc":false,"nfd":"585d6ed4ca7d2015","nfc":"596ce9617e820ce2","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8bbba736aa9eb5e6","nfc":"8bbba736aa9eb5e6","nfcEqual":true},{"in":"KJQKVPRMRONQKRQVQRVTPOOUTQOKPQUOKUOPVKVRNPGMRPTMSVQOTKSOQPPTHSRKNKNLMKRQUKVQVTNOULMRSMUMONKKTQIKQ","isNfc":false,"nfd":"3bebede0317b59e7","nfc":"801f152619bb725a","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b0adf0a0cfe54713","nfc":"5a39b81ec1c4c9fa","nfcEqual":false},{"in":"NOKVVTTTMMSKPVTVLPLNPOMOR","isNfc":false,"nfd":"85c871650c08cf36","nfc":"85c871650c08cf36","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"eb389a7817fd70c3","nfc":"89f60799a472c3a6","nfcEqual":false},{"in":"RMKUNJLRVKKNOLNMLORVRRTRNRMBPKLTRKRTNHRSPRMVBROQNQPOMT","isNfc":false,"nfd":"08c7c77ff355bd91","nfc":"a979b4c324542ca2","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"62b6328fa8619b06","nfc":"62b6328fa8619b06","nfcEqual":false},{"in":"ELKGQOLOUMMTRPPNVOKNSOPOLO","isNfc":false,"nfd":"a2aca56c556775b3","nfc":"1775a52c927f2405","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1eca046a82ac28b9","nfc":"1eca046a82ac28b9","nfcEqual":false},{"in":"GMRSNUQTMVUQQOQLSOQOSPSVVOUUPAVANPNMQLUTNLRLOOPTLTSQPNL","isNfc":false,"nfd":"d6ba3d86aadfd449","nfc":"d6ba3d86aadfd449","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b3b935500ee0726d","nfc":"469c0e2337c40e9f","nfcEqual":false},{"in":"CVTNLKLUROPQKKKVSMVTSMQSQCNULROMMPRVQQMVRUOPQNLVTLURKNLVVNOQTRLPNNSRVPRORQSPKTMPNKRVQOUKQRSALSPQQSBRKTQOO","isNfc":false,"nfd":"2152613163eddcb7","nfc":"bb1b7246799636b9","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5ec598954bf1d848","nfc":"5ec598954bf1d848","nfcEqual":false},{"in":"KRTRLSRURKAKLPKUPSKPLUVQV","isNfc":false,"nfd":"2afbf27df1810b96","nfc":"172a4e2ecb0d1a35","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4687945b8484e187","nfc":"d4200fbd323de50c","nfcEqual":false},{"in":"RTDTQQVTSTKRTLRMTTKVNOLOSUDMLOQVQQMOSRKNQKTPVKNTONMKQLMPBRLT","isNfc":false,"nfd":"2284061b394907a4","nfc":"a7e0cd7bad2f8b7b","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c04ccd7e275f13ac","nfc":"11935fe7df558b8d","nfcEqual":true},{"in":"OONTPQPQQSUOALLKVOPSTLPTRKQ","isNfc":false,"nfd":"068937d4a17325b8","nfc":"df1a337e7a415d09","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ad8c42af6785fd52","nfc":"760673ca4826be81","nfcEqual":false},{"in":"OKMPUUVOSVOKLPMTRVNTSOULMVMOTEOKPPQQOTTRUQTNMOSRKJVLKUQNLRMVR","isNfc":false,"nfd":"6b927f7518956c2c","nfc":"a1740931f9a179b6","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"f63d294ec2da7097","nfc":"c8228d0fcc685307","nfcEqual":false},{"in":"KLKVUQVURVTKPOLOPPSELPRPMNSURORLMQKGAQRNRNNVSNQVVKPLQQNMUKQSUQQVTMK","isNfc":false,"nfd":"658641df48d983c6","nfc":"012f244200e0a536","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"597d27cae39bd4ae","nfc":"bf28cfa7c2536d41","nfcEqual":false},{"in":"GPNPMOSNKKSMTNDTQKKRQUQQSUQINQV","isNfc":false,"nfd":"1203832a2085e533","nfc":"72c1b51f6af310a5","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bd724df99e816dc0","nfc":"072bff1f91a8bbd3","nfcEqual":false},{"in":"SNTSOTTKOVLAEPUNNOMLUKNUPRROLQPRUQTSRSVTQSKQOLJRQTUOKVTPLQVQLVLUVUTMKMQKVUOPLNOONNVISOTRMQTTKNVNSSS","isNfc":false,"nfd":"4070ad8cfbd3ddc8","nfc":"1783a5bc8ca67b45","nfcEqual":false},{"in":"FNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"85033aece0af664d","nfc":"85033aece0af664d","nfcEqual":true},{"in":"PLQSSVLIROLSTRVTSTKRSQKKMLQVTNNMSSOLPKUOQQLNUQOSMNRRIV","isNfc":false,"nfd":"2e0c48a579866d8b","nfc":"01f0ebbf267cae89","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"ccfa4f1200967866","nfc":"a6afc3b0382f8a1d","nfcEqual":false},{"in":"TIMBPNCMANOSQOMUPTLTNKVORMRLSUCKPUPMQNVACMQKPVFQFLKMLO","isNfc":false,"nfd":"042a136f2adf7d30","nfc":"e0a75c348ccb6c38","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"7badfd00d176a6a5","nfc":"a7d6a25df6c665d3","nfcEqual":false},{"in":"VNQKSKNPMVVRNOOLUPUSNNLKORNGRKMMLUNRKLVQSNOVNKUKONVLOSMQSMSMRSTTL","isNfc":false,"nfd":"7b172aead3e0078d","nfc":"7b172aead3e0078d","nfcEqual":false},{"in":"FNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMJNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"c3937fd1c7516c01","nfc":"1ea1699880015879","nfcEqual":true},{"in":"IUVTLLQVTQNNNRPOPQPQTMVSLVLNMMMTVVSELNTPSTVOPTNUPRTMUSNUSSMNSSLQUMKOQLLS","isNfc":false,"nfd":"3e0c8d146edf38a3","nfc":"c5853e9ea09732fd","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4cbfdd70522ccfcc","nfc":"6557e19bf892ff68","nfcEqual":false},{"in":"MLRUONMKTSRUQUQITLOQKOTVUMTLMKVUPONPOTTTTQVPLLQPN","isNfc":false,"nfd":"1f520c85e30b1ead","nfc":"903c93801d51ad54","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"886de1673e94471e","nfc":"886de1673e94471e","nfcEqual":false},{"in":"LOTLMKQVKQTPMNLQBESPKPPNMLLVUVULOLUMHRTNKTLSTKSSSVLNRPTMMRVITQVRQEMITVSSTLDVVVSATTUOLVUMONOMRKTNFUNOOQL","isNfc":false,"nfd":"908ce4609941331d","nfc":"b0db67a1f2321585","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMFMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0cf30c67d01e3fc4","nfc":"0cf30c67d01e3fc4","nfcEqual":false},{"in":"UUROKVMMMPUKRVRLVVULNVTSVVPUQSORVUKOTUVQOPSRDLROPNTTPRUUMVQMVNOJPVOQOVKPSKLPTNQTMOUNSUNNVIPUT","isNfc":false,"nfd":"0cb8087ca012b6a0","nfc":"e00ff05b9d5423cf","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"112405c40a0e34c5","nfc":"275c346dbe5c4d33","nfcEqual":false},{"in":"UNTRKREVTVMUOTOQKRLNVOBUOQPIPKNMRVVQVNUNRVOQVSQODSUSQFUVMMVOQMNNSSKVILNLRLARVVVGKPLP","isNfc":false,"nfd":"5a1a9e0b825e4353","nfc":"5518e62ec7269961","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"f33d9060a7abe71c","nfc":"f33d9060a7abe71c","nfcEqual":true},{"in":"PDKKSPLOOKQOQQOUVNVTRKKTLJKTVQ","isNfc":false,"nfd":"79f206a6e2ec7632","nfc":"f6894daf79fdb8ba","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1968f829d7c67934","nfc":"cc5c9be63c0eac6f","nfcEqual":false},{"in":"KPTSMLSKEOSPMLRRSOUOLLLPSJRKQPOLMKNOM","isNfc":false,"nfd":"e86750c95e62b678","nfc":"be6b0f163000ece8","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"342e9eb841eff77e","nfc":"342e9eb841eff77e","nfcEqual":true},{"in":"HOMTNQMSULVVRKSNSMSLKMPQSLROUOSOQPSKEMNTUTRKLRROQROMLUPGOSRVQVSUUNKLURQMKMNSQPVUTQRQVTSQOPPOMNPPNVRSLS","isNfc":false,"nfd":"c093f7350483fb69","nfc":"799d6766f3bbbe32","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e4dfd1029bb781a2","nfc":"e4dfd1029bb781a2","nfcEqual":true},{"in":"TVALUPFLUKPVVNQLTQQVPPUOTRRSLUNUKNLPNPKKMRPTLOKOMRSRNDTPOVKLTSKNQUMPLOMKQMSOAVVTOUCNOPUMPNMRMQIT","isNfc":false,"nfd":"7542998fe4091438","nfc":"8af996cbd2bd3bfe","nfcEqual":false},{"in":"BNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"60d5ea8617c19739","nfc":"9da99ba5cb6456e0","nfcEqual":false},{"in":"JONOLNOUVRLPSKUVSVVMQQLOPPUNRQSSSIVU","isNfc":false,"nfd":"0d5181d2e69cd096","nfc":"544e3562ce3d2fe6","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0a3fa655df855f45","nfc":"30f9d3f043076692","nfcEqual":false},{"in":"OLTMPQSTTRLHRMKROUTRKPTQTUTVVVNPTMKTVQKQUTOHVUPKUKQQTPLPLPVRQLMOKRORT","isNfc":false,"nfd":"f288c2ca84f52b59","nfc":"f288c2ca84f52b59","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"0a3c4ea58de46749","nfc":"0a3c4ea58de46749","nfcEqual":true},{"in":"OQQOOOTRTKQSLMURTLSNPUVSPQRDDV","isNfc":false,"nfd":"75db92efe3ebf4c4","nfc":"c5bae7281e025c95","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"daec2287ef4b4207","nfc":"daec2287ef4b4207","nfcEqual":false},{"in":"UPALTMTSMKPOKRUVKTQOMOSUQNVTSKHKRRSLNKNLTMNTTTMKSUINSKQMKUTNNRUORKLQMVPS","isNfc":false,"nfd":"0bd90c3929b88e93","nfc":"3574ced715fc8801","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8f0e2df1fa8c47ec","nfc":"8f0e2df1fa8c47ec","nfcEqual":true},{"in":"JTEQPTTKNUKULMKPPVVEOQNMROTQSUQUSRVNRRN","isNfc":false,"nfd":"f7214f0d7d345e5b","nfc":"58cc280041cab80b","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"47cb1b73ce64ed06","nfc":"08fb3d55222c2507","nfcEqual":false},{"in":"SOOUVVRSONKVGROOMTPQMTQPL","isNfc":false,"nfd":"12543e3cf66e26ab","nfc":"12543e3cf66e26ab","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4df9ad13b328438b","nfc":"4df9ad13b328438b","nfcEqual":false},{"in":"VTIUOVULNQPTOTMVOPMSUKRNOUMTUPKUSMTINSQUNLMLURVKQNPKUNQQPUKNOLUM","isNfc":false,"nfd":"a9e48fe6831ad6cc","nfc":"51ab9a2c5450e10e","nfcEqual":false},{"in":"DNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a06f73ef000dbee5","nfc":"af228163d1fc0cda","nfcEqual":false},{"in":"TNVUKQLVMQRRMRNSQKSTPQKMPSSLOMQMGPMUNMDMOTUNTMPNLRNMLKPRNLKUPLSLL","isNfc":false,"nfd":"aaa6cde39e49181a","nfc":"efe5abd87a182a91","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b182aa5b474352ba","nfc":"b182aa5b474352ba","nfcEqual":true},{"in":"SUKKQVLTOTVMUVVUVOKLPQTTQNPKULORSLLMTUNRSOUUMLRSNCHUSTRSTPUVQTUVPMQRSOOKQQQVLSNNNKUTLQSPQQMRNPUKMERSLROQLPMN","isNfc":false,"nfd":"f3dee42be769c938","nfc":"f5f2b3c6a5eca35a","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b33de1f67dca3117","nfc":"8e66e4d526cdfc5d","nfcEqual":false},{"in":"SKNVUMSQNKTPMSNQNSNMMPPQPQTKMLKOFDQQVMOCTKMGJKLOVQVMQPDVPNDULTVTNRPVLQVPPPTKRNTQTKKPRTVSURPSVS","isNfc":false,"nfd":"968b829c5e59e8b0","nfc":"84ebf809d6ae9250","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"a8c02ebcc5eb0f63","nfc":"af887d27cefc2816","nfcEqual":true},{"in":"IHMSPUVRUNQSBVKLKKNLRSOKNRUOQNRKPTVTKUUKSRUMOUQMUSUUDQTKMOULLTTKROPMSSOTROUQLRMMSPUNBPMSQ","isNfc":false,"nfd":"92484bd5693cca4e","nfc":"afc0c4b03174df65","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"d872d258407b14e7","nfc":"b9c159d577e6919f","nfcEqual":false},{"in":"NLDNORQKRUSRQTVOMQQPFVPPMUFTNVRVQPMSUUPDUSSTMMNNVUSRVFSQLVUMVKRONKUVTMMQO","isNfc":false,"nfd":"c7734ef76251b43b","nfc":"2aaddda23e547769","nfcEqual":false},{"in":"GNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b2e8b331f0bcb9dc","nfc":"b2e8b331f0bcb9dc","nfcEqual":true},{"in":"ECKURSLLSOUQQBVNKRUTMMTSLHLESIMMVTNOVQ","isNfc":false,"nfd":"0c125047e35a42d6","nfc":"174095281a759b6b","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"eab8d65c287c47ce","nfc":"eab8d65c287c47ce","nfcEqual":true},{"in":"DMLMUUTKUPUOLSQNSOOLSSVKQKVJQPHPNVKMRQSLNRPSVMMUNKNQUSSVLRVUUMVNSPQTVOLMLNKNNOMLTQNVNUSSTRTUQ","isNfc":false,"nfd":"3a449c59c90800f8","nfc":"c52e5ec908d1437d","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"d8ac0e9fb551b8bd","nfc":"a751bb9d55daa3f1","nfcEqual":false},{"in":"IVSRSPORPTQRVRMUOQLPMNRVSTVOTVLNVRTKOSUUSNSKOLLQQFVUOLQKMTVUOOMQURSVSNPUTONKNLTRKQKONPOPKOQDK","isNfc":false,"nfd":"73c329d650ecf932","nfc":"c5da4cfd3e9d19b3","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0fb34ba806c8aa5a","nfc":"0fb34ba806c8aa5a","nfcEqual":false},{"in":"KRNQDSKPMJFLLOUUKRNSPQLLLOQPSPTQGTULPTBTPOQQTKPVSUVLNSKPTKLVUOTGGVKSSOULVOTNSANPKOSRNUSORK","isNfc":false,"nfd":"1c4c0a917e32b3b8","nfc":"d0549416011c3aa7","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMFMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"7c962ebcc554435b","nfc":"fcb5c9e38085e7bc","nfcEqual":true},{"in":"JQSKLVTTRTVSTMKOKRPQOQTDMULMQMLMON","isNfc":false,"nfd":"7e48164add75162a","nfc":"28518f7217143a19","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"709a7471888b7a10","nfc":"a27581597a65370d","nfcEqual":false},{"in":"AMORUSLTPRQSLLVMUPMOMTSVMKORTSONQQLNLNVRBDTVTSKNKSVKLNNKPRPSRNPMLRMALMNMKTOOSPRKLSOOLUTLOSKTMVMO","isNfc":false,"nfd":"a525c0030aa4364b","nfc":"746d719bfd6c635c","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"40f3c4026a83fef1","nfc":"fdd691d8ca9ebc03","nfcEqual":false},{"in":"UOKMQMPQNUQNTTSQONVSOUPLVQTTRQSVUKSUIHNUKPSPLUQORMUUNFSOBTANSLUTSRQKMLR","isNfc":false,"nfd":"c3a96baac48be918","nfc":"69696b77b1ee19f1","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"9867782639248d72","nfc":"a60311ad12d91a74","nfcEqual":true},{"in":"CMVPTRNOPUPLSRPSMOVSRTSROAVLPMUSSSLQUVRNURQPUMNNOOOVOVVMSTNQDKN","isNfc":false,"nfd":"436721ab6ee62cf4","nfc":"b670ac68f4ab7e8e","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0040f44c7bd56665","nfc":"cb612c1b30f15046","nfcEqual":false},{"in":"TQKPNPUTMSTVKQRVRPMMTPNTMTNROPOPNSNJN","isNfc":false,"nfd":"af95800e790021da","nfc":"3c58334e007330d2","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"afe7859a0f5d1875","nfc":"afe7859a0f5d1875","nfcEqual":false},{"in":"GVMVPURQUNKVAVSKUMLVPSTMMOQKTQNLRURQMKURVRUVRRQOMRPMN","isNfc":false,"nfd":"7df865207f49fd8a","nfc":"7df865207f49fd8a","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0b5aac34ae842b08","nfc":"cfe0e968f17d408b","nfcEqual":false},{"in":"VVUUTTRMVTTUMPIMUKLKVTRVSLOLUSRPVO","isNfc":false,"nfd":"9855268856b22e4b","nfc":"8e1d7203ce156dda","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"142a120c87817c83","nfc":"142a120c87817c83","nfcEqual":false},{"in":"IPPPRNRLNVVNTLMTONJBQOLPST","isNfc":false,"nfd":"91140a4d27bc4a2f","nfc":"cfe70b97728e49eb","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"81f60c84545e7fe3","nfc":"3dbaaaff61102024","nfcEqual":false},{"in":"QLSKKSTRLVMRMUQNMNMRVTTMROQMTLPSLSUVSKSNVMQUNETNNTLQOKSUMRPHMKRPTPSONNVTVUSNQVTTPPSV","isNfc":false,"nfd":"e74a10ffc52877b4","nfc":"e5127d5f38122386","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"dfa6efe56aa49848","nfc":"dfa6efe56aa49848","nfcEqual":true},{"in":"VLFNOTNRQAUVSOVTOPLLLTUOSTVMMPMONLVVLQMKVUKPTVRPVQNSPAPQKOPMPMUTRUNOQ","isNfc":false,"nfd":"2aa3c5acff248ee5","nfc":"c6fd004903f1f288","nfcEqual":false},{"in":"DMMMMMMMMMMMMMMMMMMMMMMMMMMMGNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"16f7886b2d474910","nfc":"2e96c376f2fc702c","nfcEqual":false},{"in":"BJVQOSQSSSMPRQLMOVLKRRMURNRDMPOVKPULSMVURKPMSPRKKUVMOTLPNOMLMUSSKUMKKIUVOLVPRNSKKPPSMNRRORPQKTQ","isNfc":false,"nfd":"38055cde3be705f0","nfc":"ec0773edf7ae78f0","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bccfcf0774c2b364","nfc":"bccfcf0774c2b364","nfcEqual":false},{"in":"POKPKNNQVOOGNRMPVMSMSQOIUNKIUP","isNfc":false,"nfd":"7de995a59ea08b63","nfc":"99b15b6163936215","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMENMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6ea6861dc37176fc","nfc":"b8a36d9e11a37620","nfcEqual":false},{"in":"IPKORPVPSPORPVPPNLLNPKKURMSNPQQKRROVUKVNVPTTNPSQNSNHRPTMN","isNfc":false,"nfd":"3cf6dfa0af04b4cb","nfc":"8d0625a68054d0f8","nfcEqual":false},{"in":"JNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"fafdf7784a3ad038","nfc":"331129e452f8a0df","nfcEqual":false},{"in":"UVPSULLNQMFOMNVMNPKVKORJSKKPNLONTKLMPVMONOTGSTMLKPPLSSQNKTMMVNVUMLKKJDNNUQVVKMQLNPPMMQSVKVSRKSSUSLTON","isNfc":false,"nfd":"0811a3bfe4224367","nfc":"1c470c807df49825","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMINNNMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6747aefd45b49b89","nfc":"ea151a03c10f2507","nfcEqual":false},{"in":"FNUSQKKKSRKUQQPQKNUTQLBTVLOSUQO","isNfc":false,"nfd":"451a14db66d4cf08","nfc":"451a14db66d4cf08","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"8bbba736aa9eb5e6","nfc":"8bbba736aa9eb5e6","nfcEqual":true},{"in":"QKTLRTNMMKKQKONPSMMROOTOMMNUOTUTKUUJHOUTVMPSNNPSSCMNSQNLQLLTMKOTVPLTTPTCGTNQQVBKFVNLOOSSMNPOVTNDUUS","isNfc":false,"nfd":"193d870171415779","nfc":"f4aba0a55165b233","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"df5609c628db4af9","nfc":"dc0bc91c505c0dbd","nfcEqual":false},{"in":"HMPUUQOVHTQRKVRMKKCONTKQMUKRSRTKLKSSKMQRSVVTLUPRTOTMVLVURLROMLKSM","isNfc":false,"nfd":"cc26efc3a421619d","nfc":"99f4b17781fdaa8d","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"160a798f9f9ff696","nfc":"160a798f9f9ff696","nfcEqual":true},{"in":"AFURPPOTLVNTLNRMTHPNMPGPTUVFSQMQLPNLPIRVTVPTQVNKTKLROOMLVRKPKQKRUNUPVDLSLRLLJKPRGMNVLTURVIKROMVPUPQERNMMNQ","isNfc":false,"nfd":"bc55c9cc3ba71452","nfc":"7e033bdca92592aa","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b0e059ab6782c1ee","nfc":"23cc6013ada715b5","nfcEqual":false},{"in":"GASLMUSMRSKMQMQRLQROPUMPMMQTHSVNUSOVSMKVQVMRUNMKMERRTQKOTQPPRPSPQTOOUSLPMTKTMNNNLKMLSLQV","isNfc":false,"nfd":"9c0ebc07572bbe96","nfc":"406f205301850b7e","nfcEqual":false},{"in":"ANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"662350073e53b7ee","nfc":"662350073e53b7ee","nfcEqual":false},{"in":"CTSSVOOVSUTPQLQRVPNLTLTTKKLPNKSLUNTRNVROVQOPBPKVUOMSQLNTRLUKRPPVNPNT","isNfc":false,"nfd":"9c77cf2de20f6d9b","nfc":"e0b216ac0feeb3fe","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"3a7994e55c79af4c","nfc":"66ea49e1d3667a0d","nfcEqual":false},{"in":"UTQOOVSOMROOUNLULUPOUSMMUVRLMQVNRRNVSKPDOTUNSPQKULUVUMUUNTUTUVPKQSPOUTMLPRPMULUSM","isNfc":false,"nfd":"c6c87909af9d0e31","nfc":"b7c1381226afdb9f","nfcEqual":false},{"in":"CNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"b41208c9c651a1b6","nfc":"b41208c9c651a1b6","nfcEqual":true},{"in":"GLKKRKKTUPOSLRNVLNRTTSLKLOLOVMNKVOUSNMSNRKKRLPSPKKRRNRERNKMTLQRMNMNRPR","isNfc":false,"nfd":"518bda7d808524d7","nfc":"520df8149acd982b","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"5a2d7b016690af1a","nfc":"5a2d7b016690af1a","nfcEqual":false},{"in":"GSPQTVPRNNLLTOSSIRQLMLMQQKQQQQTRMLNLSNMUMTVUVMOOLUKSMOOSSKOSLSGK","isNfc":false,"nfd":"b05f4ef5e24e2582","nfc":"2cd338214eabc560","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"4393a5648951af3f","nfc":"bba67ee033345e64","nfcEqual":false},{"in":"IGTKUSOLOVPNMMONTNKVSNQVQSOVOUROUBRLOPMVUOONQNQKUVNRRLROKPVPQQMUETMQL","isNfc":false,"nfd":"2f2c605a9cdeb51e","nfc":"b631c8636365df34","nfcEqual":false},{"in":"BNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"4f44eb06cc87b97b","nfc":"4f44eb06cc87b97b","nfcEqual":true},{"in":"NTMPUOLLSPQSKVVVLVKUQMPBKRBQRKTRPBOSRRURVRNQKVMNMGSQKRPMQSNLOKKHNPPV","isNfc":false,"nfd":"ef166281bc458640","nfc":"03d7c41c0a230425","nfcEqual":false},{"in":"ENNMMMMMMMMMMMMMMMMMMMMMMMMMMHNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"895f2444f3e7c037","nfc":"8b5bb94c02ece6ae","nfcEqual":false},{"in":"SALRSKQNONOVSTONLTLLAPMORSKOUUVORKLUQPNTHUUNUQPQTOTTPQQOOPKRLLSSRQMNCNKRULOTPOORLUQUNPVPPRLPL","isNfc":false,"nfd":"9655fe6387a19379","nfc":"534971cc94f65ae9","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"89434e31c5903067","nfc":"89434e31c5903067","nfcEqual":true},{"in":"NUCSUTMOPOOQVNLKOPRTVNKTNUKVVRMORVVOUIKVLTRUMKSTNSTNKMOPQ","isNfc":false,"nfd":"6c59fbc58ca853b5","nfc":"79f783ae8ff1689a","nfcEqual":false},{"in":"FNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a786bc9ae9177d54","nfc":"a786bc9ae9177d54","nfcEqual":false},{"in":"FPKUUMPTTOSUQUTQQRFGLLRPVPKKRVKQ","isNfc":false,"nfd":"068713bc1e40825a","nfc":"068713bc1e40825a","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMCNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"251da33f10d7dccc","nfc":"bc2632c44e311361","nfcEqual":true},{"in":"NTNLSKMPNSUVULQPMPRKUQNPVSNQTSSQSODHLOTTELVHVSPQOVSOSTLRLOSNLLQNRSAURQKOTKRLUNQQLVTTOUPVRKUTKPLVPANLR","isNfc":false,"nfd":"8b6aa2eb9d495561","nfc":"c29922adb80b7354","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"721c5e3941d991c9","nfc":"721c5e3941d991c9","nfcEqual":true},{"in":"RSKOKOJSROKPVLOPLNKQPKNMMLPMRPPQQTQNUSSVQLKEKQPQVNKOMOMLVNTTTQVMKVNVQUOVLMRTTNUQRSTUHQTUOMTMQPMOUKNMUKO","isNfc":false,"nfd":"cad29bf625d5b9ba","nfc":"bc467df350e826ff","nfcEqual":false},{"in":"CNNNMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"65dd0d031fb57d10","nfc":"4ca287e5211cef77","nfcEqual":true},{"in":"HQNTPSVTNUPQUTQNOKDKNTQNUVQRKKSMQQDRLVRSROKLOSTTTUPLSTLKSUSSQMU","isNfc":false,"nfd":"a5163e60883172ec","nfc":"56f2801500af21a8","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"d4f46d8645ff8ad7","nfc":"58a49a680b2db335","nfcEqual":false},{"in":"RTVVDVVPOOQOLSPRVRNOUMVPNOCULRQNMMQJUFPQLNVMSMRUMOMLRQNVKKUROOURQQPPPQLONSUNNUPVLQMSNTT","isNfc":false,"nfd":"3248071c2885c134","nfc":"d4bf3b46c4a7645d","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e9767215b87b83bb","nfc":"dfcd79c0b0763955","nfcEqual":true},{"in":"MOTOMPNVROOVSKQPLVQMSLONVPPNVLPTKNSOOQMMHIUOBRNBQOOPVPQSNLNRRINSKOKTVROQTBUVOMRSNOOPOSMUPUKMR","isNfc":false,"nfd":"541089be5c4fde5d","nfc":"0100bb68e305f5ff","nfcEqual":false},{"in":"BMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"53c4a01b33e547b8","nfc":"53c4a01b33e547b8","nfcEqual":false},{"in":"EMVRUKUKRSOSNCMPMVPUPTSRUNLRUTOVKSOMKSRSMQTNOVPNUNPLPKLTLOR","isNfc":false,"nfd":"d664928716e11126","nfc":"62a4db88b74bed2f","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"dfe0f1f7dff99638","nfc":"830ca4156829b226","nfcEqual":true},{"in":"TLOOPVSMKCSTRTMLUOLQUPROMSVKKNMVKOAOLKTMMSPOPMQRNLSJKTLUQUPMMNVPUAOUO","isNfc":false,"nfd":"b3ee939191766aa5","nfc":"99363ff62340ce16","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"08f0cfeeb760a560","nfc":"08f0cfeeb760a560","nfcEqual":false},{"in":"MQQMVPRONBUPSONLRPKQUPUKRPUKSMLUQNVVSIHFPTKUMJQQMUTLOVLTLNNSTNVVMLVLRRL","isNfc":false,"nfd":"8497675e2f635f4b","nfc":"e7ab8500f2ab489f","nfcEqual":false},{"in":"DNMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"6cb3108ef54e2f18","nfc":"ceeef02a90d56400","nfcEqual":true},{"in":"MQLRVQKNUPMELVROTMSQMUOPLPQPSUPVNL","isNfc":false,"nfd":"8a10cf43ffdba0ce","nfc":"a322bb7e60390566","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e09bd752a61b9fa3","nfc":"bdbddaa1b2f41f8f","nfcEqual":false},{"in":"MQOQNSTOTVUQTOUHNSRONKQLLPTQMMVNTSPOLSLSQMNTQQNPLTNVRMVOTDIMUVSQKPPPVOLTMSNSKLKORSKOOLKSLSMVQUNVTURTRKRMK","isNfc":false,"nfd":"3eadb893b1f4e82e","nfc":"8f879e948d98f2a2","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"cb62111d80b8fd54","nfc":"cb62111d80b8fd54","nfcEqual":false},{"in":"LQOTQQKTMVMPQMSKSTSORKKMVISQMPMH","isNfc":false,"nfd":"991824e614a8d92d","nfc":"62623807db62c10d","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"919ca6df39003143","nfc":"99fdae28714c2a42","nfcEqual":false},{"in":"BSULTMLQUVSUUPVRLTMVSLPOOMSLTVLKSKOQUOOPUNNSOVQTLUVMONSMMNLTQURTUOOCMNMMPSLSNQRLULMMTLVLTSSSKNSJKVSKQQ","isNfc":false,"nfd":"a969bea257018218","nfc":"9157fe2fec53658e","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNNMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"19aa0b08d879f58e","nfc":"a3c71295820096d8","nfcEqual":false},{"in":"HCLRRVOOUOPKKLNPMQQTOTNBNNSUTTTOMOHRT","isNfc":false,"nfd":"2f72c2269fa3d830","nfc":"2f72c2269fa3d830","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"e0eefd5836eb8897","nfc":"c0de51ba099dbaba","nfcEqual":true},{"in":"MRUUQLNVVKMVVTTMRUQRSQVTHBMMVDQOVOMVMKVKMNVNVOQQPRULSBVKLSORJEPQNURKIVKONMFTTQNQNPPVRKNQBPORP","isNfc":false,"nfd":"f4df25cb71a5228c","nfc":"055b6d1c79dea67f","nfcEqual":false},{"in":"BNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"35473219127f8849","nfc":"35473219127f8849","nfcEqual":true},{"in":"ITUKRORTNLKQLSULUSPRKNSROTQKPLNPLRURVT","isNfc":false,"nfd":"9d924f85983982f2","nfc":"7c634ee180dc4f2f","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"30874a7dc224d35f","nfc":"3d27991b47bda03c","nfcEqual":true},{"in":"LTVNLMQQROKEPQKKVKMRRVNTNOMVMKKPRRK","isNfc":false,"nfd":"04a537692640828c","nfc":"0a9462477f684dbe","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"f77a0b2965042899","nfc":"20674ea7c36ead91","nfcEqual":false},{"in":"JEQTANRLTTERLORONLOFMOQLKMNGSQQULVLUQPNHRAMVBTKNVRQSLVLKL","isNfc":false,"nfd":"cbee85df64c1509e","nfc":"36cc97f019903ff2","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMDNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"100b259a5a2a12f3","nfc":"5544a2514992ddcf","nfcEqual":false},{"in":"ALPPTUSTVTOQPNPTSQQSRTVPELAKRMONKROPSPLNKSNMFSOSLLRFLKLLRQ","isNfc":false,"nfd":"7a43bf018f0f1304","nfc":"d7a69b9dc4f43b9d","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"eeb77475324e432f","nfc":"c6f686373b06f8e8","nfcEqual":false},{"in":"NENRLOUVPSSNNQTKMTQLMLKVVQQLTNMVVQKPSQLMUPQQKQNOQTNTKMPSKOQLQMOOKSVK","isNfc":false,"nfd":"5216c48ec8e2e7b1","nfc":"435ada5916c7a458","nfcEqual":false},{"in":"GNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"694e392c6df50cca","nfc":"694e392c6df50cca","nfcEqual":false},{"in":"UTOVTMUUKLTPGUOQVTSLQSVKQTUMLRNRMRTRTJQNFKUNSUTQQLRQVBCPTSVPOOLNCUKMM","isNfc":false,"nfd":"7fbd2d676e958f4f","nfc":"75c71712f23c27e0","nfcEqual":false},{"in":"ENNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a9b8de193d622435","nfc":"c4aff1fe9bda68a5","nfcEqual":false},{"in":"SVPLNUURMQVMVKUSUBTULNNRMKVULPMSVQVUSSMSKTRTOSTSUMQQOPPV","isNfc":false,"nfd":"8c7a07b6d62b0c3d","nfc":"8c7a07b6d62b0c3d","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"7071ae63e8556640","nfc":"575c80a07f5ad919","nfcEqual":false},{"in":"JJOQBTMQNEPOUNUKTTMSTPQNTLPNLRVQOPLUQMUNTVMSTLKSKMNMMMMRPM","isNfc":false,"nfd":"533b106be247ca1f","nfc":"f7690d69ce191ab9","nfcEqual":false},{"in":"INMMMMMMMMMMMMMMMMMMMMMMMMMMMMBMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"84080f543ab54f73","nfc":"c925f4d75c223704","nfcEqual":false},{"in":"SGOTRPMRNQLQPPOQTROVRKSORSTKNRVLQTSMOUUSTUVLKLVQNVUFKNLQVK","isNfc":false,"nfd":"8d2decf4647b2470","nfc":"8d2decf4647b2470","nfcEqual":false},{"in":"JNNNMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"2e2f83fa069ee5ed","nfc":"29ee8bdaf51a7b3f","nfcEqual":true},{"in":"IBTKQKATVMKVKPQRLQNORPNTQNSNQTNOUSVKRQRNPORKLOHVLPUQUVVUVOPTNLVLOQ","isNfc":false,"nfd":"4522e5f65836a0fa","nfc":"075a287d80cb23bd","nfcEqual":false},{"in":"AMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMGMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9f36a9f5a8581921","nfc":"9f36a9f5a8581921","nfcEqual":false},{"in":"BTMVRUNMSVLRKNQLPPOSLKTHOMTRRMQUL","isNfc":false,"nfd":"8c6750a813e10cbe","nfc":"8c6750a813e10cbe","nfcEqual":false},{"in":"GNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"2bcd7aea4d6e3894","nfc":"2bcd7aea4d6e3894","nfcEqual":false},{"in":"ALNLLTROUPVPOPMNNKSPNSQUMRUSO","isNfc":false,"nfd":"81a02c7bd6073e6e","nfc":"5dfb497b1c62ac83","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"141b5f9a19308d16","nfc":"141b5f9a19308d16","nfcEqual":false},{"in":"KJKMRRUQULRTVUKMVROUKNUVURKKMVKQUVC","isNfc":false,"nfd":"e45d89cd8234bbd9","nfc":"1a2ef245a0365b61","nfcEqual":false},{"in":"ANNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"6d5b67367d5c08e5","nfc":"6d5b67367d5c08e5","nfcEqual":false},{"in":"SKKQSULSKSVLRHNQVVLNANFPKOUNSTVT","isNfc":false,"nfd":"3d8e97acf50195a0","nfc":"3d8e97acf50195a0","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMCMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"1213a53239df25d2","nfc":"1213a53239df25d2","nfcEqual":false},{"in":"MPHPKKRPRUSUVIQPLUSRNLKTTRMURKPNOVSQINTVPQVSQLMVVHTSKLTAUMLSV","isNfc":false,"nfd":"cfb950f28c67560e","nfc":"a476666478ebef9d","nfcEqual":false},{"in":"HNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJNNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0fee7712885bfe73","nfc":"897b3f922bb7137c","nfcEqual":false},{"in":"QLNTRKMLQLSRQKPORSPORPUNPVUNOVOUURTOMPVOQVVTNRSNCQNRMLONELLQQUSLRRVSFOMQUKOKUSMSQOOLVSPRORRVNTKNNVQTMQPM","isNfc":false,"nfd":"47604036bb513a0a","nfc":"0e3942703fa53b89","nfcEqual":false},{"in":"ANMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"72d3be4b3b51a846","nfc":"72d3be4b3b51a846","nfcEqual":true},{"in":"KNOUMSRTOQKSSTRPKVOLUKNLQKNMPUU","isNfc":false,"nfd":"37073d71d7a1487d","nfc":"37073d71d7a1487d","nfcEqual":false},{"in":"INNNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"17e96a8378cff55a","nfc":"bb7b282c5968f076","nfcEqual":false},{"in":"SLKKBVVRRNRNRPLPSTMQVPVTSRKLQQTLLLURUMRPKUVURSVPKQVQCMRORPQQLLMHELNTRRMUONLNPQKSNRQKMNTORRROKU","isNfc":false,"nfd":"fc56c998070ab24c","nfc":"2c701314aa868cf0","nfcEqual":false},{"in":"IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"18fc7a509ae11575","nfc":"16a60865cc0c918e","nfcEqual":false},{"in":"CNRRQVULLNPNRLVQROKUTNNSRMPTMSPPOLRNVVMPQVRSOUTUKOUMPSLNPLNLMPRCM","isNfc":false,"nfd":"a991ad8e115b2eea","nfc":"a991ad8e115b2eea","nfcEqual":false},{"in":"CMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"58b193c04a3d988f","nfc":"58b193c04a3d988f","nfcEqual":true},{"in":"RVLUKTRMVOPSSKNPRLLNLFRLLKKSFQSMKVOTTLQSIVMSRQTPSTSQTQQVVSS","isNfc":false,"nfd":"38f0077532b19f84","nfc":"8961c43c859a6ad8","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"7071ae63e8556640","nfc":"575c80a07f5ad919","nfcEqual":false},{"in":"RUPTLOKTMPSTPPLSMTQNVNPLNRRLMKUNUKQTP","isNfc":false,"nfd":"196d45b07b1beb5e","nfc":"196d45b07b1beb5e","nfcEqual":false},{"in":"CNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHNMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"e78842b494373580","nfc":"e78842b494373580","nfcEqual":false},{"in":"VHMPRUJKMQNURNRPKSUOSLKOOQSKRPLNKOVT","isNfc":false,"nfd":"4a65e7ccfd6b3ca5","nfc":"217af268514d11c9","nfcEqual":false},{"in":"JNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"468ba6ab7f3347d5","nfc":"ad9b935b875f2cee","nfcEqual":false},{"in":"OLKPKNQUOOUHVVLLLNTRMNPNNUNPQTMURKKN","isNfc":false,"nfd":"211c902ec54322d6","nfc":"211c902ec54322d6","nfcEqual":false},{"in":"ENMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"9da1f265cc558b21","nfc":"48386e7704de24ea","nfcEqual":false},{"in":"SNAKIPVPRPVMTQKMNUCNKPOQNOGTLUB","isNfc":false,"nfd":"c6100d8ea893cb98","nfc":"9a68708303e5d385","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"a55998b439e236ca","nfc":"a55998b439e236ca","nfcEqual":false},{"in":"DVMOQSOSMTVMKMLTENOTOOLLOORQPSVTMKNORUVLVVPSTPVSMBTUPMQUTSNKRILQKVKRMRPNORLOSVPRMVPVUPLBLTKMSETFLMKSPK","isNfc":false,"nfd":"d80a67a05e016147","nfc":"eaebdc04bf449f92","nfcEqual":false},{"in":"EMMMMMMMMMMMMMMMMMMMMMMMMMMMMMANNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"bfc746709d043152","nfc":"f14aaf9ed73acc10","nfcEqual":false},{"in":"KMMTTKPRUSKTNLRRMMNMKQMLNOPRNKDTNLRTQKKVSPNVSMRSNFNVSMHMSPOTKKTPQKQRQMUSKUVRONULVVTLLRNRSTMVLTLOMVQ","isNfc":false,"nfd":"c50a59e92a31ceba","nfc":"d786402070a72ac4","nfcEqual":false},{"in":"GMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMBNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"3e6ee337d5424fd9","nfc":"3e6ee337d5424fd9","nfcEqual":false},{"in":"MVUPNNRPPOVSPSSMTOTPMPQLTSKSUNLLTKONRQRLUUSLLURTNMLSVMVU","isNfc":false,"nfd":"49afea1f34990d49","nfc":"49afea1f34990d49","nfcEqual":false},{"in":"FMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"27f8726ef503506f","nfc":"27f8726ef503506f","nfcEqual":true},{"in":"AQMKUSSQRRSKVLLQLNPVKPRURMQVVPVNTSQTSNUUQLURLPURSLUKOPNVLKLMSQTTOTNKSSNSQTPLQPMOLNSVTNSVMMSRT","isNfc":false,"nfd":"2b6456ecf2486616","nfc":"2b6456ecf2486616","nfcEqual":false},{"in":"DNNNMMMMMMMMMMMMMMMMMMMMMMMMINMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"0457df8c49fe6b13","nfc":"5329a81c2951163c","nfcEqual":false},{"in":"EFPRSKNULRPOQQRKTKSTANRVNRSPMURNKOQFQUKRKUKTNLQSNSPPQUQTNLMOMDSRKLSROPTTKKSRPQLQROSLPBUP","isNfc":false,"nfd":"8b6672270791b5df","nfc":"84416708bef115c3","nfcEqual":false},{"in":"INNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"b3b935500ee0726d","nfc":"469c0e2337c40e9f","nfcEqual":false},{"in":"TLUUQUNQPSVQMUKTTCKVNPURSLOVORRRQVQVPRTQMMKNSRLTOKOMOUVKQLS","isNfc":false,"nfd":"ef2e1bf7efc28e72","nfc":"ef2e1bf7efc28e72","nfcEqual":false},{"in":"HNNNMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"cfe8093559e85bce","nfc":"cfe8093559e85bce","nfcEqual":true},{"in":"SPTKNNVSTLTKLUUTLONIQSLVUMKOKRSSDOO","isNfc":false,"nfd":"49c590fd3e5f5d8c","nfc":"04ede8e0717aab66","nfcEqual":false},{"in":"JMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCNNMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"43d71d0b4e22509d","nfc":"67ce99ff560d4919","nfcEqual":false},{"in":"VVVURUKSRPLKQPRNTMTOPGRMLPPVOUUKKLROQTPTPKOLIQOOTFPLQRQTVTTKKRM","isNfc":false,"nfd":"dd577a3b9e845c9a","nfc":"f587b10df3b7b4f1","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":true,"nfd":"23b31947af9ae420","nfc":"23b31947af9ae420","nfcEqual":true},{"in":"TOORKTPSOSTTRUTSNKLKVROKOOPKORQPRKTPSVKUKOLMFULSRONNVKQLOOMSUOPRRUVTUMUPVLNOVOPQSTTSOKPTRQ","isNfc":false,"nfd":"93bfeed1b099cbf6","nfc":"93bfeed1b099cbf6","nfcEqual":false},{"in":"HNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM","isNfc":false,"nfd":"aa2a013404eb6c14","nfc":"aa2a013404eb6c14","nfcEqual":false}]} diff --git a/packages/skill-tree/scripts/unicode-15.0.0-go.json b/packages/skill-tree/scripts/unicode-15.0.0-go.json index 85bb1df..4a3d353 100644 --- a/packages/skill-tree/scripts/unicode-15.0.0-go.json +++ b/packages/skill-tree/scripts/unicode-15.0.0-go.json @@ -1 +1 @@ -{"unicodeVersion":"15.0.0","normVersion":"15.0.0","goVersion":"go1.25.3","assigned":[[0,887],[890,895],[900,906],[908,908],[910,929],[931,1327],[1329,1366],[1369,1418],[1421,1423],[1425,1479],[1488,1514],[1519,1524],[1536,1805],[1807,1866],[1869,1969],[1984,2042],[2045,2093],[2096,2110],[2112,2139],[2142,2142],[2144,2154],[2160,2190],[2192,2193],[2200,2435],[2437,2444],[2447,2448],[2451,2472],[2474,2480],[2482,2482],[2486,2489],[2492,2500],[2503,2504],[2507,2510],[2519,2519],[2524,2525],[2527,2531],[2534,2558],[2561,2563],[2565,2570],[2575,2576],[2579,2600],[2602,2608],[2610,2611],[2613,2614],[2616,2617],[2620,2620],[2622,2626],[2631,2632],[2635,2637],[2641,2641],[2649,2652],[2654,2654],[2662,2678],[2689,2691],[2693,2701],[2703,2705],[2707,2728],[2730,2736],[2738,2739],[2741,2745],[2748,2757],[2759,2761],[2763,2765],[2768,2768],[2784,2787],[2790,2801],[2809,2815],[2817,2819],[2821,2828],[2831,2832],[2835,2856],[2858,2864],[2866,2867],[2869,2873],[2876,2884],[2887,2888],[2891,2893],[2901,2903],[2908,2909],[2911,2915],[2918,2935],[2946,2947],[2949,2954],[2958,2960],[2962,2965],[2969,2970],[2972,2972],[2974,2975],[2979,2980],[2984,2986],[2990,3001],[3006,3010],[3014,3016],[3018,3021],[3024,3024],[3031,3031],[3046,3066],[3072,3084],[3086,3088],[3090,3112],[3114,3129],[3132,3140],[3142,3144],[3146,3149],[3157,3158],[3160,3162],[3165,3165],[3168,3171],[3174,3183],[3191,3212],[3214,3216],[3218,3240],[3242,3251],[3253,3257],[3260,3268],[3270,3272],[3274,3277],[3285,3286],[3293,3294],[3296,3299],[3302,3311],[3313,3315],[3328,3340],[3342,3344],[3346,3396],[3398,3400],[3402,3407],[3412,3427],[3430,3455],[3457,3459],[3461,3478],[3482,3505],[3507,3515],[3517,3517],[3520,3526],[3530,3530],[3535,3540],[3542,3542],[3544,3551],[3558,3567],[3570,3572],[3585,3642],[3647,3675],[3713,3714],[3716,3716],[3718,3722],[3724,3747],[3749,3749],[3751,3773],[3776,3780],[3782,3782],[3784,3790],[3792,3801],[3804,3807],[3840,3911],[3913,3948],[3953,3991],[3993,4028],[4030,4044],[4046,4058],[4096,4293],[4295,4295],[4301,4301],[4304,4680],[4682,4685],[4688,4694],[4696,4696],[4698,4701],[4704,4744],[4746,4749],[4752,4784],[4786,4789],[4792,4798],[4800,4800],[4802,4805],[4808,4822],[4824,4880],[4882,4885],[4888,4954],[4957,4988],[4992,5017],[5024,5109],[5112,5117],[5120,5788],[5792,5880],[5888,5909],[5919,5942],[5952,5971],[5984,5996],[5998,6000],[6002,6003],[6016,6109],[6112,6121],[6128,6137],[6144,6169],[6176,6264],[6272,6314],[6320,6389],[6400,6430],[6432,6443],[6448,6459],[6464,6464],[6468,6509],[6512,6516],[6528,6571],[6576,6601],[6608,6618],[6622,6683],[6686,6750],[6752,6780],[6783,6793],[6800,6809],[6816,6829],[6832,6862],[6912,6988],[6992,7038],[7040,7155],[7164,7223],[7227,7241],[7245,7304],[7312,7354],[7357,7367],[7376,7418],[7424,7957],[7960,7965],[7968,8005],[8008,8013],[8016,8023],[8025,8025],[8027,8027],[8029,8029],[8031,8061],[8064,8116],[8118,8132],[8134,8147],[8150,8155],[8157,8175],[8178,8180],[8182,8190],[8192,8292],[8294,8305],[8308,8334],[8336,8348],[8352,8384],[8400,8432],[8448,8587],[8592,9254],[9280,9290],[9312,11123],[11126,11157],[11159,11507],[11513,11557],[11559,11559],[11565,11565],[11568,11623],[11631,11632],[11647,11670],[11680,11686],[11688,11694],[11696,11702],[11704,11710],[11712,11718],[11720,11726],[11728,11734],[11736,11742],[11744,11869],[11904,11929],[11931,12019],[12032,12245],[12272,12283],[12288,12351],[12353,12438],[12441,12543],[12549,12591],[12593,12686],[12688,12771],[12784,12830],[12832,42124],[42128,42182],[42192,42539],[42560,42743],[42752,42954],[42960,42961],[42963,42963],[42965,42969],[42994,43052],[43056,43065],[43072,43127],[43136,43205],[43214,43225],[43232,43347],[43359,43388],[43392,43469],[43471,43481],[43486,43518],[43520,43574],[43584,43597],[43600,43609],[43612,43714],[43739,43766],[43777,43782],[43785,43790],[43793,43798],[43808,43814],[43816,43822],[43824,43883],[43888,44013],[44016,44025],[44032,55203],[55216,55238],[55243,55291],[55296,64109],[64112,64217],[64256,64262],[64275,64279],[64285,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64450],[64467,64911],[64914,64967],[64975,64975],[65008,65049],[65056,65106],[65108,65126],[65128,65131],[65136,65140],[65142,65276],[65279,65279],[65281,65470],[65474,65479],[65482,65487],[65490,65495],[65498,65500],[65504,65510],[65512,65518],[65529,65533],[65536,65547],[65549,65574],[65576,65594],[65596,65597],[65599,65613],[65616,65629],[65664,65786],[65792,65794],[65799,65843],[65847,65934],[65936,65948],[65952,65952],[66000,66045],[66176,66204],[66208,66256],[66272,66299],[66304,66339],[66349,66378],[66384,66426],[66432,66461],[66463,66499],[66504,66517],[66560,66717],[66720,66729],[66736,66771],[66776,66811],[66816,66855],[66864,66915],[66927,66938],[66940,66954],[66956,66962],[66964,66965],[66967,66977],[66979,66993],[66995,67001],[67003,67004],[67072,67382],[67392,67413],[67424,67431],[67456,67461],[67463,67504],[67506,67514],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67742],[67751,67759],[67808,67826],[67828,67829],[67835,67867],[67871,67897],[67903,67903],[67968,68023],[68028,68047],[68050,68099],[68101,68102],[68108,68115],[68117,68119],[68121,68149],[68152,68154],[68159,68168],[68176,68184],[68192,68255],[68288,68326],[68331,68342],[68352,68405],[68409,68437],[68440,68466],[68472,68497],[68505,68508],[68521,68527],[68608,68680],[68736,68786],[68800,68850],[68858,68903],[68912,68921],[69216,69246],[69248,69289],[69291,69293],[69296,69297],[69373,69415],[69424,69465],[69488,69513],[69552,69579],[69600,69622],[69632,69709],[69714,69749],[69759,69826],[69837,69837],[69840,69864],[69872,69881],[69888,69940],[69942,69959],[69968,70006],[70016,70111],[70113,70132],[70144,70161],[70163,70209],[70272,70278],[70280,70280],[70282,70285],[70287,70301],[70303,70313],[70320,70378],[70384,70393],[70400,70403],[70405,70412],[70415,70416],[70419,70440],[70442,70448],[70450,70451],[70453,70457],[70459,70468],[70471,70472],[70475,70477],[70480,70480],[70487,70487],[70493,70499],[70502,70508],[70512,70516],[70656,70747],[70749,70753],[70784,70855],[70864,70873],[71040,71093],[71096,71133],[71168,71236],[71248,71257],[71264,71276],[71296,71353],[71360,71369],[71424,71450],[71453,71467],[71472,71494],[71680,71739],[71840,71922],[71935,71942],[71945,71945],[71948,71955],[71957,71958],[71960,71989],[71991,71992],[71995,72006],[72016,72025],[72096,72103],[72106,72151],[72154,72164],[72192,72263],[72272,72354],[72368,72440],[72448,72457],[72704,72712],[72714,72758],[72760,72773],[72784,72812],[72816,72847],[72850,72871],[72873,72886],[72960,72966],[72968,72969],[72971,73014],[73018,73018],[73020,73021],[73023,73031],[73040,73049],[73056,73061],[73063,73064],[73066,73102],[73104,73105],[73107,73112],[73120,73129],[73440,73464],[73472,73488],[73490,73530],[73534,73561],[73648,73648],[73664,73713],[73727,74649],[74752,74862],[74864,74868],[74880,75075],[77712,77810],[77824,78933],[82944,83526],[92160,92728],[92736,92766],[92768,92777],[92782,92862],[92864,92873],[92880,92909],[92912,92917],[92928,92997],[93008,93017],[93019,93025],[93027,93047],[93053,93071],[93760,93850],[93952,94026],[94031,94087],[94095,94111],[94176,94180],[94192,94193],[94208,100343],[100352,101589],[101632,101640],[110576,110579],[110581,110587],[110589,110590],[110592,110882],[110898,110898],[110928,110930],[110933,110933],[110948,110951],[110960,111355],[113664,113770],[113776,113788],[113792,113800],[113808,113817],[113820,113827],[118528,118573],[118576,118598],[118608,118723],[118784,119029],[119040,119078],[119081,119274],[119296,119365],[119488,119507],[119520,119539],[119552,119638],[119648,119672],[119808,119892],[119894,119964],[119966,119967],[119970,119970],[119973,119974],[119977,119980],[119982,119993],[119995,119995],[119997,120003],[120005,120069],[120071,120074],[120077,120084],[120086,120092],[120094,120121],[120123,120126],[120128,120132],[120134,120134],[120138,120144],[120146,120485],[120488,120779],[120782,121483],[121499,121503],[121505,121519],[122624,122654],[122661,122666],[122880,122886],[122888,122904],[122907,122913],[122915,122916],[122918,122922],[122928,122989],[123023,123023],[123136,123180],[123184,123197],[123200,123209],[123214,123215],[123536,123566],[123584,123641],[123647,123647],[124112,124153],[124896,124902],[124904,124907],[124909,124910],[124912,124926],[124928,125124],[125127,125142],[125184,125259],[125264,125273],[125278,125279],[126065,126132],[126209,126269],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[126704,126705],[126976,127019],[127024,127123],[127136,127150],[127153,127167],[127169,127183],[127185,127221],[127232,127405],[127462,127490],[127504,127547],[127552,127560],[127568,127569],[127584,127589],[127744,128727],[128732,128748],[128752,128764],[128768,128886],[128891,128985],[128992,129003],[129008,129008],[129024,129035],[129040,129095],[129104,129113],[129120,129159],[129168,129197],[129200,129201],[129280,129619],[129632,129645],[129648,129660],[129664,129672],[129680,129725],[129727,129733],[129742,129755],[129760,129768],[129776,129784],[129792,129938],[129940,129994],[130032,130041],[131072,173791],[173824,177977],[177984,178205],[178208,183969],[183984,191456],[194560,195101],[196608,201546],[201552,205743],[917505,917505],[917536,917631],[917760,917999],[983040,1048573],[1048576,1114109]],"format":[[173,173],[1536,1541],[1564,1564],[1757,1757],[1807,1807],[2192,2193],[2274,2274],[6158,6158],[8203,8207],[8234,8238],[8288,8292],[8294,8303],[65279,65279],[65529,65531],[69821,69821],[69837,69837],[78896,78911],[113824,113827],[119155,119162],[917505,917505],[917536,917631]],"combiningClass":[[768,230],[769,230],[770,230],[771,230],[772,230],[773,230],[774,230],[775,230],[776,230],[777,230],[778,230],[779,230],[780,230],[781,230],[782,230],[783,230],[784,230],[785,230],[786,230],[787,230],[788,230],[789,232],[790,220],[791,220],[792,220],[793,220],[794,232],[795,216],[796,220],[797,220],[798,220],[799,220],[800,220],[801,202],[802,202],[803,220],[804,220],[805,220],[806,220],[807,202],[808,202],[809,220],[810,220],[811,220],[812,220],[813,220],[814,220],[815,220],[816,220],[817,220],[818,220],[819,220],[820,1],[821,1],[822,1],[823,1],[824,1],[825,220],[826,220],[827,220],[828,220],[829,230],[830,230],[831,230],[832,230],[833,230],[834,230],[835,230],[836,230],[837,240],[838,230],[839,220],[840,220],[841,220],[842,230],[843,230],[844,230],[845,220],[846,220],[848,230],[849,230],[850,230],[851,220],[852,220],[853,220],[854,220],[855,230],[856,232],[857,220],[858,220],[859,230],[860,233],[861,234],[862,234],[863,233],[864,234],[865,234],[866,233],[867,230],[868,230],[869,230],[870,230],[871,230],[872,230],[873,230],[874,230],[875,230],[876,230],[877,230],[878,230],[879,230],[1155,230],[1156,230],[1157,230],[1158,230],[1159,230],[1425,220],[1426,230],[1427,230],[1428,230],[1429,230],[1430,220],[1431,230],[1432,230],[1433,230],[1434,222],[1435,220],[1436,230],[1437,230],[1438,230],[1439,230],[1440,230],[1441,230],[1442,220],[1443,220],[1444,220],[1445,220],[1446,220],[1447,220],[1448,230],[1449,230],[1450,220],[1451,230],[1452,230],[1453,222],[1454,228],[1455,230],[1456,10],[1457,11],[1458,12],[1459,13],[1460,14],[1461,15],[1462,16],[1463,17],[1464,18],[1465,19],[1466,19],[1467,20],[1468,21],[1469,22],[1471,23],[1473,24],[1474,25],[1476,230],[1477,220],[1479,18],[1552,230],[1553,230],[1554,230],[1555,230],[1556,230],[1557,230],[1558,230],[1559,230],[1560,30],[1561,31],[1562,32],[1611,27],[1612,28],[1613,29],[1614,30],[1615,31],[1616,32],[1617,33],[1618,34],[1619,230],[1620,230],[1621,220],[1622,220],[1623,230],[1624,230],[1625,230],[1626,230],[1627,230],[1628,220],[1629,230],[1630,230],[1631,220],[1648,35],[1750,230],[1751,230],[1752,230],[1753,230],[1754,230],[1755,230],[1756,230],[1759,230],[1760,230],[1761,230],[1762,230],[1763,220],[1764,230],[1767,230],[1768,230],[1770,220],[1771,230],[1772,230],[1773,220],[1809,36],[1840,230],[1841,220],[1842,230],[1843,230],[1844,220],[1845,230],[1846,230],[1847,220],[1848,220],[1849,220],[1850,230],[1851,220],[1852,220],[1853,230],[1854,220],[1855,230],[1856,230],[1857,230],[1858,220],[1859,230],[1860,220],[1861,230],[1862,220],[1863,230],[1864,220],[1865,230],[1866,230],[2027,230],[2028,230],[2029,230],[2030,230],[2031,230],[2032,230],[2033,230],[2034,220],[2035,230],[2045,220],[2070,230],[2071,230],[2072,230],[2073,230],[2075,230],[2076,230],[2077,230],[2078,230],[2079,230],[2080,230],[2081,230],[2082,230],[2083,230],[2085,230],[2086,230],[2087,230],[2089,230],[2090,230],[2091,230],[2092,230],[2093,230],[2137,220],[2138,220],[2139,220],[2200,230],[2201,220],[2202,220],[2203,220],[2204,230],[2205,230],[2206,230],[2207,230],[2250,230],[2251,230],[2252,230],[2253,230],[2254,230],[2255,220],[2256,220],[2257,220],[2258,220],[2259,220],[2260,230],[2261,230],[2262,230],[2263,230],[2264,230],[2265,230],[2266,230],[2267,230],[2268,230],[2269,230],[2270,230],[2271,230],[2272,230],[2273,230],[2275,220],[2276,230],[2277,230],[2278,220],[2279,230],[2280,230],[2281,220],[2282,230],[2283,230],[2284,230],[2285,220],[2286,220],[2287,220],[2288,27],[2289,28],[2290,29],[2291,230],[2292,230],[2293,230],[2294,220],[2295,230],[2296,230],[2297,220],[2298,220],[2299,230],[2300,230],[2301,230],[2302,230],[2303,230],[2364,7],[2381,9],[2385,230],[2386,220],[2387,230],[2388,230],[2492,7],[2509,9],[2558,230],[2620,7],[2637,9],[2748,7],[2765,9],[2876,7],[2893,9],[3021,9],[3132,7],[3149,9],[3157,84],[3158,91],[3260,7],[3277,9],[3387,9],[3388,9],[3405,9],[3530,9],[3640,103],[3641,103],[3642,9],[3656,107],[3657,107],[3658,107],[3659,107],[3768,118],[3769,118],[3770,9],[3784,122],[3785,122],[3786,122],[3787,122],[3864,220],[3865,220],[3893,220],[3895,220],[3897,216],[3953,129],[3954,130],[3956,132],[3962,130],[3963,130],[3964,130],[3965,130],[3968,130],[3970,230],[3971,230],[3972,9],[3974,230],[3975,230],[4038,220],[4151,7],[4153,9],[4154,9],[4237,220],[4957,230],[4958,230],[4959,230],[5908,9],[5909,9],[5940,9],[6098,9],[6109,230],[6313,228],[6457,222],[6458,230],[6459,220],[6679,230],[6680,220],[6752,9],[6773,230],[6774,230],[6775,230],[6776,230],[6777,230],[6778,230],[6779,230],[6780,230],[6783,220],[6832,230],[6833,230],[6834,230],[6835,230],[6836,230],[6837,220],[6838,220],[6839,220],[6840,220],[6841,220],[6842,220],[6843,230],[6844,230],[6845,220],[6847,220],[6848,220],[6849,230],[6850,230],[6851,220],[6852,220],[6853,230],[6854,230],[6855,230],[6856,230],[6857,230],[6858,220],[6859,230],[6860,230],[6861,230],[6862,230],[6964,7],[6980,9],[7019,230],[7020,220],[7021,230],[7022,230],[7023,230],[7024,230],[7025,230],[7026,230],[7027,230],[7082,9],[7083,9],[7142,7],[7154,9],[7155,9],[7223,7],[7376,230],[7377,230],[7378,230],[7380,1],[7381,220],[7382,220],[7383,220],[7384,220],[7385,220],[7386,230],[7387,230],[7388,220],[7389,220],[7390,220],[7391,220],[7392,230],[7394,1],[7395,1],[7396,1],[7397,1],[7398,1],[7399,1],[7400,1],[7405,220],[7412,230],[7416,230],[7417,230],[7616,230],[7617,230],[7618,220],[7619,230],[7620,230],[7621,230],[7622,230],[7623,230],[7624,230],[7625,230],[7626,220],[7627,230],[7628,230],[7629,234],[7630,214],[7631,220],[7632,202],[7633,230],[7634,230],[7635,230],[7636,230],[7637,230],[7638,230],[7639,230],[7640,230],[7641,230],[7642,230],[7643,230],[7644,230],[7645,230],[7646,230],[7647,230],[7648,230],[7649,230],[7650,230],[7651,230],[7652,230],[7653,230],[7654,230],[7655,230],[7656,230],[7657,230],[7658,230],[7659,230],[7660,230],[7661,230],[7662,230],[7663,230],[7664,230],[7665,230],[7666,230],[7667,230],[7668,230],[7669,230],[7670,232],[7671,228],[7672,228],[7673,220],[7674,218],[7675,230],[7676,233],[7677,220],[7678,230],[7679,220],[8400,230],[8401,230],[8402,1],[8403,1],[8404,230],[8405,230],[8406,230],[8407,230],[8408,1],[8409,1],[8410,1],[8411,230],[8412,230],[8417,230],[8421,1],[8422,1],[8423,230],[8424,220],[8425,230],[8426,1],[8427,1],[8428,220],[8429,220],[8430,220],[8431,220],[8432,230],[11503,230],[11504,230],[11505,230],[11647,9],[11744,230],[11745,230],[11746,230],[11747,230],[11748,230],[11749,230],[11750,230],[11751,230],[11752,230],[11753,230],[11754,230],[11755,230],[11756,230],[11757,230],[11758,230],[11759,230],[11760,230],[11761,230],[11762,230],[11763,230],[11764,230],[11765,230],[11766,230],[11767,230],[11768,230],[11769,230],[11770,230],[11771,230],[11772,230],[11773,230],[11774,230],[11775,230],[12330,218],[12331,228],[12332,232],[12333,222],[12334,224],[12335,224],[12441,8],[12442,8],[42607,230],[42612,230],[42613,230],[42614,230],[42615,230],[42616,230],[42617,230],[42618,230],[42619,230],[42620,230],[42621,230],[42654,230],[42655,230],[42736,230],[42737,230],[43014,9],[43052,9],[43204,9],[43232,230],[43233,230],[43234,230],[43235,230],[43236,230],[43237,230],[43238,230],[43239,230],[43240,230],[43241,230],[43242,230],[43243,230],[43244,230],[43245,230],[43246,230],[43247,230],[43248,230],[43249,230],[43307,220],[43308,220],[43309,220],[43347,9],[43443,7],[43456,9],[43696,230],[43698,230],[43699,230],[43700,220],[43703,230],[43704,230],[43710,230],[43711,230],[43713,230],[43766,9],[44013,9],[64286,26],[65056,230],[65057,230],[65058,230],[65059,230],[65060,230],[65061,230],[65062,230],[65063,220],[65064,220],[65065,220],[65066,220],[65067,220],[65068,220],[65069,220],[65070,230],[65071,230],[66045,220],[66272,220],[66422,230],[66423,230],[66424,230],[66425,230],[66426,230],[68109,220],[68111,230],[68152,230],[68153,1],[68154,220],[68159,9],[68325,230],[68326,220],[68900,230],[68901,230],[68902,230],[68903,230],[69291,230],[69292,230],[69373,220],[69374,220],[69375,220],[69446,220],[69447,220],[69448,230],[69449,230],[69450,230],[69451,220],[69452,230],[69453,220],[69454,220],[69455,220],[69456,220],[69506,230],[69507,220],[69508,230],[69509,220],[69702,9],[69744,9],[69759,9],[69817,9],[69818,7],[69888,230],[69889,230],[69890,230],[69939,9],[69940,9],[70003,7],[70080,9],[70090,7],[70197,9],[70198,7],[70377,7],[70378,9],[70459,7],[70460,7],[70477,9],[70502,230],[70503,230],[70504,230],[70505,230],[70506,230],[70507,230],[70508,230],[70512,230],[70513,230],[70514,230],[70515,230],[70516,230],[70722,9],[70726,7],[70750,230],[70850,9],[70851,7],[71103,9],[71104,7],[71231,9],[71350,9],[71351,7],[71467,9],[71737,9],[71738,7],[71997,9],[71998,9],[72003,7],[72160,9],[72244,9],[72263,9],[72345,9],[72767,9],[73026,7],[73028,9],[73029,9],[73111,9],[73537,9],[73538,9],[92912,1],[92913,1],[92914,1],[92915,1],[92916,1],[92976,230],[92977,230],[92978,230],[92979,230],[92980,230],[92981,230],[92982,230],[94192,6],[94193,6],[113822,1],[119141,216],[119142,216],[119143,1],[119144,1],[119145,1],[119149,226],[119150,216],[119151,216],[119152,216],[119153,216],[119154,216],[119163,220],[119164,220],[119165,220],[119166,220],[119167,220],[119168,220],[119169,220],[119170,220],[119173,230],[119174,230],[119175,230],[119176,230],[119177,230],[119178,220],[119179,220],[119210,230],[119211,230],[119212,230],[119213,230],[119362,230],[119363,230],[119364,230],[122880,230],[122881,230],[122882,230],[122883,230],[122884,230],[122885,230],[122886,230],[122888,230],[122889,230],[122890,230],[122891,230],[122892,230],[122893,230],[122894,230],[122895,230],[122896,230],[122897,230],[122898,230],[122899,230],[122900,230],[122901,230],[122902,230],[122903,230],[122904,230],[122907,230],[122908,230],[122909,230],[122910,230],[122911,230],[122912,230],[122913,230],[122915,230],[122916,230],[122918,230],[122919,230],[122920,230],[122921,230],[122922,230],[123023,230],[123184,230],[123185,230],[123186,230],[123187,230],[123188,230],[123189,230],[123190,230],[123566,230],[123628,230],[123629,230],[123630,230],[123631,230],[124140,232],[124141,232],[124142,220],[124143,230],[125136,220],[125137,220],[125138,220],[125139,220],[125140,220],[125141,220],[125142,220],[125252,230],[125253,230],[125254,230],[125255,230],[125256,230],[125257,230],[125258,7]],"decompositions":[[192,65,768],[193,65,769],[194,65,770],[195,65,771],[196,65,776],[197,65,778],[199,67,807],[200,69,768],[201,69,769],[202,69,770],[203,69,776],[204,73,768],[205,73,769],[206,73,770],[207,73,776],[209,78,771],[210,79,768],[211,79,769],[212,79,770],[213,79,771],[214,79,776],[217,85,768],[218,85,769],[219,85,770],[220,85,776],[221,89,769],[224,97,768],[225,97,769],[226,97,770],[227,97,771],[228,97,776],[229,97,778],[231,99,807],[232,101,768],[233,101,769],[234,101,770],[235,101,776],[236,105,768],[237,105,769],[238,105,770],[239,105,776],[241,110,771],[242,111,768],[243,111,769],[244,111,770],[245,111,771],[246,111,776],[249,117,768],[250,117,769],[251,117,770],[252,117,776],[253,121,769],[255,121,776],[256,65,772],[257,97,772],[258,65,774],[259,97,774],[260,65,808],[261,97,808],[262,67,769],[263,99,769],[264,67,770],[265,99,770],[266,67,775],[267,99,775],[268,67,780],[269,99,780],[270,68,780],[271,100,780],[274,69,772],[275,101,772],[276,69,774],[277,101,774],[278,69,775],[279,101,775],[280,69,808],[281,101,808],[282,69,780],[283,101,780],[284,71,770],[285,103,770],[286,71,774],[287,103,774],[288,71,775],[289,103,775],[290,71,807],[291,103,807],[292,72,770],[293,104,770],[296,73,771],[297,105,771],[298,73,772],[299,105,772],[300,73,774],[301,105,774],[302,73,808],[303,105,808],[304,73,775],[308,74,770],[309,106,770],[310,75,807],[311,107,807],[313,76,769],[314,108,769],[315,76,807],[316,108,807],[317,76,780],[318,108,780],[323,78,769],[324,110,769],[325,78,807],[326,110,807],[327,78,780],[328,110,780],[332,79,772],[333,111,772],[334,79,774],[335,111,774],[336,79,779],[337,111,779],[340,82,769],[341,114,769],[342,82,807],[343,114,807],[344,82,780],[345,114,780],[346,83,769],[347,115,769],[348,83,770],[349,115,770],[350,83,807],[351,115,807],[352,83,780],[353,115,780],[354,84,807],[355,116,807],[356,84,780],[357,116,780],[360,85,771],[361,117,771],[362,85,772],[363,117,772],[364,85,774],[365,117,774],[366,85,778],[367,117,778],[368,85,779],[369,117,779],[370,85,808],[371,117,808],[372,87,770],[373,119,770],[374,89,770],[375,121,770],[376,89,776],[377,90,769],[378,122,769],[379,90,775],[380,122,775],[381,90,780],[382,122,780],[416,79,795],[417,111,795],[431,85,795],[432,117,795],[461,65,780],[462,97,780],[463,73,780],[464,105,780],[465,79,780],[466,111,780],[467,85,780],[468,117,780],[469,220,772],[470,252,772],[471,220,769],[472,252,769],[473,220,780],[474,252,780],[475,220,768],[476,252,768],[478,196,772],[479,228,772],[480,550,772],[481,551,772],[482,198,772],[483,230,772],[486,71,780],[487,103,780],[488,75,780],[489,107,780],[490,79,808],[491,111,808],[492,490,772],[493,491,772],[494,439,780],[495,658,780],[496,106,780],[500,71,769],[501,103,769],[504,78,768],[505,110,768],[506,197,769],[507,229,769],[508,198,769],[509,230,769],[510,216,769],[511,248,769],[512,65,783],[513,97,783],[514,65,785],[515,97,785],[516,69,783],[517,101,783],[518,69,785],[519,101,785],[520,73,783],[521,105,783],[522,73,785],[523,105,785],[524,79,783],[525,111,783],[526,79,785],[527,111,785],[528,82,783],[529,114,783],[530,82,785],[531,114,785],[532,85,783],[533,117,783],[534,85,785],[535,117,785],[536,83,806],[537,115,806],[538,84,806],[539,116,806],[542,72,780],[543,104,780],[550,65,775],[551,97,775],[552,69,807],[553,101,807],[554,214,772],[555,246,772],[556,213,772],[557,245,772],[558,79,775],[559,111,775],[560,558,772],[561,559,772],[562,89,772],[563,121,772],[832,768],[833,769],[835,787],[836,776,769],[884,697],[894,59],[901,168,769],[902,913,769],[903,183],[904,917,769],[905,919,769],[906,921,769],[908,927,769],[910,933,769],[911,937,769],[912,970,769],[938,921,776],[939,933,776],[940,945,769],[941,949,769],[942,951,769],[943,953,769],[944,971,769],[970,953,776],[971,965,776],[972,959,769],[973,965,769],[974,969,769],[979,978,769],[980,978,776],[1024,1045,768],[1025,1045,776],[1027,1043,769],[1031,1030,776],[1036,1050,769],[1037,1048,768],[1038,1059,774],[1049,1048,774],[1081,1080,774],[1104,1077,768],[1105,1077,776],[1107,1075,769],[1111,1110,776],[1116,1082,769],[1117,1080,768],[1118,1091,774],[1142,1140,783],[1143,1141,783],[1217,1046,774],[1218,1078,774],[1232,1040,774],[1233,1072,774],[1234,1040,776],[1235,1072,776],[1238,1045,774],[1239,1077,774],[1242,1240,776],[1243,1241,776],[1244,1046,776],[1245,1078,776],[1246,1047,776],[1247,1079,776],[1250,1048,772],[1251,1080,772],[1252,1048,776],[1253,1080,776],[1254,1054,776],[1255,1086,776],[1258,1256,776],[1259,1257,776],[1260,1069,776],[1261,1101,776],[1262,1059,772],[1263,1091,772],[1264,1059,776],[1265,1091,776],[1266,1059,779],[1267,1091,779],[1268,1063,776],[1269,1095,776],[1272,1067,776],[1273,1099,776],[1570,1575,1619],[1571,1575,1620],[1572,1608,1620],[1573,1575,1621],[1574,1610,1620],[1728,1749,1620],[1730,1729,1620],[1747,1746,1620],[2345,2344,2364],[2353,2352,2364],[2356,2355,2364],[2392,2325,2364],[2393,2326,2364],[2394,2327,2364],[2395,2332,2364],[2396,2337,2364],[2397,2338,2364],[2398,2347,2364],[2399,2351,2364],[2507,2503,2494],[2508,2503,2519],[2524,2465,2492],[2525,2466,2492],[2527,2479,2492],[2611,2610,2620],[2614,2616,2620],[2649,2582,2620],[2650,2583,2620],[2651,2588,2620],[2654,2603,2620],[2888,2887,2902],[2891,2887,2878],[2892,2887,2903],[2908,2849,2876],[2909,2850,2876],[2964,2962,3031],[3018,3014,3006],[3019,3015,3006],[3020,3014,3031],[3144,3142,3158],[3264,3263,3285],[3271,3270,3285],[3272,3270,3286],[3274,3270,3266],[3275,3274,3285],[3402,3398,3390],[3403,3399,3390],[3404,3398,3415],[3546,3545,3530],[3548,3545,3535],[3549,3548,3530],[3550,3545,3551],[3907,3906,4023],[3917,3916,4023],[3922,3921,4023],[3927,3926,4023],[3932,3931,4023],[3945,3904,4021],[3955,3953,3954],[3957,3953,3956],[3958,4018,3968],[3960,4019,3968],[3969,3953,3968],[3987,3986,4023],[3997,3996,4023],[4002,4001,4023],[4007,4006,4023],[4012,4011,4023],[4025,3984,4021],[4134,4133,4142],[6918,6917,6965],[6920,6919,6965],[6922,6921,6965],[6924,6923,6965],[6926,6925,6965],[6930,6929,6965],[6971,6970,6965],[6973,6972,6965],[6976,6974,6965],[6977,6975,6965],[6979,6978,6965],[7680,65,805],[7681,97,805],[7682,66,775],[7683,98,775],[7684,66,803],[7685,98,803],[7686,66,817],[7687,98,817],[7688,199,769],[7689,231,769],[7690,68,775],[7691,100,775],[7692,68,803],[7693,100,803],[7694,68,817],[7695,100,817],[7696,68,807],[7697,100,807],[7698,68,813],[7699,100,813],[7700,274,768],[7701,275,768],[7702,274,769],[7703,275,769],[7704,69,813],[7705,101,813],[7706,69,816],[7707,101,816],[7708,552,774],[7709,553,774],[7710,70,775],[7711,102,775],[7712,71,772],[7713,103,772],[7714,72,775],[7715,104,775],[7716,72,803],[7717,104,803],[7718,72,776],[7719,104,776],[7720,72,807],[7721,104,807],[7722,72,814],[7723,104,814],[7724,73,816],[7725,105,816],[7726,207,769],[7727,239,769],[7728,75,769],[7729,107,769],[7730,75,803],[7731,107,803],[7732,75,817],[7733,107,817],[7734,76,803],[7735,108,803],[7736,7734,772],[7737,7735,772],[7738,76,817],[7739,108,817],[7740,76,813],[7741,108,813],[7742,77,769],[7743,109,769],[7744,77,775],[7745,109,775],[7746,77,803],[7747,109,803],[7748,78,775],[7749,110,775],[7750,78,803],[7751,110,803],[7752,78,817],[7753,110,817],[7754,78,813],[7755,110,813],[7756,213,769],[7757,245,769],[7758,213,776],[7759,245,776],[7760,332,768],[7761,333,768],[7762,332,769],[7763,333,769],[7764,80,769],[7765,112,769],[7766,80,775],[7767,112,775],[7768,82,775],[7769,114,775],[7770,82,803],[7771,114,803],[7772,7770,772],[7773,7771,772],[7774,82,817],[7775,114,817],[7776,83,775],[7777,115,775],[7778,83,803],[7779,115,803],[7780,346,775],[7781,347,775],[7782,352,775],[7783,353,775],[7784,7778,775],[7785,7779,775],[7786,84,775],[7787,116,775],[7788,84,803],[7789,116,803],[7790,84,817],[7791,116,817],[7792,84,813],[7793,116,813],[7794,85,804],[7795,117,804],[7796,85,816],[7797,117,816],[7798,85,813],[7799,117,813],[7800,360,769],[7801,361,769],[7802,362,776],[7803,363,776],[7804,86,771],[7805,118,771],[7806,86,803],[7807,118,803],[7808,87,768],[7809,119,768],[7810,87,769],[7811,119,769],[7812,87,776],[7813,119,776],[7814,87,775],[7815,119,775],[7816,87,803],[7817,119,803],[7818,88,775],[7819,120,775],[7820,88,776],[7821,120,776],[7822,89,775],[7823,121,775],[7824,90,770],[7825,122,770],[7826,90,803],[7827,122,803],[7828,90,817],[7829,122,817],[7830,104,817],[7831,116,776],[7832,119,778],[7833,121,778],[7835,383,775],[7840,65,803],[7841,97,803],[7842,65,777],[7843,97,777],[7844,194,769],[7845,226,769],[7846,194,768],[7847,226,768],[7848,194,777],[7849,226,777],[7850,194,771],[7851,226,771],[7852,7840,770],[7853,7841,770],[7854,258,769],[7855,259,769],[7856,258,768],[7857,259,768],[7858,258,777],[7859,259,777],[7860,258,771],[7861,259,771],[7862,7840,774],[7863,7841,774],[7864,69,803],[7865,101,803],[7866,69,777],[7867,101,777],[7868,69,771],[7869,101,771],[7870,202,769],[7871,234,769],[7872,202,768],[7873,234,768],[7874,202,777],[7875,234,777],[7876,202,771],[7877,234,771],[7878,7864,770],[7879,7865,770],[7880,73,777],[7881,105,777],[7882,73,803],[7883,105,803],[7884,79,803],[7885,111,803],[7886,79,777],[7887,111,777],[7888,212,769],[7889,244,769],[7890,212,768],[7891,244,768],[7892,212,777],[7893,244,777],[7894,212,771],[7895,244,771],[7896,7884,770],[7897,7885,770],[7898,416,769],[7899,417,769],[7900,416,768],[7901,417,768],[7902,416,777],[7903,417,777],[7904,416,771],[7905,417,771],[7906,416,803],[7907,417,803],[7908,85,803],[7909,117,803],[7910,85,777],[7911,117,777],[7912,431,769],[7913,432,769],[7914,431,768],[7915,432,768],[7916,431,777],[7917,432,777],[7918,431,771],[7919,432,771],[7920,431,803],[7921,432,803],[7922,89,768],[7923,121,768],[7924,89,803],[7925,121,803],[7926,89,777],[7927,121,777],[7928,89,771],[7929,121,771],[7936,945,787],[7937,945,788],[7938,7936,768],[7939,7937,768],[7940,7936,769],[7941,7937,769],[7942,7936,834],[7943,7937,834],[7944,913,787],[7945,913,788],[7946,7944,768],[7947,7945,768],[7948,7944,769],[7949,7945,769],[7950,7944,834],[7951,7945,834],[7952,949,787],[7953,949,788],[7954,7952,768],[7955,7953,768],[7956,7952,769],[7957,7953,769],[7960,917,787],[7961,917,788],[7962,7960,768],[7963,7961,768],[7964,7960,769],[7965,7961,769],[7968,951,787],[7969,951,788],[7970,7968,768],[7971,7969,768],[7972,7968,769],[7973,7969,769],[7974,7968,834],[7975,7969,834],[7976,919,787],[7977,919,788],[7978,7976,768],[7979,7977,768],[7980,7976,769],[7981,7977,769],[7982,7976,834],[7983,7977,834],[7984,953,787],[7985,953,788],[7986,7984,768],[7987,7985,768],[7988,7984,769],[7989,7985,769],[7990,7984,834],[7991,7985,834],[7992,921,787],[7993,921,788],[7994,7992,768],[7995,7993,768],[7996,7992,769],[7997,7993,769],[7998,7992,834],[7999,7993,834],[8000,959,787],[8001,959,788],[8002,8000,768],[8003,8001,768],[8004,8000,769],[8005,8001,769],[8008,927,787],[8009,927,788],[8010,8008,768],[8011,8009,768],[8012,8008,769],[8013,8009,769],[8016,965,787],[8017,965,788],[8018,8016,768],[8019,8017,768],[8020,8016,769],[8021,8017,769],[8022,8016,834],[8023,8017,834],[8025,933,788],[8027,8025,768],[8029,8025,769],[8031,8025,834],[8032,969,787],[8033,969,788],[8034,8032,768],[8035,8033,768],[8036,8032,769],[8037,8033,769],[8038,8032,834],[8039,8033,834],[8040,937,787],[8041,937,788],[8042,8040,768],[8043,8041,768],[8044,8040,769],[8045,8041,769],[8046,8040,834],[8047,8041,834],[8048,945,768],[8049,945,769],[8050,949,768],[8051,949,769],[8052,951,768],[8053,951,769],[8054,953,768],[8055,953,769],[8056,959,768],[8057,959,769],[8058,965,768],[8059,965,769],[8060,969,768],[8061,969,769],[8064,7936,837],[8065,7937,837],[8066,7938,837],[8067,7939,837],[8068,7940,837],[8069,7941,837],[8070,7942,837],[8071,7943,837],[8072,7944,837],[8073,7945,837],[8074,7946,837],[8075,7947,837],[8076,7948,837],[8077,7949,837],[8078,7950,837],[8079,7951,837],[8080,7968,837],[8081,7969,837],[8082,7970,837],[8083,7971,837],[8084,7972,837],[8085,7973,837],[8086,7974,837],[8087,7975,837],[8088,7976,837],[8089,7977,837],[8090,7978,837],[8091,7979,837],[8092,7980,837],[8093,7981,837],[8094,7982,837],[8095,7983,837],[8096,8032,837],[8097,8033,837],[8098,8034,837],[8099,8035,837],[8100,8036,837],[8101,8037,837],[8102,8038,837],[8103,8039,837],[8104,8040,837],[8105,8041,837],[8106,8042,837],[8107,8043,837],[8108,8044,837],[8109,8045,837],[8110,8046,837],[8111,8047,837],[8112,945,774],[8113,945,772],[8114,8048,837],[8115,945,837],[8116,940,837],[8118,945,834],[8119,8118,837],[8120,913,774],[8121,913,772],[8122,913,768],[8123,913,769],[8124,913,837],[8126,953],[8129,168,834],[8130,8052,837],[8131,951,837],[8132,942,837],[8134,951,834],[8135,8134,837],[8136,917,768],[8137,917,769],[8138,919,768],[8139,919,769],[8140,919,837],[8141,8127,768],[8142,8127,769],[8143,8127,834],[8144,953,774],[8145,953,772],[8146,970,768],[8147,953,776,769],[8150,953,834],[8151,970,834],[8152,921,774],[8153,921,772],[8154,921,768],[8155,921,769],[8157,8190,768],[8158,8190,769],[8159,8190,834],[8160,965,774],[8161,965,772],[8162,971,768],[8163,965,776,769],[8164,961,787],[8165,961,788],[8166,965,834],[8167,971,834],[8168,933,774],[8169,933,772],[8170,933,768],[8171,933,769],[8172,929,788],[8173,168,768],[8174,168,769],[8175,96],[8178,8060,837],[8179,969,837],[8180,974,837],[8182,969,834],[8183,8182,837],[8184,927,768],[8185,927,769],[8186,937,768],[8187,937,769],[8188,937,837],[8189,180],[8192,8194],[8193,8195],[8486,937],[8490,75],[8491,65,778],[8602,8592,824],[8603,8594,824],[8622,8596,824],[8653,8656,824],[8654,8660,824],[8655,8658,824],[8708,8707,824],[8713,8712,824],[8716,8715,824],[8740,8739,824],[8742,8741,824],[8769,8764,824],[8772,8771,824],[8775,8773,824],[8777,8776,824],[8800,61,824],[8802,8801,824],[8813,8781,824],[8814,60,824],[8815,62,824],[8816,8804,824],[8817,8805,824],[8820,8818,824],[8821,8819,824],[8824,8822,824],[8825,8823,824],[8832,8826,824],[8833,8827,824],[8836,8834,824],[8837,8835,824],[8840,8838,824],[8841,8839,824],[8876,8866,824],[8877,8872,824],[8878,8873,824],[8879,8875,824],[8928,8828,824],[8929,8829,824],[8930,8849,824],[8931,8850,824],[8938,8882,824],[8939,8883,824],[8940,8884,824],[8941,8885,824],[9001,12296],[9002,12297],[10972,10973,824],[12364,12363,12441],[12366,12365,12441],[12368,12367,12441],[12370,12369,12441],[12372,12371,12441],[12374,12373,12441],[12376,12375,12441],[12378,12377,12441],[12380,12379,12441],[12382,12381,12441],[12384,12383,12441],[12386,12385,12441],[12389,12388,12441],[12391,12390,12441],[12393,12392,12441],[12400,12399,12441],[12401,12399,12442],[12403,12402,12441],[12404,12402,12442],[12406,12405,12441],[12407,12405,12442],[12409,12408,12441],[12410,12408,12442],[12412,12411,12441],[12413,12411,12442],[12436,12358,12441],[12446,12445,12441],[12460,12459,12441],[12462,12461,12441],[12464,12463,12441],[12466,12465,12441],[12468,12467,12441],[12470,12469,12441],[12472,12471,12441],[12474,12473,12441],[12476,12475,12441],[12478,12477,12441],[12480,12479,12441],[12482,12481,12441],[12485,12484,12441],[12487,12486,12441],[12489,12488,12441],[12496,12495,12441],[12497,12495,12442],[12499,12498,12441],[12500,12498,12442],[12502,12501,12441],[12503,12501,12442],[12505,12504,12441],[12506,12504,12442],[12508,12507,12441],[12509,12507,12442],[12532,12454,12441],[12535,12527,12441],[12536,12528,12441],[12537,12529,12441],[12538,12530,12441],[12542,12541,12441],[63744,35912],[63745,26356],[63746,36554],[63747,36040],[63748,28369],[63749,20018],[63750,21477],[63751,40860],[63752,40860],[63753,22865],[63754,37329],[63755,21895],[63756,22856],[63757,25078],[63758,30313],[63759,32645],[63760,34367],[63761,34746],[63762,35064],[63763,37007],[63764,27138],[63765,27931],[63766,28889],[63767,29662],[63768,33853],[63769,37226],[63770,39409],[63771,20098],[63772,21365],[63773,27396],[63774,29211],[63775,34349],[63776,40478],[63777,23888],[63778,28651],[63779,34253],[63780,35172],[63781,25289],[63782,33240],[63783,34847],[63784,24266],[63785,26391],[63786,28010],[63787,29436],[63788,37070],[63789,20358],[63790,20919],[63791,21214],[63792,25796],[63793,27347],[63794,29200],[63795,30439],[63796,32769],[63797,34310],[63798,34396],[63799,36335],[63800,38706],[63801,39791],[63802,40442],[63803,30860],[63804,31103],[63805,32160],[63806,33737],[63807,37636],[63808,40575],[63809,35542],[63810,22751],[63811,24324],[63812,31840],[63813,32894],[63814,29282],[63815,30922],[63816,36034],[63817,38647],[63818,22744],[63819,23650],[63820,27155],[63821,28122],[63822,28431],[63823,32047],[63824,32311],[63825,38475],[63826,21202],[63827,32907],[63828,20956],[63829,20940],[63830,31260],[63831,32190],[63832,33777],[63833,38517],[63834,35712],[63835,25295],[63836,27138],[63837,35582],[63838,20025],[63839,23527],[63840,24594],[63841,29575],[63842,30064],[63843,21271],[63844,30971],[63845,20415],[63846,24489],[63847,19981],[63848,27852],[63849,25976],[63850,32034],[63851,21443],[63852,22622],[63853,30465],[63854,33865],[63855,35498],[63856,27578],[63857,36784],[63858,27784],[63859,25342],[63860,33509],[63861,25504],[63862,30053],[63863,20142],[63864,20841],[63865,20937],[63866,26753],[63867,31975],[63868,33391],[63869,35538],[63870,37327],[63871,21237],[63872,21570],[63873,22899],[63874,24300],[63875,26053],[63876,28670],[63877,31018],[63878,38317],[63879,39530],[63880,40599],[63881,40654],[63882,21147],[63883,26310],[63884,27511],[63885,36706],[63886,24180],[63887,24976],[63888,25088],[63889,25754],[63890,28451],[63891,29001],[63892,29833],[63893,31178],[63894,32244],[63895,32879],[63896,36646],[63897,34030],[63898,36899],[63899,37706],[63900,21015],[63901,21155],[63902,21693],[63903,28872],[63904,35010],[63905,35498],[63906,24265],[63907,24565],[63908,25467],[63909,27566],[63910,31806],[63911,29557],[63912,20196],[63913,22265],[63914,23527],[63915,23994],[63916,24604],[63917,29618],[63918,29801],[63919,32666],[63920,32838],[63921,37428],[63922,38646],[63923,38728],[63924,38936],[63925,20363],[63926,31150],[63927,37300],[63928,38584],[63929,24801],[63930,20102],[63931,20698],[63932,23534],[63933,23615],[63934,26009],[63935,27138],[63936,29134],[63937,30274],[63938,34044],[63939,36988],[63940,40845],[63941,26248],[63942,38446],[63943,21129],[63944,26491],[63945,26611],[63946,27969],[63947,28316],[63948,29705],[63949,30041],[63950,30827],[63951,32016],[63952,39006],[63953,20845],[63954,25134],[63955,38520],[63956,20523],[63957,23833],[63958,28138],[63959,36650],[63960,24459],[63961,24900],[63962,26647],[63963,29575],[63964,38534],[63965,21033],[63966,21519],[63967,23653],[63968,26131],[63969,26446],[63970,26792],[63971,27877],[63972,29702],[63973,30178],[63974,32633],[63975,35023],[63976,35041],[63977,37324],[63978,38626],[63979,21311],[63980,28346],[63981,21533],[63982,29136],[63983,29848],[63984,34298],[63985,38563],[63986,40023],[63987,40607],[63988,26519],[63989,28107],[63990,33256],[63991,31435],[63992,31520],[63993,31890],[63994,29376],[63995,28825],[63996,35672],[63997,20160],[63998,33590],[63999,21050],[64000,20999],[64001,24230],[64002,25299],[64003,31958],[64004,23429],[64005,27934],[64006,26292],[64007,36667],[64008,34892],[64009,38477],[64010,35211],[64011,24275],[64012,20800],[64013,21952],[64016,22618],[64018,26228],[64021,20958],[64022,29482],[64023,30410],[64024,31036],[64025,31070],[64026,31077],[64027,31119],[64028,38742],[64029,31934],[64030,32701],[64032,34322],[64034,35576],[64037,36920],[64038,37117],[64042,39151],[64043,39164],[64044,39208],[64045,40372],[64046,37086],[64047,38583],[64048,20398],[64049,20711],[64050,20813],[64051,21193],[64052,21220],[64053,21329],[64054,21917],[64055,22022],[64056,22120],[64057,22592],[64058,22696],[64059,23652],[64060,23662],[64061,24724],[64062,24936],[64063,24974],[64064,25074],[64065,25935],[64066,26082],[64067,26257],[64068,26757],[64069,28023],[64070,28186],[64071,28450],[64072,29038],[64073,29227],[64074,29730],[64075,30865],[64076,31038],[64077,31049],[64078,31048],[64079,31056],[64080,31062],[64081,31069],[64082,31117],[64083,31118],[64084,31296],[64085,31361],[64086,31680],[64087,32244],[64088,32265],[64089,32321],[64090,32626],[64091,32773],[64092,33261],[64093,33401],[64094,33401],[64095,33879],[64096,35088],[64097,35222],[64098,35585],[64099,35641],[64100,36051],[64101,36104],[64102,36790],[64103,36920],[64104,38627],[64105,38911],[64106,38971],[64107,24693],[64108,148206],[64109,33304],[64112,20006],[64113,20917],[64114,20840],[64115,20352],[64116,20805],[64117,20864],[64118,21191],[64119,21242],[64120,21917],[64121,21845],[64122,21913],[64123,21986],[64124,22618],[64125,22707],[64126,22852],[64127,22868],[64128,23138],[64129,23336],[64130,24274],[64131,24281],[64132,24425],[64133,24493],[64134,24792],[64135,24910],[64136,24840],[64137,24974],[64138,24928],[64139,25074],[64140,25140],[64141,25540],[64142,25628],[64143,25682],[64144,25942],[64145,26228],[64146,26391],[64147,26395],[64148,26454],[64149,27513],[64150,27578],[64151,27969],[64152,28379],[64153,28363],[64154,28450],[64155,28702],[64156,29038],[64157,30631],[64158,29237],[64159,29359],[64160,29482],[64161,29809],[64162,29958],[64163,30011],[64164,30237],[64165,30239],[64166,30410],[64167,30427],[64168,30452],[64169,30538],[64170,30528],[64171,30924],[64172,31409],[64173,31680],[64174,31867],[64175,32091],[64176,32244],[64177,32574],[64178,32773],[64179,33618],[64180,33775],[64181,34681],[64182,35137],[64183,35206],[64184,35222],[64185,35519],[64186,35576],[64187,35531],[64188,35585],[64189,35582],[64190,35565],[64191,35641],[64192,35722],[64193,36104],[64194,36664],[64195,36978],[64196,37273],[64197,37494],[64198,38524],[64199,38627],[64200,38742],[64201,38875],[64202,38911],[64203,38923],[64204,38971],[64205,39698],[64206,40860],[64207,141386],[64208,141380],[64209,144341],[64210,15261],[64211,16408],[64212,16441],[64213,152137],[64214,154832],[64215,163539],[64216,40771],[64217,40846],[64285,1497,1460],[64287,1522,1463],[64298,1513,1473],[64299,1513,1474],[64300,1513,1468,1473],[64301,1513,1468,1474],[64302,1488,1463],[64303,1488,1464],[64304,1488,1468],[64305,1489,1468],[64306,1490,1468],[64307,1491,1468],[64308,1492,1468],[64309,1493,1468],[64310,1494,1468],[64312,1496,1468],[64313,1497,1468],[64314,1498,1468],[64315,1499,1468],[64316,1500,1468],[64318,1502,1468],[64320,1504,1468],[64321,1505,1468],[64323,1507,1468],[64324,1508,1468],[64326,1510,1468],[64327,1511,1468],[64328,1512,1468],[64329,1513,1468],[64330,1514,1468],[64331,1493,1465],[64332,1489,1471],[64333,1499,1471],[64334,1508,1471],[69786,69785,69818],[69788,69787,69818],[69803,69797,69818],[69934,69937,69927],[69935,69938,69927],[70475,70471,70462],[70476,70471,70487],[70843,70841,70842],[70844,70841,70832],[70846,70841,70845],[71098,71096,71087],[71099,71097,71087],[71992,71989,71984],[119134,119127,119141],[119135,119128,119141],[119136,119128,119141,119150],[119137,119128,119141,119151],[119138,119128,119141,119152],[119139,119128,119141,119153],[119140,119128,119141,119154],[119227,119225,119141],[119228,119226,119141],[119229,119225,119141,119150],[119230,119226,119141,119150],[119231,119225,119141,119151],[119232,119226,119141,119151],[194560,20029],[194561,20024],[194562,20033],[194563,131362],[194564,20320],[194565,20398],[194566,20411],[194567,20482],[194568,20602],[194569,20633],[194570,20711],[194571,20687],[194572,13470],[194573,132666],[194574,20813],[194575,20820],[194576,20836],[194577,20855],[194578,132380],[194579,13497],[194580,20839],[194581,20877],[194582,132427],[194583,20887],[194584,20900],[194585,20172],[194586,20908],[194587,20917],[194588,168415],[194589,20981],[194590,20995],[194591,13535],[194592,21051],[194593,21062],[194594,21106],[194595,21111],[194596,13589],[194597,21191],[194598,21193],[194599,21220],[194600,21242],[194601,21253],[194602,21254],[194603,21271],[194604,21321],[194605,21329],[194606,21338],[194607,21363],[194608,21373],[194609,21375],[194610,21375],[194611,21375],[194612,133676],[194613,28784],[194614,21450],[194615,21471],[194616,133987],[194617,21483],[194618,21489],[194619,21510],[194620,21662],[194621,21560],[194622,21576],[194623,21608],[194624,21666],[194625,21750],[194626,21776],[194627,21843],[194628,21859],[194629,21892],[194630,21892],[194631,21913],[194632,21931],[194633,21939],[194634,21954],[194635,22294],[194636,22022],[194637,22295],[194638,22097],[194639,22132],[194640,20999],[194641,22766],[194642,22478],[194643,22516],[194644,22541],[194645,22411],[194646,22578],[194647,22577],[194648,22700],[194649,136420],[194650,22770],[194651,22775],[194652,22790],[194653,22810],[194654,22818],[194655,22882],[194656,136872],[194657,136938],[194658,23020],[194659,23067],[194660,23079],[194661,23000],[194662,23142],[194663,14062],[194664,14076],[194665,23304],[194666,23358],[194667,23358],[194668,137672],[194669,23491],[194670,23512],[194671,23527],[194672,23539],[194673,138008],[194674,23551],[194675,23558],[194676,24403],[194677,23586],[194678,14209],[194679,23648],[194680,23662],[194681,23744],[194682,23693],[194683,138724],[194684,23875],[194685,138726],[194686,23918],[194687,23915],[194688,23932],[194689,24033],[194690,24034],[194691,14383],[194692,24061],[194693,24104],[194694,24125],[194695,24169],[194696,14434],[194697,139651],[194698,14460],[194699,24240],[194700,24243],[194701,24246],[194702,24266],[194703,172946],[194704,24318],[194705,140081],[194706,140081],[194707,33281],[194708,24354],[194709,24354],[194710,14535],[194711,144056],[194712,156122],[194713,24418],[194714,24427],[194715,14563],[194716,24474],[194717,24525],[194718,24535],[194719,24569],[194720,24705],[194721,14650],[194722,14620],[194723,24724],[194724,141012],[194725,24775],[194726,24904],[194727,24908],[194728,24910],[194729,24908],[194730,24954],[194731,24974],[194732,25010],[194733,24996],[194734,25007],[194735,25054],[194736,25074],[194737,25078],[194738,25104],[194739,25115],[194740,25181],[194741,25265],[194742,25300],[194743,25424],[194744,142092],[194745,25405],[194746,25340],[194747,25448],[194748,25475],[194749,25572],[194750,142321],[194751,25634],[194752,25541],[194753,25513],[194754,14894],[194755,25705],[194756,25726],[194757,25757],[194758,25719],[194759,14956],[194760,25935],[194761,25964],[194762,143370],[194763,26083],[194764,26360],[194765,26185],[194766,15129],[194767,26257],[194768,15112],[194769,15076],[194770,20882],[194771,20885],[194772,26368],[194773,26268],[194774,32941],[194775,17369],[194776,26391],[194777,26395],[194778,26401],[194779,26462],[194780,26451],[194781,144323],[194782,15177],[194783,26618],[194784,26501],[194785,26706],[194786,26757],[194787,144493],[194788,26766],[194789,26655],[194790,26900],[194791,15261],[194792,26946],[194793,27043],[194794,27114],[194795,27304],[194796,145059],[194797,27355],[194798,15384],[194799,27425],[194800,145575],[194801,27476],[194802,15438],[194803,27506],[194804,27551],[194805,27578],[194806,27579],[194807,146061],[194808,138507],[194809,146170],[194810,27726],[194811,146620],[194812,27839],[194813,27853],[194814,27751],[194815,27926],[194816,27966],[194817,28023],[194818,27969],[194819,28009],[194820,28024],[194821,28037],[194822,146718],[194823,27956],[194824,28207],[194825,28270],[194826,15667],[194827,28363],[194828,28359],[194829,147153],[194830,28153],[194831,28526],[194832,147294],[194833,147342],[194834,28614],[194835,28729],[194836,28702],[194837,28699],[194838,15766],[194839,28746],[194840,28797],[194841,28791],[194842,28845],[194843,132389],[194844,28997],[194845,148067],[194846,29084],[194847,148395],[194848,29224],[194849,29237],[194850,29264],[194851,149000],[194852,29312],[194853,29333],[194854,149301],[194855,149524],[194856,29562],[194857,29579],[194858,16044],[194859,29605],[194860,16056],[194861,16056],[194862,29767],[194863,29788],[194864,29809],[194865,29829],[194866,29898],[194867,16155],[194868,29988],[194869,150582],[194870,30014],[194871,150674],[194872,30064],[194873,139679],[194874,30224],[194875,151457],[194876,151480],[194877,151620],[194878,16380],[194879,16392],[194880,30452],[194881,151795],[194882,151794],[194883,151833],[194884,151859],[194885,30494],[194886,30495],[194887,30495],[194888,30538],[194889,16441],[194890,30603],[194891,16454],[194892,16534],[194893,152605],[194894,30798],[194895,30860],[194896,30924],[194897,16611],[194898,153126],[194899,31062],[194900,153242],[194901,153285],[194902,31119],[194903,31211],[194904,16687],[194905,31296],[194906,31306],[194907,31311],[194908,153980],[194909,154279],[194910,154279],[194911,31470],[194912,16898],[194913,154539],[194914,31686],[194915,31689],[194916,16935],[194917,154752],[194918,31954],[194919,17056],[194920,31976],[194921,31971],[194922,32000],[194923,155526],[194924,32099],[194925,17153],[194926,32199],[194927,32258],[194928,32325],[194929,17204],[194930,156200],[194931,156231],[194932,17241],[194933,156377],[194934,32634],[194935,156478],[194936,32661],[194937,32762],[194938,32773],[194939,156890],[194940,156963],[194941,32864],[194942,157096],[194943,32880],[194944,144223],[194945,17365],[194946,32946],[194947,33027],[194948,17419],[194949,33086],[194950,23221],[194951,157607],[194952,157621],[194953,144275],[194954,144284],[194955,33281],[194956,33284],[194957,36766],[194958,17515],[194959,33425],[194960,33419],[194961,33437],[194962,21171],[194963,33457],[194964,33459],[194965,33469],[194966,33510],[194967,158524],[194968,33509],[194969,33565],[194970,33635],[194971,33709],[194972,33571],[194973,33725],[194974,33767],[194975,33879],[194976,33619],[194977,33738],[194978,33740],[194979,33756],[194980,158774],[194981,159083],[194982,158933],[194983,17707],[194984,34033],[194985,34035],[194986,34070],[194987,160714],[194988,34148],[194989,159532],[194990,17757],[194991,17761],[194992,159665],[194993,159954],[194994,17771],[194995,34384],[194996,34396],[194997,34407],[194998,34409],[194999,34473],[195000,34440],[195001,34574],[195002,34530],[195003,34681],[195004,34600],[195005,34667],[195006,34694],[195007,17879],[195008,34785],[195009,34817],[195010,17913],[195011,34912],[195012,34915],[195013,161383],[195014,35031],[195015,35038],[195016,17973],[195017,35066],[195018,13499],[195019,161966],[195020,162150],[195021,18110],[195022,18119],[195023,35488],[195024,35565],[195025,35722],[195026,35925],[195027,162984],[195028,36011],[195029,36033],[195030,36123],[195031,36215],[195032,163631],[195033,133124],[195034,36299],[195035,36284],[195036,36336],[195037,133342],[195038,36564],[195039,36664],[195040,165330],[195041,165357],[195042,37012],[195043,37105],[195044,37137],[195045,165678],[195046,37147],[195047,37432],[195048,37591],[195049,37592],[195050,37500],[195051,37881],[195052,37909],[195053,166906],[195054,38283],[195055,18837],[195056,38327],[195057,167287],[195058,18918],[195059,38595],[195060,23986],[195061,38691],[195062,168261],[195063,168474],[195064,19054],[195065,19062],[195066,38880],[195067,168970],[195068,19122],[195069,169110],[195070,38923],[195071,38923],[195072,38953],[195073,169398],[195074,39138],[195075,19251],[195076,39209],[195077,39335],[195078,39362],[195079,39422],[195080,19406],[195081,170800],[195082,39698],[195083,40000],[195084,40189],[195085,19662],[195086,19693],[195087,40295],[195088,172238],[195089,19704],[195090,172293],[195091,172558],[195092,172689],[195093,40635],[195094,19798],[195095,40697],[195096,40702],[195097,40709],[195098,40719],[195099,40726],[195100,40763],[195101,173568]],"composites":[192,193,194,195,196,197,199,200,201,202,203,204,205,206,207,209,210,211,212,213,214,217,218,219,220,221,224,225,226,227,228,229,231,232,233,234,235,236,237,238,239,241,242,243,244,245,246,249,250,251,252,253,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,296,297,298,299,300,301,302,303,304,308,309,310,311,313,314,315,316,317,318,323,324,325,326,327,328,332,333,334,335,336,337,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,416,417,431,432,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,478,479,480,481,482,483,486,487,488,489,490,491,492,493,494,495,496,500,501,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,542,543,550,551,552,553,554,555,556,557,558,559,560,561,562,563,901,902,904,905,906,908,910,911,912,938,939,940,941,942,943,944,970,971,972,973,974,979,980,1024,1025,1027,1031,1036,1037,1038,1049,1081,1104,1105,1107,1111,1116,1117,1118,1142,1143,1217,1218,1232,1233,1234,1235,1238,1239,1242,1243,1244,1245,1246,1247,1250,1251,1252,1253,1254,1255,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1272,1273,1570,1571,1572,1573,1574,1728,1730,1747,2345,2353,2356,2507,2508,2888,2891,2892,2964,3018,3019,3020,3144,3264,3271,3272,3274,3275,3402,3403,3404,3546,3548,3549,3550,4134,6918,6920,6922,6924,6926,6930,6971,6973,6976,6977,6979,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7835,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8050,8052,8054,8056,8058,8060,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8124,8129,8130,8131,8132,8134,8135,8136,8138,8140,8141,8142,8143,8144,8145,8146,8150,8151,8152,8153,8154,8157,8158,8159,8160,8161,8162,8164,8165,8166,8167,8168,8169,8170,8172,8173,8178,8179,8180,8182,8183,8184,8186,8188,8602,8603,8622,8653,8654,8655,8708,8713,8716,8740,8742,8769,8772,8775,8777,8800,8802,8813,8814,8815,8816,8817,8820,8821,8824,8825,8832,8833,8836,8837,8840,8841,8876,8877,8878,8879,8928,8929,8930,8931,8938,8939,8940,8941,12364,12366,12368,12370,12372,12374,12376,12378,12380,12382,12384,12386,12389,12391,12393,12400,12401,12403,12404,12406,12407,12409,12410,12412,12413,12436,12446,12460,12462,12464,12466,12468,12470,12472,12474,12476,12478,12480,12482,12485,12487,12489,12496,12497,12499,12500,12502,12503,12505,12506,12508,12509,12532,12535,12536,12537,12538,12542,69786,69788,69803,69934,69935,70475,70476,70843,70844,70846,71098,71099,71992]} +{"unicodeVersion":"15.0.0","normVersion":"15.0.0","goVersion":"go1.25.3","assigned":[[0,887],[890,895],[900,906],[908,908],[910,929],[931,1327],[1329,1366],[1369,1418],[1421,1423],[1425,1479],[1488,1514],[1519,1524],[1536,1805],[1807,1866],[1869,1969],[1984,2042],[2045,2093],[2096,2110],[2112,2139],[2142,2142],[2144,2154],[2160,2190],[2192,2193],[2200,2435],[2437,2444],[2447,2448],[2451,2472],[2474,2480],[2482,2482],[2486,2489],[2492,2500],[2503,2504],[2507,2510],[2519,2519],[2524,2525],[2527,2531],[2534,2558],[2561,2563],[2565,2570],[2575,2576],[2579,2600],[2602,2608],[2610,2611],[2613,2614],[2616,2617],[2620,2620],[2622,2626],[2631,2632],[2635,2637],[2641,2641],[2649,2652],[2654,2654],[2662,2678],[2689,2691],[2693,2701],[2703,2705],[2707,2728],[2730,2736],[2738,2739],[2741,2745],[2748,2757],[2759,2761],[2763,2765],[2768,2768],[2784,2787],[2790,2801],[2809,2815],[2817,2819],[2821,2828],[2831,2832],[2835,2856],[2858,2864],[2866,2867],[2869,2873],[2876,2884],[2887,2888],[2891,2893],[2901,2903],[2908,2909],[2911,2915],[2918,2935],[2946,2947],[2949,2954],[2958,2960],[2962,2965],[2969,2970],[2972,2972],[2974,2975],[2979,2980],[2984,2986],[2990,3001],[3006,3010],[3014,3016],[3018,3021],[3024,3024],[3031,3031],[3046,3066],[3072,3084],[3086,3088],[3090,3112],[3114,3129],[3132,3140],[3142,3144],[3146,3149],[3157,3158],[3160,3162],[3165,3165],[3168,3171],[3174,3183],[3191,3212],[3214,3216],[3218,3240],[3242,3251],[3253,3257],[3260,3268],[3270,3272],[3274,3277],[3285,3286],[3293,3294],[3296,3299],[3302,3311],[3313,3315],[3328,3340],[3342,3344],[3346,3396],[3398,3400],[3402,3407],[3412,3427],[3430,3455],[3457,3459],[3461,3478],[3482,3505],[3507,3515],[3517,3517],[3520,3526],[3530,3530],[3535,3540],[3542,3542],[3544,3551],[3558,3567],[3570,3572],[3585,3642],[3647,3675],[3713,3714],[3716,3716],[3718,3722],[3724,3747],[3749,3749],[3751,3773],[3776,3780],[3782,3782],[3784,3790],[3792,3801],[3804,3807],[3840,3911],[3913,3948],[3953,3991],[3993,4028],[4030,4044],[4046,4058],[4096,4293],[4295,4295],[4301,4301],[4304,4680],[4682,4685],[4688,4694],[4696,4696],[4698,4701],[4704,4744],[4746,4749],[4752,4784],[4786,4789],[4792,4798],[4800,4800],[4802,4805],[4808,4822],[4824,4880],[4882,4885],[4888,4954],[4957,4988],[4992,5017],[5024,5109],[5112,5117],[5120,5788],[5792,5880],[5888,5909],[5919,5942],[5952,5971],[5984,5996],[5998,6000],[6002,6003],[6016,6109],[6112,6121],[6128,6137],[6144,6169],[6176,6264],[6272,6314],[6320,6389],[6400,6430],[6432,6443],[6448,6459],[6464,6464],[6468,6509],[6512,6516],[6528,6571],[6576,6601],[6608,6618],[6622,6683],[6686,6750],[6752,6780],[6783,6793],[6800,6809],[6816,6829],[6832,6862],[6912,6988],[6992,7038],[7040,7155],[7164,7223],[7227,7241],[7245,7304],[7312,7354],[7357,7367],[7376,7418],[7424,7957],[7960,7965],[7968,8005],[8008,8013],[8016,8023],[8025,8025],[8027,8027],[8029,8029],[8031,8061],[8064,8116],[8118,8132],[8134,8147],[8150,8155],[8157,8175],[8178,8180],[8182,8190],[8192,8292],[8294,8305],[8308,8334],[8336,8348],[8352,8384],[8400,8432],[8448,8587],[8592,9254],[9280,9290],[9312,11123],[11126,11157],[11159,11507],[11513,11557],[11559,11559],[11565,11565],[11568,11623],[11631,11632],[11647,11670],[11680,11686],[11688,11694],[11696,11702],[11704,11710],[11712,11718],[11720,11726],[11728,11734],[11736,11742],[11744,11869],[11904,11929],[11931,12019],[12032,12245],[12272,12283],[12288,12351],[12353,12438],[12441,12543],[12549,12591],[12593,12686],[12688,12771],[12784,12830],[12832,42124],[42128,42182],[42192,42539],[42560,42743],[42752,42954],[42960,42961],[42963,42963],[42965,42969],[42994,43052],[43056,43065],[43072,43127],[43136,43205],[43214,43225],[43232,43347],[43359,43388],[43392,43469],[43471,43481],[43486,43518],[43520,43574],[43584,43597],[43600,43609],[43612,43714],[43739,43766],[43777,43782],[43785,43790],[43793,43798],[43808,43814],[43816,43822],[43824,43883],[43888,44013],[44016,44025],[44032,55203],[55216,55238],[55243,55291],[55296,64109],[64112,64217],[64256,64262],[64275,64279],[64285,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64450],[64467,64911],[64914,64967],[64975,64975],[65008,65049],[65056,65106],[65108,65126],[65128,65131],[65136,65140],[65142,65276],[65279,65279],[65281,65470],[65474,65479],[65482,65487],[65490,65495],[65498,65500],[65504,65510],[65512,65518],[65529,65533],[65536,65547],[65549,65574],[65576,65594],[65596,65597],[65599,65613],[65616,65629],[65664,65786],[65792,65794],[65799,65843],[65847,65934],[65936,65948],[65952,65952],[66000,66045],[66176,66204],[66208,66256],[66272,66299],[66304,66339],[66349,66378],[66384,66426],[66432,66461],[66463,66499],[66504,66517],[66560,66717],[66720,66729],[66736,66771],[66776,66811],[66816,66855],[66864,66915],[66927,66938],[66940,66954],[66956,66962],[66964,66965],[66967,66977],[66979,66993],[66995,67001],[67003,67004],[67072,67382],[67392,67413],[67424,67431],[67456,67461],[67463,67504],[67506,67514],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67742],[67751,67759],[67808,67826],[67828,67829],[67835,67867],[67871,67897],[67903,67903],[67968,68023],[68028,68047],[68050,68099],[68101,68102],[68108,68115],[68117,68119],[68121,68149],[68152,68154],[68159,68168],[68176,68184],[68192,68255],[68288,68326],[68331,68342],[68352,68405],[68409,68437],[68440,68466],[68472,68497],[68505,68508],[68521,68527],[68608,68680],[68736,68786],[68800,68850],[68858,68903],[68912,68921],[69216,69246],[69248,69289],[69291,69293],[69296,69297],[69373,69415],[69424,69465],[69488,69513],[69552,69579],[69600,69622],[69632,69709],[69714,69749],[69759,69826],[69837,69837],[69840,69864],[69872,69881],[69888,69940],[69942,69959],[69968,70006],[70016,70111],[70113,70132],[70144,70161],[70163,70209],[70272,70278],[70280,70280],[70282,70285],[70287,70301],[70303,70313],[70320,70378],[70384,70393],[70400,70403],[70405,70412],[70415,70416],[70419,70440],[70442,70448],[70450,70451],[70453,70457],[70459,70468],[70471,70472],[70475,70477],[70480,70480],[70487,70487],[70493,70499],[70502,70508],[70512,70516],[70656,70747],[70749,70753],[70784,70855],[70864,70873],[71040,71093],[71096,71133],[71168,71236],[71248,71257],[71264,71276],[71296,71353],[71360,71369],[71424,71450],[71453,71467],[71472,71494],[71680,71739],[71840,71922],[71935,71942],[71945,71945],[71948,71955],[71957,71958],[71960,71989],[71991,71992],[71995,72006],[72016,72025],[72096,72103],[72106,72151],[72154,72164],[72192,72263],[72272,72354],[72368,72440],[72448,72457],[72704,72712],[72714,72758],[72760,72773],[72784,72812],[72816,72847],[72850,72871],[72873,72886],[72960,72966],[72968,72969],[72971,73014],[73018,73018],[73020,73021],[73023,73031],[73040,73049],[73056,73061],[73063,73064],[73066,73102],[73104,73105],[73107,73112],[73120,73129],[73440,73464],[73472,73488],[73490,73530],[73534,73561],[73648,73648],[73664,73713],[73727,74649],[74752,74862],[74864,74868],[74880,75075],[77712,77810],[77824,78933],[82944,83526],[92160,92728],[92736,92766],[92768,92777],[92782,92862],[92864,92873],[92880,92909],[92912,92917],[92928,92997],[93008,93017],[93019,93025],[93027,93047],[93053,93071],[93760,93850],[93952,94026],[94031,94087],[94095,94111],[94176,94180],[94192,94193],[94208,100343],[100352,101589],[101632,101640],[110576,110579],[110581,110587],[110589,110590],[110592,110882],[110898,110898],[110928,110930],[110933,110933],[110948,110951],[110960,111355],[113664,113770],[113776,113788],[113792,113800],[113808,113817],[113820,113827],[118528,118573],[118576,118598],[118608,118723],[118784,119029],[119040,119078],[119081,119274],[119296,119365],[119488,119507],[119520,119539],[119552,119638],[119648,119672],[119808,119892],[119894,119964],[119966,119967],[119970,119970],[119973,119974],[119977,119980],[119982,119993],[119995,119995],[119997,120003],[120005,120069],[120071,120074],[120077,120084],[120086,120092],[120094,120121],[120123,120126],[120128,120132],[120134,120134],[120138,120144],[120146,120485],[120488,120779],[120782,121483],[121499,121503],[121505,121519],[122624,122654],[122661,122666],[122880,122886],[122888,122904],[122907,122913],[122915,122916],[122918,122922],[122928,122989],[123023,123023],[123136,123180],[123184,123197],[123200,123209],[123214,123215],[123536,123566],[123584,123641],[123647,123647],[124112,124153],[124896,124902],[124904,124907],[124909,124910],[124912,124926],[124928,125124],[125127,125142],[125184,125259],[125264,125273],[125278,125279],[126065,126132],[126209,126269],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[126704,126705],[126976,127019],[127024,127123],[127136,127150],[127153,127167],[127169,127183],[127185,127221],[127232,127405],[127462,127490],[127504,127547],[127552,127560],[127568,127569],[127584,127589],[127744,128727],[128732,128748],[128752,128764],[128768,128886],[128891,128985],[128992,129003],[129008,129008],[129024,129035],[129040,129095],[129104,129113],[129120,129159],[129168,129197],[129200,129201],[129280,129619],[129632,129645],[129648,129660],[129664,129672],[129680,129725],[129727,129733],[129742,129755],[129760,129768],[129776,129784],[129792,129938],[129940,129994],[130032,130041],[131072,173791],[173824,177977],[177984,178205],[178208,183969],[183984,191456],[194560,195101],[196608,201546],[201552,205743],[917505,917505],[917536,917631],[917760,917999],[983040,1048573],[1048576,1114109]],"format":[[173,173],[1536,1541],[1564,1564],[1757,1757],[1807,1807],[2192,2193],[2274,2274],[6158,6158],[8203,8207],[8234,8238],[8288,8292],[8294,8303],[65279,65279],[65529,65531],[69821,69821],[69837,69837],[78896,78911],[113824,113827],[119155,119162],[917505,917505],[917536,917631]],"combiningClass":[[768,230],[769,230],[770,230],[771,230],[772,230],[773,230],[774,230],[775,230],[776,230],[777,230],[778,230],[779,230],[780,230],[781,230],[782,230],[783,230],[784,230],[785,230],[786,230],[787,230],[788,230],[789,232],[790,220],[791,220],[792,220],[793,220],[794,232],[795,216],[796,220],[797,220],[798,220],[799,220],[800,220],[801,202],[802,202],[803,220],[804,220],[805,220],[806,220],[807,202],[808,202],[809,220],[810,220],[811,220],[812,220],[813,220],[814,220],[815,220],[816,220],[817,220],[818,220],[819,220],[820,1],[821,1],[822,1],[823,1],[824,1],[825,220],[826,220],[827,220],[828,220],[829,230],[830,230],[831,230],[832,230],[833,230],[834,230],[835,230],[836,230],[837,240],[838,230],[839,220],[840,220],[841,220],[842,230],[843,230],[844,230],[845,220],[846,220],[848,230],[849,230],[850,230],[851,220],[852,220],[853,220],[854,220],[855,230],[856,232],[857,220],[858,220],[859,230],[860,233],[861,234],[862,234],[863,233],[864,234],[865,234],[866,233],[867,230],[868,230],[869,230],[870,230],[871,230],[872,230],[873,230],[874,230],[875,230],[876,230],[877,230],[878,230],[879,230],[1155,230],[1156,230],[1157,230],[1158,230],[1159,230],[1425,220],[1426,230],[1427,230],[1428,230],[1429,230],[1430,220],[1431,230],[1432,230],[1433,230],[1434,222],[1435,220],[1436,230],[1437,230],[1438,230],[1439,230],[1440,230],[1441,230],[1442,220],[1443,220],[1444,220],[1445,220],[1446,220],[1447,220],[1448,230],[1449,230],[1450,220],[1451,230],[1452,230],[1453,222],[1454,228],[1455,230],[1456,10],[1457,11],[1458,12],[1459,13],[1460,14],[1461,15],[1462,16],[1463,17],[1464,18],[1465,19],[1466,19],[1467,20],[1468,21],[1469,22],[1471,23],[1473,24],[1474,25],[1476,230],[1477,220],[1479,18],[1552,230],[1553,230],[1554,230],[1555,230],[1556,230],[1557,230],[1558,230],[1559,230],[1560,30],[1561,31],[1562,32],[1611,27],[1612,28],[1613,29],[1614,30],[1615,31],[1616,32],[1617,33],[1618,34],[1619,230],[1620,230],[1621,220],[1622,220],[1623,230],[1624,230],[1625,230],[1626,230],[1627,230],[1628,220],[1629,230],[1630,230],[1631,220],[1648,35],[1750,230],[1751,230],[1752,230],[1753,230],[1754,230],[1755,230],[1756,230],[1759,230],[1760,230],[1761,230],[1762,230],[1763,220],[1764,230],[1767,230],[1768,230],[1770,220],[1771,230],[1772,230],[1773,220],[1809,36],[1840,230],[1841,220],[1842,230],[1843,230],[1844,220],[1845,230],[1846,230],[1847,220],[1848,220],[1849,220],[1850,230],[1851,220],[1852,220],[1853,230],[1854,220],[1855,230],[1856,230],[1857,230],[1858,220],[1859,230],[1860,220],[1861,230],[1862,220],[1863,230],[1864,220],[1865,230],[1866,230],[2027,230],[2028,230],[2029,230],[2030,230],[2031,230],[2032,230],[2033,230],[2034,220],[2035,230],[2045,220],[2070,230],[2071,230],[2072,230],[2073,230],[2075,230],[2076,230],[2077,230],[2078,230],[2079,230],[2080,230],[2081,230],[2082,230],[2083,230],[2085,230],[2086,230],[2087,230],[2089,230],[2090,230],[2091,230],[2092,230],[2093,230],[2137,220],[2138,220],[2139,220],[2200,230],[2201,220],[2202,220],[2203,220],[2204,230],[2205,230],[2206,230],[2207,230],[2250,230],[2251,230],[2252,230],[2253,230],[2254,230],[2255,220],[2256,220],[2257,220],[2258,220],[2259,220],[2260,230],[2261,230],[2262,230],[2263,230],[2264,230],[2265,230],[2266,230],[2267,230],[2268,230],[2269,230],[2270,230],[2271,230],[2272,230],[2273,230],[2275,220],[2276,230],[2277,230],[2278,220],[2279,230],[2280,230],[2281,220],[2282,230],[2283,230],[2284,230],[2285,220],[2286,220],[2287,220],[2288,27],[2289,28],[2290,29],[2291,230],[2292,230],[2293,230],[2294,220],[2295,230],[2296,230],[2297,220],[2298,220],[2299,230],[2300,230],[2301,230],[2302,230],[2303,230],[2364,7],[2381,9],[2385,230],[2386,220],[2387,230],[2388,230],[2492,7],[2509,9],[2558,230],[2620,7],[2637,9],[2748,7],[2765,9],[2876,7],[2893,9],[3021,9],[3132,7],[3149,9],[3157,84],[3158,91],[3260,7],[3277,9],[3387,9],[3388,9],[3405,9],[3530,9],[3640,103],[3641,103],[3642,9],[3656,107],[3657,107],[3658,107],[3659,107],[3768,118],[3769,118],[3770,9],[3784,122],[3785,122],[3786,122],[3787,122],[3864,220],[3865,220],[3893,220],[3895,220],[3897,216],[3953,129],[3954,130],[3956,132],[3962,130],[3963,130],[3964,130],[3965,130],[3968,130],[3970,230],[3971,230],[3972,9],[3974,230],[3975,230],[4038,220],[4151,7],[4153,9],[4154,9],[4237,220],[4957,230],[4958,230],[4959,230],[5908,9],[5909,9],[5940,9],[6098,9],[6109,230],[6313,228],[6457,222],[6458,230],[6459,220],[6679,230],[6680,220],[6752,9],[6773,230],[6774,230],[6775,230],[6776,230],[6777,230],[6778,230],[6779,230],[6780,230],[6783,220],[6832,230],[6833,230],[6834,230],[6835,230],[6836,230],[6837,220],[6838,220],[6839,220],[6840,220],[6841,220],[6842,220],[6843,230],[6844,230],[6845,220],[6847,220],[6848,220],[6849,230],[6850,230],[6851,220],[6852,220],[6853,230],[6854,230],[6855,230],[6856,230],[6857,230],[6858,220],[6859,230],[6860,230],[6861,230],[6862,230],[6964,7],[6980,9],[7019,230],[7020,220],[7021,230],[7022,230],[7023,230],[7024,230],[7025,230],[7026,230],[7027,230],[7082,9],[7083,9],[7142,7],[7154,9],[7155,9],[7223,7],[7376,230],[7377,230],[7378,230],[7380,1],[7381,220],[7382,220],[7383,220],[7384,220],[7385,220],[7386,230],[7387,230],[7388,220],[7389,220],[7390,220],[7391,220],[7392,230],[7394,1],[7395,1],[7396,1],[7397,1],[7398,1],[7399,1],[7400,1],[7405,220],[7412,230],[7416,230],[7417,230],[7616,230],[7617,230],[7618,220],[7619,230],[7620,230],[7621,230],[7622,230],[7623,230],[7624,230],[7625,230],[7626,220],[7627,230],[7628,230],[7629,234],[7630,214],[7631,220],[7632,202],[7633,230],[7634,230],[7635,230],[7636,230],[7637,230],[7638,230],[7639,230],[7640,230],[7641,230],[7642,230],[7643,230],[7644,230],[7645,230],[7646,230],[7647,230],[7648,230],[7649,230],[7650,230],[7651,230],[7652,230],[7653,230],[7654,230],[7655,230],[7656,230],[7657,230],[7658,230],[7659,230],[7660,230],[7661,230],[7662,230],[7663,230],[7664,230],[7665,230],[7666,230],[7667,230],[7668,230],[7669,230],[7670,232],[7671,228],[7672,228],[7673,220],[7674,218],[7675,230],[7676,233],[7677,220],[7678,230],[7679,220],[8400,230],[8401,230],[8402,1],[8403,1],[8404,230],[8405,230],[8406,230],[8407,230],[8408,1],[8409,1],[8410,1],[8411,230],[8412,230],[8417,230],[8421,1],[8422,1],[8423,230],[8424,220],[8425,230],[8426,1],[8427,1],[8428,220],[8429,220],[8430,220],[8431,220],[8432,230],[11503,230],[11504,230],[11505,230],[11647,9],[11744,230],[11745,230],[11746,230],[11747,230],[11748,230],[11749,230],[11750,230],[11751,230],[11752,230],[11753,230],[11754,230],[11755,230],[11756,230],[11757,230],[11758,230],[11759,230],[11760,230],[11761,230],[11762,230],[11763,230],[11764,230],[11765,230],[11766,230],[11767,230],[11768,230],[11769,230],[11770,230],[11771,230],[11772,230],[11773,230],[11774,230],[11775,230],[12330,218],[12331,228],[12332,232],[12333,222],[12334,224],[12335,224],[12441,8],[12442,8],[42607,230],[42612,230],[42613,230],[42614,230],[42615,230],[42616,230],[42617,230],[42618,230],[42619,230],[42620,230],[42621,230],[42654,230],[42655,230],[42736,230],[42737,230],[43014,9],[43052,9],[43204,9],[43232,230],[43233,230],[43234,230],[43235,230],[43236,230],[43237,230],[43238,230],[43239,230],[43240,230],[43241,230],[43242,230],[43243,230],[43244,230],[43245,230],[43246,230],[43247,230],[43248,230],[43249,230],[43307,220],[43308,220],[43309,220],[43347,9],[43443,7],[43456,9],[43696,230],[43698,230],[43699,230],[43700,220],[43703,230],[43704,230],[43710,230],[43711,230],[43713,230],[43766,9],[44013,9],[64286,26],[65056,230],[65057,230],[65058,230],[65059,230],[65060,230],[65061,230],[65062,230],[65063,220],[65064,220],[65065,220],[65066,220],[65067,220],[65068,220],[65069,220],[65070,230],[65071,230],[66045,220],[66272,220],[66422,230],[66423,230],[66424,230],[66425,230],[66426,230],[68109,220],[68111,230],[68152,230],[68153,1],[68154,220],[68159,9],[68325,230],[68326,220],[68900,230],[68901,230],[68902,230],[68903,230],[69291,230],[69292,230],[69373,220],[69374,220],[69375,220],[69446,220],[69447,220],[69448,230],[69449,230],[69450,230],[69451,220],[69452,230],[69453,220],[69454,220],[69455,220],[69456,220],[69506,230],[69507,220],[69508,230],[69509,220],[69702,9],[69744,9],[69759,9],[69817,9],[69818,7],[69888,230],[69889,230],[69890,230],[69939,9],[69940,9],[70003,7],[70080,9],[70090,7],[70197,9],[70198,7],[70377,7],[70378,9],[70459,7],[70460,7],[70477,9],[70502,230],[70503,230],[70504,230],[70505,230],[70506,230],[70507,230],[70508,230],[70512,230],[70513,230],[70514,230],[70515,230],[70516,230],[70722,9],[70726,7],[70750,230],[70850,9],[70851,7],[71103,9],[71104,7],[71231,9],[71350,9],[71351,7],[71467,9],[71737,9],[71738,7],[71997,9],[71998,9],[72003,7],[72160,9],[72244,9],[72263,9],[72345,9],[72767,9],[73026,7],[73028,9],[73029,9],[73111,9],[73537,9],[73538,9],[92912,1],[92913,1],[92914,1],[92915,1],[92916,1],[92976,230],[92977,230],[92978,230],[92979,230],[92980,230],[92981,230],[92982,230],[94192,6],[94193,6],[113822,1],[119141,216],[119142,216],[119143,1],[119144,1],[119145,1],[119149,226],[119150,216],[119151,216],[119152,216],[119153,216],[119154,216],[119163,220],[119164,220],[119165,220],[119166,220],[119167,220],[119168,220],[119169,220],[119170,220],[119173,230],[119174,230],[119175,230],[119176,230],[119177,230],[119178,220],[119179,220],[119210,230],[119211,230],[119212,230],[119213,230],[119362,230],[119363,230],[119364,230],[122880,230],[122881,230],[122882,230],[122883,230],[122884,230],[122885,230],[122886,230],[122888,230],[122889,230],[122890,230],[122891,230],[122892,230],[122893,230],[122894,230],[122895,230],[122896,230],[122897,230],[122898,230],[122899,230],[122900,230],[122901,230],[122902,230],[122903,230],[122904,230],[122907,230],[122908,230],[122909,230],[122910,230],[122911,230],[122912,230],[122913,230],[122915,230],[122916,230],[122918,230],[122919,230],[122920,230],[122921,230],[122922,230],[123023,230],[123184,230],[123185,230],[123186,230],[123187,230],[123188,230],[123189,230],[123190,230],[123566,230],[123628,230],[123629,230],[123630,230],[123631,230],[124140,232],[124141,232],[124142,220],[124143,230],[125136,220],[125137,220],[125138,220],[125139,220],[125140,220],[125141,220],[125142,220],[125252,230],[125253,230],[125254,230],[125255,230],[125256,230],[125257,230],[125258,7]],"decompositions":[[192,65,768],[193,65,769],[194,65,770],[195,65,771],[196,65,776],[197,65,778],[199,67,807],[200,69,768],[201,69,769],[202,69,770],[203,69,776],[204,73,768],[205,73,769],[206,73,770],[207,73,776],[209,78,771],[210,79,768],[211,79,769],[212,79,770],[213,79,771],[214,79,776],[217,85,768],[218,85,769],[219,85,770],[220,85,776],[221,89,769],[224,97,768],[225,97,769],[226,97,770],[227,97,771],[228,97,776],[229,97,778],[231,99,807],[232,101,768],[233,101,769],[234,101,770],[235,101,776],[236,105,768],[237,105,769],[238,105,770],[239,105,776],[241,110,771],[242,111,768],[243,111,769],[244,111,770],[245,111,771],[246,111,776],[249,117,768],[250,117,769],[251,117,770],[252,117,776],[253,121,769],[255,121,776],[256,65,772],[257,97,772],[258,65,774],[259,97,774],[260,65,808],[261,97,808],[262,67,769],[263,99,769],[264,67,770],[265,99,770],[266,67,775],[267,99,775],[268,67,780],[269,99,780],[270,68,780],[271,100,780],[274,69,772],[275,101,772],[276,69,774],[277,101,774],[278,69,775],[279,101,775],[280,69,808],[281,101,808],[282,69,780],[283,101,780],[284,71,770],[285,103,770],[286,71,774],[287,103,774],[288,71,775],[289,103,775],[290,71,807],[291,103,807],[292,72,770],[293,104,770],[296,73,771],[297,105,771],[298,73,772],[299,105,772],[300,73,774],[301,105,774],[302,73,808],[303,105,808],[304,73,775],[308,74,770],[309,106,770],[310,75,807],[311,107,807],[313,76,769],[314,108,769],[315,76,807],[316,108,807],[317,76,780],[318,108,780],[323,78,769],[324,110,769],[325,78,807],[326,110,807],[327,78,780],[328,110,780],[332,79,772],[333,111,772],[334,79,774],[335,111,774],[336,79,779],[337,111,779],[340,82,769],[341,114,769],[342,82,807],[343,114,807],[344,82,780],[345,114,780],[346,83,769],[347,115,769],[348,83,770],[349,115,770],[350,83,807],[351,115,807],[352,83,780],[353,115,780],[354,84,807],[355,116,807],[356,84,780],[357,116,780],[360,85,771],[361,117,771],[362,85,772],[363,117,772],[364,85,774],[365,117,774],[366,85,778],[367,117,778],[368,85,779],[369,117,779],[370,85,808],[371,117,808],[372,87,770],[373,119,770],[374,89,770],[375,121,770],[376,89,776],[377,90,769],[378,122,769],[379,90,775],[380,122,775],[381,90,780],[382,122,780],[416,79,795],[417,111,795],[431,85,795],[432,117,795],[461,65,780],[462,97,780],[463,73,780],[464,105,780],[465,79,780],[466,111,780],[467,85,780],[468,117,780],[469,220,772],[470,252,772],[471,220,769],[472,252,769],[473,220,780],[474,252,780],[475,220,768],[476,252,768],[478,196,772],[479,228,772],[480,550,772],[481,551,772],[482,198,772],[483,230,772],[486,71,780],[487,103,780],[488,75,780],[489,107,780],[490,79,808],[491,111,808],[492,490,772],[493,491,772],[494,439,780],[495,658,780],[496,106,780],[500,71,769],[501,103,769],[504,78,768],[505,110,768],[506,197,769],[507,229,769],[508,198,769],[509,230,769],[510,216,769],[511,248,769],[512,65,783],[513,97,783],[514,65,785],[515,97,785],[516,69,783],[517,101,783],[518,69,785],[519,101,785],[520,73,783],[521,105,783],[522,73,785],[523,105,785],[524,79,783],[525,111,783],[526,79,785],[527,111,785],[528,82,783],[529,114,783],[530,82,785],[531,114,785],[532,85,783],[533,117,783],[534,85,785],[535,117,785],[536,83,806],[537,115,806],[538,84,806],[539,116,806],[542,72,780],[543,104,780],[550,65,775],[551,97,775],[552,69,807],[553,101,807],[554,214,772],[555,246,772],[556,213,772],[557,245,772],[558,79,775],[559,111,775],[560,558,772],[561,559,772],[562,89,772],[563,121,772],[832,768],[833,769],[835,787],[836,776,769],[884,697],[894,59],[901,168,769],[902,913,769],[903,183],[904,917,769],[905,919,769],[906,921,769],[908,927,769],[910,933,769],[911,937,769],[912,970,769],[938,921,776],[939,933,776],[940,945,769],[941,949,769],[942,951,769],[943,953,769],[944,971,769],[970,953,776],[971,965,776],[972,959,769],[973,965,769],[974,969,769],[979,978,769],[980,978,776],[1024,1045,768],[1025,1045,776],[1027,1043,769],[1031,1030,776],[1036,1050,769],[1037,1048,768],[1038,1059,774],[1049,1048,774],[1081,1080,774],[1104,1077,768],[1105,1077,776],[1107,1075,769],[1111,1110,776],[1116,1082,769],[1117,1080,768],[1118,1091,774],[1142,1140,783],[1143,1141,783],[1217,1046,774],[1218,1078,774],[1232,1040,774],[1233,1072,774],[1234,1040,776],[1235,1072,776],[1238,1045,774],[1239,1077,774],[1242,1240,776],[1243,1241,776],[1244,1046,776],[1245,1078,776],[1246,1047,776],[1247,1079,776],[1250,1048,772],[1251,1080,772],[1252,1048,776],[1253,1080,776],[1254,1054,776],[1255,1086,776],[1258,1256,776],[1259,1257,776],[1260,1069,776],[1261,1101,776],[1262,1059,772],[1263,1091,772],[1264,1059,776],[1265,1091,776],[1266,1059,779],[1267,1091,779],[1268,1063,776],[1269,1095,776],[1272,1067,776],[1273,1099,776],[1570,1575,1619],[1571,1575,1620],[1572,1608,1620],[1573,1575,1621],[1574,1610,1620],[1728,1749,1620],[1730,1729,1620],[1747,1746,1620],[2345,2344,2364],[2353,2352,2364],[2356,2355,2364],[2392,2325,2364],[2393,2326,2364],[2394,2327,2364],[2395,2332,2364],[2396,2337,2364],[2397,2338,2364],[2398,2347,2364],[2399,2351,2364],[2507,2503,2494],[2508,2503,2519],[2524,2465,2492],[2525,2466,2492],[2527,2479,2492],[2611,2610,2620],[2614,2616,2620],[2649,2582,2620],[2650,2583,2620],[2651,2588,2620],[2654,2603,2620],[2888,2887,2902],[2891,2887,2878],[2892,2887,2903],[2908,2849,2876],[2909,2850,2876],[2964,2962,3031],[3018,3014,3006],[3019,3015,3006],[3020,3014,3031],[3144,3142,3158],[3264,3263,3285],[3271,3270,3285],[3272,3270,3286],[3274,3270,3266],[3275,3274,3285],[3402,3398,3390],[3403,3399,3390],[3404,3398,3415],[3546,3545,3530],[3548,3545,3535],[3549,3548,3530],[3550,3545,3551],[3907,3906,4023],[3917,3916,4023],[3922,3921,4023],[3927,3926,4023],[3932,3931,4023],[3945,3904,4021],[3955,3953,3954],[3957,3953,3956],[3958,4018,3968],[3960,4019,3968],[3969,3953,3968],[3987,3986,4023],[3997,3996,4023],[4002,4001,4023],[4007,4006,4023],[4012,4011,4023],[4025,3984,4021],[4134,4133,4142],[6918,6917,6965],[6920,6919,6965],[6922,6921,6965],[6924,6923,6965],[6926,6925,6965],[6930,6929,6965],[6971,6970,6965],[6973,6972,6965],[6976,6974,6965],[6977,6975,6965],[6979,6978,6965],[7680,65,805],[7681,97,805],[7682,66,775],[7683,98,775],[7684,66,803],[7685,98,803],[7686,66,817],[7687,98,817],[7688,199,769],[7689,231,769],[7690,68,775],[7691,100,775],[7692,68,803],[7693,100,803],[7694,68,817],[7695,100,817],[7696,68,807],[7697,100,807],[7698,68,813],[7699,100,813],[7700,274,768],[7701,275,768],[7702,274,769],[7703,275,769],[7704,69,813],[7705,101,813],[7706,69,816],[7707,101,816],[7708,552,774],[7709,553,774],[7710,70,775],[7711,102,775],[7712,71,772],[7713,103,772],[7714,72,775],[7715,104,775],[7716,72,803],[7717,104,803],[7718,72,776],[7719,104,776],[7720,72,807],[7721,104,807],[7722,72,814],[7723,104,814],[7724,73,816],[7725,105,816],[7726,207,769],[7727,239,769],[7728,75,769],[7729,107,769],[7730,75,803],[7731,107,803],[7732,75,817],[7733,107,817],[7734,76,803],[7735,108,803],[7736,7734,772],[7737,7735,772],[7738,76,817],[7739,108,817],[7740,76,813],[7741,108,813],[7742,77,769],[7743,109,769],[7744,77,775],[7745,109,775],[7746,77,803],[7747,109,803],[7748,78,775],[7749,110,775],[7750,78,803],[7751,110,803],[7752,78,817],[7753,110,817],[7754,78,813],[7755,110,813],[7756,213,769],[7757,245,769],[7758,213,776],[7759,245,776],[7760,332,768],[7761,333,768],[7762,332,769],[7763,333,769],[7764,80,769],[7765,112,769],[7766,80,775],[7767,112,775],[7768,82,775],[7769,114,775],[7770,82,803],[7771,114,803],[7772,7770,772],[7773,7771,772],[7774,82,817],[7775,114,817],[7776,83,775],[7777,115,775],[7778,83,803],[7779,115,803],[7780,346,775],[7781,347,775],[7782,352,775],[7783,353,775],[7784,7778,775],[7785,7779,775],[7786,84,775],[7787,116,775],[7788,84,803],[7789,116,803],[7790,84,817],[7791,116,817],[7792,84,813],[7793,116,813],[7794,85,804],[7795,117,804],[7796,85,816],[7797,117,816],[7798,85,813],[7799,117,813],[7800,360,769],[7801,361,769],[7802,362,776],[7803,363,776],[7804,86,771],[7805,118,771],[7806,86,803],[7807,118,803],[7808,87,768],[7809,119,768],[7810,87,769],[7811,119,769],[7812,87,776],[7813,119,776],[7814,87,775],[7815,119,775],[7816,87,803],[7817,119,803],[7818,88,775],[7819,120,775],[7820,88,776],[7821,120,776],[7822,89,775],[7823,121,775],[7824,90,770],[7825,122,770],[7826,90,803],[7827,122,803],[7828,90,817],[7829,122,817],[7830,104,817],[7831,116,776],[7832,119,778],[7833,121,778],[7835,383,775],[7840,65,803],[7841,97,803],[7842,65,777],[7843,97,777],[7844,194,769],[7845,226,769],[7846,194,768],[7847,226,768],[7848,194,777],[7849,226,777],[7850,194,771],[7851,226,771],[7852,7840,770],[7853,7841,770],[7854,258,769],[7855,259,769],[7856,258,768],[7857,259,768],[7858,258,777],[7859,259,777],[7860,258,771],[7861,259,771],[7862,7840,774],[7863,7841,774],[7864,69,803],[7865,101,803],[7866,69,777],[7867,101,777],[7868,69,771],[7869,101,771],[7870,202,769],[7871,234,769],[7872,202,768],[7873,234,768],[7874,202,777],[7875,234,777],[7876,202,771],[7877,234,771],[7878,7864,770],[7879,7865,770],[7880,73,777],[7881,105,777],[7882,73,803],[7883,105,803],[7884,79,803],[7885,111,803],[7886,79,777],[7887,111,777],[7888,212,769],[7889,244,769],[7890,212,768],[7891,244,768],[7892,212,777],[7893,244,777],[7894,212,771],[7895,244,771],[7896,7884,770],[7897,7885,770],[7898,416,769],[7899,417,769],[7900,416,768],[7901,417,768],[7902,416,777],[7903,417,777],[7904,416,771],[7905,417,771],[7906,416,803],[7907,417,803],[7908,85,803],[7909,117,803],[7910,85,777],[7911,117,777],[7912,431,769],[7913,432,769],[7914,431,768],[7915,432,768],[7916,431,777],[7917,432,777],[7918,431,771],[7919,432,771],[7920,431,803],[7921,432,803],[7922,89,768],[7923,121,768],[7924,89,803],[7925,121,803],[7926,89,777],[7927,121,777],[7928,89,771],[7929,121,771],[7936,945,787],[7937,945,788],[7938,7936,768],[7939,7937,768],[7940,7936,769],[7941,7937,769],[7942,7936,834],[7943,7937,834],[7944,913,787],[7945,913,788],[7946,7944,768],[7947,7945,768],[7948,7944,769],[7949,7945,769],[7950,7944,834],[7951,7945,834],[7952,949,787],[7953,949,788],[7954,7952,768],[7955,7953,768],[7956,7952,769],[7957,7953,769],[7960,917,787],[7961,917,788],[7962,7960,768],[7963,7961,768],[7964,7960,769],[7965,7961,769],[7968,951,787],[7969,951,788],[7970,7968,768],[7971,7969,768],[7972,7968,769],[7973,7969,769],[7974,7968,834],[7975,7969,834],[7976,919,787],[7977,919,788],[7978,7976,768],[7979,7977,768],[7980,7976,769],[7981,7977,769],[7982,7976,834],[7983,7977,834],[7984,953,787],[7985,953,788],[7986,7984,768],[7987,7985,768],[7988,7984,769],[7989,7985,769],[7990,7984,834],[7991,7985,834],[7992,921,787],[7993,921,788],[7994,7992,768],[7995,7993,768],[7996,7992,769],[7997,7993,769],[7998,7992,834],[7999,7993,834],[8000,959,787],[8001,959,788],[8002,8000,768],[8003,8001,768],[8004,8000,769],[8005,8001,769],[8008,927,787],[8009,927,788],[8010,8008,768],[8011,8009,768],[8012,8008,769],[8013,8009,769],[8016,965,787],[8017,965,788],[8018,8016,768],[8019,8017,768],[8020,8016,769],[8021,8017,769],[8022,8016,834],[8023,8017,834],[8025,933,788],[8027,8025,768],[8029,8025,769],[8031,8025,834],[8032,969,787],[8033,969,788],[8034,8032,768],[8035,8033,768],[8036,8032,769],[8037,8033,769],[8038,8032,834],[8039,8033,834],[8040,937,787],[8041,937,788],[8042,8040,768],[8043,8041,768],[8044,8040,769],[8045,8041,769],[8046,8040,834],[8047,8041,834],[8048,945,768],[8049,945,769],[8050,949,768],[8051,949,769],[8052,951,768],[8053,951,769],[8054,953,768],[8055,953,769],[8056,959,768],[8057,959,769],[8058,965,768],[8059,965,769],[8060,969,768],[8061,969,769],[8064,7936,837],[8065,7937,837],[8066,7938,837],[8067,7939,837],[8068,7940,837],[8069,7941,837],[8070,7942,837],[8071,7943,837],[8072,7944,837],[8073,7945,837],[8074,7946,837],[8075,7947,837],[8076,7948,837],[8077,7949,837],[8078,7950,837],[8079,7951,837],[8080,7968,837],[8081,7969,837],[8082,7970,837],[8083,7971,837],[8084,7972,837],[8085,7973,837],[8086,7974,837],[8087,7975,837],[8088,7976,837],[8089,7977,837],[8090,7978,837],[8091,7979,837],[8092,7980,837],[8093,7981,837],[8094,7982,837],[8095,7983,837],[8096,8032,837],[8097,8033,837],[8098,8034,837],[8099,8035,837],[8100,8036,837],[8101,8037,837],[8102,8038,837],[8103,8039,837],[8104,8040,837],[8105,8041,837],[8106,8042,837],[8107,8043,837],[8108,8044,837],[8109,8045,837],[8110,8046,837],[8111,8047,837],[8112,945,774],[8113,945,772],[8114,8048,837],[8115,945,837],[8116,940,837],[8118,945,834],[8119,8118,837],[8120,913,774],[8121,913,772],[8122,913,768],[8123,913,769],[8124,913,837],[8126,953],[8129,168,834],[8130,8052,837],[8131,951,837],[8132,942,837],[8134,951,834],[8135,8134,837],[8136,917,768],[8137,917,769],[8138,919,768],[8139,919,769],[8140,919,837],[8141,8127,768],[8142,8127,769],[8143,8127,834],[8144,953,774],[8145,953,772],[8146,970,768],[8147,953,776,769],[8150,953,834],[8151,970,834],[8152,921,774],[8153,921,772],[8154,921,768],[8155,921,769],[8157,8190,768],[8158,8190,769],[8159,8190,834],[8160,965,774],[8161,965,772],[8162,971,768],[8163,965,776,769],[8164,961,787],[8165,961,788],[8166,965,834],[8167,971,834],[8168,933,774],[8169,933,772],[8170,933,768],[8171,933,769],[8172,929,788],[8173,168,768],[8174,168,769],[8175,96],[8178,8060,837],[8179,969,837],[8180,974,837],[8182,969,834],[8183,8182,837],[8184,927,768],[8185,927,769],[8186,937,768],[8187,937,769],[8188,937,837],[8189,180],[8192,8194],[8193,8195],[8486,937],[8490,75],[8491,65,778],[8602,8592,824],[8603,8594,824],[8622,8596,824],[8653,8656,824],[8654,8660,824],[8655,8658,824],[8708,8707,824],[8713,8712,824],[8716,8715,824],[8740,8739,824],[8742,8741,824],[8769,8764,824],[8772,8771,824],[8775,8773,824],[8777,8776,824],[8800,61,824],[8802,8801,824],[8813,8781,824],[8814,60,824],[8815,62,824],[8816,8804,824],[8817,8805,824],[8820,8818,824],[8821,8819,824],[8824,8822,824],[8825,8823,824],[8832,8826,824],[8833,8827,824],[8836,8834,824],[8837,8835,824],[8840,8838,824],[8841,8839,824],[8876,8866,824],[8877,8872,824],[8878,8873,824],[8879,8875,824],[8928,8828,824],[8929,8829,824],[8930,8849,824],[8931,8850,824],[8938,8882,824],[8939,8883,824],[8940,8884,824],[8941,8885,824],[9001,12296],[9002,12297],[10972,10973,824],[12364,12363,12441],[12366,12365,12441],[12368,12367,12441],[12370,12369,12441],[12372,12371,12441],[12374,12373,12441],[12376,12375,12441],[12378,12377,12441],[12380,12379,12441],[12382,12381,12441],[12384,12383,12441],[12386,12385,12441],[12389,12388,12441],[12391,12390,12441],[12393,12392,12441],[12400,12399,12441],[12401,12399,12442],[12403,12402,12441],[12404,12402,12442],[12406,12405,12441],[12407,12405,12442],[12409,12408,12441],[12410,12408,12442],[12412,12411,12441],[12413,12411,12442],[12436,12358,12441],[12446,12445,12441],[12460,12459,12441],[12462,12461,12441],[12464,12463,12441],[12466,12465,12441],[12468,12467,12441],[12470,12469,12441],[12472,12471,12441],[12474,12473,12441],[12476,12475,12441],[12478,12477,12441],[12480,12479,12441],[12482,12481,12441],[12485,12484,12441],[12487,12486,12441],[12489,12488,12441],[12496,12495,12441],[12497,12495,12442],[12499,12498,12441],[12500,12498,12442],[12502,12501,12441],[12503,12501,12442],[12505,12504,12441],[12506,12504,12442],[12508,12507,12441],[12509,12507,12442],[12532,12454,12441],[12535,12527,12441],[12536,12528,12441],[12537,12529,12441],[12538,12530,12441],[12542,12541,12441],[63744,35912],[63745,26356],[63746,36554],[63747,36040],[63748,28369],[63749,20018],[63750,21477],[63751,40860],[63752,40860],[63753,22865],[63754,37329],[63755,21895],[63756,22856],[63757,25078],[63758,30313],[63759,32645],[63760,34367],[63761,34746],[63762,35064],[63763,37007],[63764,27138],[63765,27931],[63766,28889],[63767,29662],[63768,33853],[63769,37226],[63770,39409],[63771,20098],[63772,21365],[63773,27396],[63774,29211],[63775,34349],[63776,40478],[63777,23888],[63778,28651],[63779,34253],[63780,35172],[63781,25289],[63782,33240],[63783,34847],[63784,24266],[63785,26391],[63786,28010],[63787,29436],[63788,37070],[63789,20358],[63790,20919],[63791,21214],[63792,25796],[63793,27347],[63794,29200],[63795,30439],[63796,32769],[63797,34310],[63798,34396],[63799,36335],[63800,38706],[63801,39791],[63802,40442],[63803,30860],[63804,31103],[63805,32160],[63806,33737],[63807,37636],[63808,40575],[63809,35542],[63810,22751],[63811,24324],[63812,31840],[63813,32894],[63814,29282],[63815,30922],[63816,36034],[63817,38647],[63818,22744],[63819,23650],[63820,27155],[63821,28122],[63822,28431],[63823,32047],[63824,32311],[63825,38475],[63826,21202],[63827,32907],[63828,20956],[63829,20940],[63830,31260],[63831,32190],[63832,33777],[63833,38517],[63834,35712],[63835,25295],[63836,27138],[63837,35582],[63838,20025],[63839,23527],[63840,24594],[63841,29575],[63842,30064],[63843,21271],[63844,30971],[63845,20415],[63846,24489],[63847,19981],[63848,27852],[63849,25976],[63850,32034],[63851,21443],[63852,22622],[63853,30465],[63854,33865],[63855,35498],[63856,27578],[63857,36784],[63858,27784],[63859,25342],[63860,33509],[63861,25504],[63862,30053],[63863,20142],[63864,20841],[63865,20937],[63866,26753],[63867,31975],[63868,33391],[63869,35538],[63870,37327],[63871,21237],[63872,21570],[63873,22899],[63874,24300],[63875,26053],[63876,28670],[63877,31018],[63878,38317],[63879,39530],[63880,40599],[63881,40654],[63882,21147],[63883,26310],[63884,27511],[63885,36706],[63886,24180],[63887,24976],[63888,25088],[63889,25754],[63890,28451],[63891,29001],[63892,29833],[63893,31178],[63894,32244],[63895,32879],[63896,36646],[63897,34030],[63898,36899],[63899,37706],[63900,21015],[63901,21155],[63902,21693],[63903,28872],[63904,35010],[63905,35498],[63906,24265],[63907,24565],[63908,25467],[63909,27566],[63910,31806],[63911,29557],[63912,20196],[63913,22265],[63914,23527],[63915,23994],[63916,24604],[63917,29618],[63918,29801],[63919,32666],[63920,32838],[63921,37428],[63922,38646],[63923,38728],[63924,38936],[63925,20363],[63926,31150],[63927,37300],[63928,38584],[63929,24801],[63930,20102],[63931,20698],[63932,23534],[63933,23615],[63934,26009],[63935,27138],[63936,29134],[63937,30274],[63938,34044],[63939,36988],[63940,40845],[63941,26248],[63942,38446],[63943,21129],[63944,26491],[63945,26611],[63946,27969],[63947,28316],[63948,29705],[63949,30041],[63950,30827],[63951,32016],[63952,39006],[63953,20845],[63954,25134],[63955,38520],[63956,20523],[63957,23833],[63958,28138],[63959,36650],[63960,24459],[63961,24900],[63962,26647],[63963,29575],[63964,38534],[63965,21033],[63966,21519],[63967,23653],[63968,26131],[63969,26446],[63970,26792],[63971,27877],[63972,29702],[63973,30178],[63974,32633],[63975,35023],[63976,35041],[63977,37324],[63978,38626],[63979,21311],[63980,28346],[63981,21533],[63982,29136],[63983,29848],[63984,34298],[63985,38563],[63986,40023],[63987,40607],[63988,26519],[63989,28107],[63990,33256],[63991,31435],[63992,31520],[63993,31890],[63994,29376],[63995,28825],[63996,35672],[63997,20160],[63998,33590],[63999,21050],[64000,20999],[64001,24230],[64002,25299],[64003,31958],[64004,23429],[64005,27934],[64006,26292],[64007,36667],[64008,34892],[64009,38477],[64010,35211],[64011,24275],[64012,20800],[64013,21952],[64016,22618],[64018,26228],[64021,20958],[64022,29482],[64023,30410],[64024,31036],[64025,31070],[64026,31077],[64027,31119],[64028,38742],[64029,31934],[64030,32701],[64032,34322],[64034,35576],[64037,36920],[64038,37117],[64042,39151],[64043,39164],[64044,39208],[64045,40372],[64046,37086],[64047,38583],[64048,20398],[64049,20711],[64050,20813],[64051,21193],[64052,21220],[64053,21329],[64054,21917],[64055,22022],[64056,22120],[64057,22592],[64058,22696],[64059,23652],[64060,23662],[64061,24724],[64062,24936],[64063,24974],[64064,25074],[64065,25935],[64066,26082],[64067,26257],[64068,26757],[64069,28023],[64070,28186],[64071,28450],[64072,29038],[64073,29227],[64074,29730],[64075,30865],[64076,31038],[64077,31049],[64078,31048],[64079,31056],[64080,31062],[64081,31069],[64082,31117],[64083,31118],[64084,31296],[64085,31361],[64086,31680],[64087,32244],[64088,32265],[64089,32321],[64090,32626],[64091,32773],[64092,33261],[64093,33401],[64094,33401],[64095,33879],[64096,35088],[64097,35222],[64098,35585],[64099,35641],[64100,36051],[64101,36104],[64102,36790],[64103,36920],[64104,38627],[64105,38911],[64106,38971],[64107,24693],[64108,148206],[64109,33304],[64112,20006],[64113,20917],[64114,20840],[64115,20352],[64116,20805],[64117,20864],[64118,21191],[64119,21242],[64120,21917],[64121,21845],[64122,21913],[64123,21986],[64124,22618],[64125,22707],[64126,22852],[64127,22868],[64128,23138],[64129,23336],[64130,24274],[64131,24281],[64132,24425],[64133,24493],[64134,24792],[64135,24910],[64136,24840],[64137,24974],[64138,24928],[64139,25074],[64140,25140],[64141,25540],[64142,25628],[64143,25682],[64144,25942],[64145,26228],[64146,26391],[64147,26395],[64148,26454],[64149,27513],[64150,27578],[64151,27969],[64152,28379],[64153,28363],[64154,28450],[64155,28702],[64156,29038],[64157,30631],[64158,29237],[64159,29359],[64160,29482],[64161,29809],[64162,29958],[64163,30011],[64164,30237],[64165,30239],[64166,30410],[64167,30427],[64168,30452],[64169,30538],[64170,30528],[64171,30924],[64172,31409],[64173,31680],[64174,31867],[64175,32091],[64176,32244],[64177,32574],[64178,32773],[64179,33618],[64180,33775],[64181,34681],[64182,35137],[64183,35206],[64184,35222],[64185,35519],[64186,35576],[64187,35531],[64188,35585],[64189,35582],[64190,35565],[64191,35641],[64192,35722],[64193,36104],[64194,36664],[64195,36978],[64196,37273],[64197,37494],[64198,38524],[64199,38627],[64200,38742],[64201,38875],[64202,38911],[64203,38923],[64204,38971],[64205,39698],[64206,40860],[64207,141386],[64208,141380],[64209,144341],[64210,15261],[64211,16408],[64212,16441],[64213,152137],[64214,154832],[64215,163539],[64216,40771],[64217,40846],[64285,1497,1460],[64287,1522,1463],[64298,1513,1473],[64299,1513,1474],[64300,1513,1468,1473],[64301,1513,1468,1474],[64302,1488,1463],[64303,1488,1464],[64304,1488,1468],[64305,1489,1468],[64306,1490,1468],[64307,1491,1468],[64308,1492,1468],[64309,1493,1468],[64310,1494,1468],[64312,1496,1468],[64313,1497,1468],[64314,1498,1468],[64315,1499,1468],[64316,1500,1468],[64318,1502,1468],[64320,1504,1468],[64321,1505,1468],[64323,1507,1468],[64324,1508,1468],[64326,1510,1468],[64327,1511,1468],[64328,1512,1468],[64329,1513,1468],[64330,1514,1468],[64331,1493,1465],[64332,1489,1471],[64333,1499,1471],[64334,1508,1471],[69786,69785,69818],[69788,69787,69818],[69803,69797,69818],[69934,69937,69927],[69935,69938,69927],[70475,70471,70462],[70476,70471,70487],[70843,70841,70842],[70844,70841,70832],[70846,70841,70845],[71098,71096,71087],[71099,71097,71087],[71992,71989,71984],[119134,119127,119141],[119135,119128,119141],[119136,119128,119141,119150],[119137,119128,119141,119151],[119138,119128,119141,119152],[119139,119128,119141,119153],[119140,119128,119141,119154],[119227,119225,119141],[119228,119226,119141],[119229,119225,119141,119150],[119230,119226,119141,119150],[119231,119225,119141,119151],[119232,119226,119141,119151],[194560,20029],[194561,20024],[194562,20033],[194563,131362],[194564,20320],[194565,20398],[194566,20411],[194567,20482],[194568,20602],[194569,20633],[194570,20711],[194571,20687],[194572,13470],[194573,132666],[194574,20813],[194575,20820],[194576,20836],[194577,20855],[194578,132380],[194579,13497],[194580,20839],[194581,20877],[194582,132427],[194583,20887],[194584,20900],[194585,20172],[194586,20908],[194587,20917],[194588,168415],[194589,20981],[194590,20995],[194591,13535],[194592,21051],[194593,21062],[194594,21106],[194595,21111],[194596,13589],[194597,21191],[194598,21193],[194599,21220],[194600,21242],[194601,21253],[194602,21254],[194603,21271],[194604,21321],[194605,21329],[194606,21338],[194607,21363],[194608,21373],[194609,21375],[194610,21375],[194611,21375],[194612,133676],[194613,28784],[194614,21450],[194615,21471],[194616,133987],[194617,21483],[194618,21489],[194619,21510],[194620,21662],[194621,21560],[194622,21576],[194623,21608],[194624,21666],[194625,21750],[194626,21776],[194627,21843],[194628,21859],[194629,21892],[194630,21892],[194631,21913],[194632,21931],[194633,21939],[194634,21954],[194635,22294],[194636,22022],[194637,22295],[194638,22097],[194639,22132],[194640,20999],[194641,22766],[194642,22478],[194643,22516],[194644,22541],[194645,22411],[194646,22578],[194647,22577],[194648,22700],[194649,136420],[194650,22770],[194651,22775],[194652,22790],[194653,22810],[194654,22818],[194655,22882],[194656,136872],[194657,136938],[194658,23020],[194659,23067],[194660,23079],[194661,23000],[194662,23142],[194663,14062],[194664,14076],[194665,23304],[194666,23358],[194667,23358],[194668,137672],[194669,23491],[194670,23512],[194671,23527],[194672,23539],[194673,138008],[194674,23551],[194675,23558],[194676,24403],[194677,23586],[194678,14209],[194679,23648],[194680,23662],[194681,23744],[194682,23693],[194683,138724],[194684,23875],[194685,138726],[194686,23918],[194687,23915],[194688,23932],[194689,24033],[194690,24034],[194691,14383],[194692,24061],[194693,24104],[194694,24125],[194695,24169],[194696,14434],[194697,139651],[194698,14460],[194699,24240],[194700,24243],[194701,24246],[194702,24266],[194703,172946],[194704,24318],[194705,140081],[194706,140081],[194707,33281],[194708,24354],[194709,24354],[194710,14535],[194711,144056],[194712,156122],[194713,24418],[194714,24427],[194715,14563],[194716,24474],[194717,24525],[194718,24535],[194719,24569],[194720,24705],[194721,14650],[194722,14620],[194723,24724],[194724,141012],[194725,24775],[194726,24904],[194727,24908],[194728,24910],[194729,24908],[194730,24954],[194731,24974],[194732,25010],[194733,24996],[194734,25007],[194735,25054],[194736,25074],[194737,25078],[194738,25104],[194739,25115],[194740,25181],[194741,25265],[194742,25300],[194743,25424],[194744,142092],[194745,25405],[194746,25340],[194747,25448],[194748,25475],[194749,25572],[194750,142321],[194751,25634],[194752,25541],[194753,25513],[194754,14894],[194755,25705],[194756,25726],[194757,25757],[194758,25719],[194759,14956],[194760,25935],[194761,25964],[194762,143370],[194763,26083],[194764,26360],[194765,26185],[194766,15129],[194767,26257],[194768,15112],[194769,15076],[194770,20882],[194771,20885],[194772,26368],[194773,26268],[194774,32941],[194775,17369],[194776,26391],[194777,26395],[194778,26401],[194779,26462],[194780,26451],[194781,144323],[194782,15177],[194783,26618],[194784,26501],[194785,26706],[194786,26757],[194787,144493],[194788,26766],[194789,26655],[194790,26900],[194791,15261],[194792,26946],[194793,27043],[194794,27114],[194795,27304],[194796,145059],[194797,27355],[194798,15384],[194799,27425],[194800,145575],[194801,27476],[194802,15438],[194803,27506],[194804,27551],[194805,27578],[194806,27579],[194807,146061],[194808,138507],[194809,146170],[194810,27726],[194811,146620],[194812,27839],[194813,27853],[194814,27751],[194815,27926],[194816,27966],[194817,28023],[194818,27969],[194819,28009],[194820,28024],[194821,28037],[194822,146718],[194823,27956],[194824,28207],[194825,28270],[194826,15667],[194827,28363],[194828,28359],[194829,147153],[194830,28153],[194831,28526],[194832,147294],[194833,147342],[194834,28614],[194835,28729],[194836,28702],[194837,28699],[194838,15766],[194839,28746],[194840,28797],[194841,28791],[194842,28845],[194843,132389],[194844,28997],[194845,148067],[194846,29084],[194847,148395],[194848,29224],[194849,29237],[194850,29264],[194851,149000],[194852,29312],[194853,29333],[194854,149301],[194855,149524],[194856,29562],[194857,29579],[194858,16044],[194859,29605],[194860,16056],[194861,16056],[194862,29767],[194863,29788],[194864,29809],[194865,29829],[194866,29898],[194867,16155],[194868,29988],[194869,150582],[194870,30014],[194871,150674],[194872,30064],[194873,139679],[194874,30224],[194875,151457],[194876,151480],[194877,151620],[194878,16380],[194879,16392],[194880,30452],[194881,151795],[194882,151794],[194883,151833],[194884,151859],[194885,30494],[194886,30495],[194887,30495],[194888,30538],[194889,16441],[194890,30603],[194891,16454],[194892,16534],[194893,152605],[194894,30798],[194895,30860],[194896,30924],[194897,16611],[194898,153126],[194899,31062],[194900,153242],[194901,153285],[194902,31119],[194903,31211],[194904,16687],[194905,31296],[194906,31306],[194907,31311],[194908,153980],[194909,154279],[194910,154279],[194911,31470],[194912,16898],[194913,154539],[194914,31686],[194915,31689],[194916,16935],[194917,154752],[194918,31954],[194919,17056],[194920,31976],[194921,31971],[194922,32000],[194923,155526],[194924,32099],[194925,17153],[194926,32199],[194927,32258],[194928,32325],[194929,17204],[194930,156200],[194931,156231],[194932,17241],[194933,156377],[194934,32634],[194935,156478],[194936,32661],[194937,32762],[194938,32773],[194939,156890],[194940,156963],[194941,32864],[194942,157096],[194943,32880],[194944,144223],[194945,17365],[194946,32946],[194947,33027],[194948,17419],[194949,33086],[194950,23221],[194951,157607],[194952,157621],[194953,144275],[194954,144284],[194955,33281],[194956,33284],[194957,36766],[194958,17515],[194959,33425],[194960,33419],[194961,33437],[194962,21171],[194963,33457],[194964,33459],[194965,33469],[194966,33510],[194967,158524],[194968,33509],[194969,33565],[194970,33635],[194971,33709],[194972,33571],[194973,33725],[194974,33767],[194975,33879],[194976,33619],[194977,33738],[194978,33740],[194979,33756],[194980,158774],[194981,159083],[194982,158933],[194983,17707],[194984,34033],[194985,34035],[194986,34070],[194987,160714],[194988,34148],[194989,159532],[194990,17757],[194991,17761],[194992,159665],[194993,159954],[194994,17771],[194995,34384],[194996,34396],[194997,34407],[194998,34409],[194999,34473],[195000,34440],[195001,34574],[195002,34530],[195003,34681],[195004,34600],[195005,34667],[195006,34694],[195007,17879],[195008,34785],[195009,34817],[195010,17913],[195011,34912],[195012,34915],[195013,161383],[195014,35031],[195015,35038],[195016,17973],[195017,35066],[195018,13499],[195019,161966],[195020,162150],[195021,18110],[195022,18119],[195023,35488],[195024,35565],[195025,35722],[195026,35925],[195027,162984],[195028,36011],[195029,36033],[195030,36123],[195031,36215],[195032,163631],[195033,133124],[195034,36299],[195035,36284],[195036,36336],[195037,133342],[195038,36564],[195039,36664],[195040,165330],[195041,165357],[195042,37012],[195043,37105],[195044,37137],[195045,165678],[195046,37147],[195047,37432],[195048,37591],[195049,37592],[195050,37500],[195051,37881],[195052,37909],[195053,166906],[195054,38283],[195055,18837],[195056,38327],[195057,167287],[195058,18918],[195059,38595],[195060,23986],[195061,38691],[195062,168261],[195063,168474],[195064,19054],[195065,19062],[195066,38880],[195067,168970],[195068,19122],[195069,169110],[195070,38923],[195071,38923],[195072,38953],[195073,169398],[195074,39138],[195075,19251],[195076,39209],[195077,39335],[195078,39362],[195079,39422],[195080,19406],[195081,170800],[195082,39698],[195083,40000],[195084,40189],[195085,19662],[195086,19693],[195087,40295],[195088,172238],[195089,19704],[195090,172293],[195091,172558],[195092,172689],[195093,40635],[195094,19798],[195095,40697],[195096,40702],[195097,40709],[195098,40719],[195099,40726],[195100,40763],[195101,173568]],"composites":[192,193,194,195,196,197,199,200,201,202,203,204,205,206,207,209,210,211,212,213,214,217,218,219,220,221,224,225,226,227,228,229,231,232,233,234,235,236,237,238,239,241,242,243,244,245,246,249,250,251,252,253,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,296,297,298,299,300,301,302,303,304,308,309,310,311,313,314,315,316,317,318,323,324,325,326,327,328,332,333,334,335,336,337,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,416,417,431,432,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,478,479,480,481,482,483,486,487,488,489,490,491,492,493,494,495,496,500,501,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,542,543,550,551,552,553,554,555,556,557,558,559,560,561,562,563,901,902,904,905,906,908,910,911,912,938,939,940,941,942,943,944,970,971,972,973,974,979,980,1024,1025,1027,1031,1036,1037,1038,1049,1081,1104,1105,1107,1111,1116,1117,1118,1142,1143,1217,1218,1232,1233,1234,1235,1238,1239,1242,1243,1244,1245,1246,1247,1250,1251,1252,1253,1254,1255,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1272,1273,1570,1571,1572,1573,1574,1728,1730,1747,2345,2353,2356,2507,2508,2888,2891,2892,2964,3018,3019,3020,3144,3264,3271,3272,3274,3275,3402,3403,3404,3546,3548,3549,3550,4134,6918,6920,6922,6924,6926,6930,6971,6973,6976,6977,6979,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711,7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759,7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807,7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7835,7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7960,7961,7962,7963,7964,7965,7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983,7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999,8000,8001,8002,8003,8004,8005,8008,8009,8010,8011,8012,8013,8016,8017,8018,8019,8020,8021,8022,8023,8025,8027,8029,8031,8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047,8048,8050,8052,8054,8056,8058,8060,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111,8112,8113,8114,8115,8116,8118,8119,8120,8121,8122,8124,8129,8130,8131,8132,8134,8135,8136,8138,8140,8141,8142,8143,8144,8145,8146,8150,8151,8152,8153,8154,8157,8158,8159,8160,8161,8162,8164,8165,8166,8167,8168,8169,8170,8172,8173,8178,8179,8180,8182,8183,8184,8186,8188,8602,8603,8622,8653,8654,8655,8708,8713,8716,8740,8742,8769,8772,8775,8777,8800,8802,8813,8814,8815,8816,8817,8820,8821,8824,8825,8832,8833,8836,8837,8840,8841,8876,8877,8878,8879,8928,8929,8930,8931,8938,8939,8940,8941,12364,12366,12368,12370,12372,12374,12376,12378,12380,12382,12384,12386,12389,12391,12393,12400,12401,12403,12404,12406,12407,12409,12410,12412,12413,12436,12446,12460,12462,12464,12466,12468,12470,12472,12474,12476,12478,12480,12482,12485,12487,12489,12496,12497,12499,12500,12502,12503,12505,12506,12508,12509,12532,12535,12536,12537,12538,12542,69786,69788,69803,69934,69935,70475,70476,70843,70844,70846,71098,71099,71992],"streamSafe":[[168,0,1],[175,0,1],[180,0,1],[184,0,1],[192,0,1],[193,0,1],[194,0,1],[195,0,1],[196,0,1],[197,0,1],[199,0,1],[200,0,1],[201,0,1],[202,0,1],[203,0,1],[204,0,1],[205,0,1],[206,0,1],[207,0,1],[209,0,1],[210,0,1],[211,0,1],[212,0,1],[213,0,1],[214,0,1],[217,0,1],[218,0,1],[219,0,1],[220,0,1],[221,0,1],[224,0,1],[225,0,1],[226,0,1],[227,0,1],[228,0,1],[229,0,1],[231,0,1],[232,0,1],[233,0,1],[234,0,1],[235,0,1],[236,0,1],[237,0,1],[238,0,1],[239,0,1],[241,0,1],[242,0,1],[243,0,1],[244,0,1],[245,0,1],[246,0,1],[249,0,1],[250,0,1],[251,0,1],[252,0,1],[253,0,1],[255,0,1],[256,0,1],[257,0,1],[258,0,1],[259,0,1],[260,0,1],[261,0,1],[262,0,1],[263,0,1],[264,0,1],[265,0,1],[266,0,1],[267,0,1],[268,0,1],[269,0,1],[270,0,1],[271,0,1],[274,0,1],[275,0,1],[276,0,1],[277,0,1],[278,0,1],[279,0,1],[280,0,1],[281,0,1],[282,0,1],[283,0,1],[284,0,1],[285,0,1],[286,0,1],[287,0,1],[288,0,1],[289,0,1],[290,0,1],[291,0,1],[292,0,1],[293,0,1],[296,0,1],[297,0,1],[298,0,1],[299,0,1],[300,0,1],[301,0,1],[302,0,1],[303,0,1],[304,0,1],[308,0,1],[309,0,1],[310,0,1],[311,0,1],[313,0,1],[314,0,1],[315,0,1],[316,0,1],[317,0,1],[318,0,1],[323,0,1],[324,0,1],[325,0,1],[326,0,1],[327,0,1],[328,0,1],[332,0,1],[333,0,1],[334,0,1],[335,0,1],[336,0,1],[337,0,1],[340,0,1],[341,0,1],[342,0,1],[343,0,1],[344,0,1],[345,0,1],[346,0,1],[347,0,1],[348,0,1],[349,0,1],[350,0,1],[351,0,1],[352,0,1],[353,0,1],[354,0,1],[355,0,1],[356,0,1],[357,0,1],[360,0,1],[361,0,1],[362,0,1],[363,0,1],[364,0,1],[365,0,1],[366,0,1],[367,0,1],[368,0,1],[369,0,1],[370,0,1],[371,0,1],[372,0,1],[373,0,1],[374,0,1],[375,0,1],[376,0,1],[377,0,1],[378,0,1],[379,0,1],[380,0,1],[381,0,1],[382,0,1],[416,0,1],[417,0,1],[431,0,1],[432,0,1],[452,0,1],[453,0,1],[454,0,1],[461,0,1],[462,0,1],[463,0,1],[464,0,1],[465,0,1],[466,0,1],[467,0,1],[468,0,1],[469,0,2],[470,0,2],[471,0,2],[472,0,2],[473,0,2],[474,0,2],[475,0,2],[476,0,2],[478,0,2],[479,0,2],[480,0,2],[481,0,2],[482,0,1],[483,0,1],[486,0,1],[487,0,1],[488,0,1],[489,0,1],[490,0,1],[491,0,1],[492,0,2],[493,0,2],[494,0,1],[495,0,1],[496,0,1],[500,0,1],[501,0,1],[504,0,1],[505,0,1],[506,0,2],[507,0,2],[508,0,1],[509,0,1],[510,0,1],[511,0,1],[512,0,1],[513,0,1],[514,0,1],[515,0,1],[516,0,1],[517,0,1],[518,0,1],[519,0,1],[520,0,1],[521,0,1],[522,0,1],[523,0,1],[524,0,1],[525,0,1],[526,0,1],[527,0,1],[528,0,1],[529,0,1],[530,0,1],[531,0,1],[532,0,1],[533,0,1],[534,0,1],[535,0,1],[536,0,1],[537,0,1],[538,0,1],[539,0,1],[542,0,1],[543,0,1],[550,0,1],[551,0,1],[552,0,1],[553,0,1],[554,0,2],[555,0,2],[556,0,2],[557,0,2],[558,0,1],[559,0,1],[560,0,2],[561,0,2],[562,0,1],[563,0,1],[728,0,1],[729,0,1],[730,0,1],[731,0,1],[732,0,1],[733,0,1],[768,1,1],[769,1,1],[770,1,1],[771,1,1],[772,1,1],[773,1,1],[774,1,1],[775,1,1],[776,1,1],[777,1,1],[778,1,1],[779,1,1],[780,1,1],[781,1,1],[782,1,1],[783,1,1],[784,1,1],[785,1,1],[786,1,1],[787,1,1],[788,1,1],[789,1,1],[790,1,1],[791,1,1],[792,1,1],[793,1,1],[794,1,1],[795,1,1],[796,1,1],[797,1,1],[798,1,1],[799,1,1],[800,1,1],[801,1,1],[802,1,1],[803,1,1],[804,1,1],[805,1,1],[806,1,1],[807,1,1],[808,1,1],[809,1,1],[810,1,1],[811,1,1],[812,1,1],[813,1,1],[814,1,1],[815,1,1],[816,1,1],[817,1,1],[818,1,1],[819,1,1],[820,1,1],[821,1,1],[822,1,1],[823,1,1],[824,1,1],[825,1,1],[826,1,1],[827,1,1],[828,1,1],[829,1,1],[830,1,1],[831,1,1],[832,1,1],[833,1,1],[834,1,1],[835,1,1],[836,2,2],[837,1,1],[838,1,1],[839,1,1],[840,1,1],[841,1,1],[842,1,1],[843,1,1],[844,1,1],[845,1,1],[846,1,1],[848,1,1],[849,1,1],[850,1,1],[851,1,1],[852,1,1],[853,1,1],[854,1,1],[855,1,1],[856,1,1],[857,1,1],[858,1,1],[859,1,1],[860,1,1],[861,1,1],[862,1,1],[863,1,1],[864,1,1],[865,1,1],[866,1,1],[867,1,1],[868,1,1],[869,1,1],[870,1,1],[871,1,1],[872,1,1],[873,1,1],[874,1,1],[875,1,1],[876,1,1],[877,1,1],[878,1,1],[879,1,1],[890,0,1],[900,0,1],[901,0,2],[902,0,1],[904,0,1],[905,0,1],[906,0,1],[908,0,1],[910,0,1],[911,0,1],[912,0,2],[938,0,1],[939,0,1],[940,0,1],[941,0,1],[942,0,1],[943,0,1],[944,0,2],[970,0,1],[971,0,1],[972,0,1],[973,0,1],[974,0,1],[979,0,1],[980,0,1],[1024,0,1],[1025,0,1],[1027,0,1],[1031,0,1],[1036,0,1],[1037,0,1],[1038,0,1],[1049,0,1],[1081,0,1],[1104,0,1],[1105,0,1],[1107,0,1],[1111,0,1],[1116,0,1],[1117,0,1],[1118,0,1],[1142,0,1],[1143,0,1],[1155,1,1],[1156,1,1],[1157,1,1],[1158,1,1],[1159,1,1],[1217,0,1],[1218,0,1],[1232,0,1],[1233,0,1],[1234,0,1],[1235,0,1],[1238,0,1],[1239,0,1],[1242,0,1],[1243,0,1],[1244,0,1],[1245,0,1],[1246,0,1],[1247,0,1],[1250,0,1],[1251,0,1],[1252,0,1],[1253,0,1],[1254,0,1],[1255,0,1],[1258,0,1],[1259,0,1],[1260,0,1],[1261,0,1],[1262,0,1],[1263,0,1],[1264,0,1],[1265,0,1],[1266,0,1],[1267,0,1],[1268,0,1],[1269,0,1],[1272,0,1],[1273,0,1],[1425,1,1],[1426,1,1],[1427,1,1],[1428,1,1],[1429,1,1],[1430,1,1],[1431,1,1],[1432,1,1],[1433,1,1],[1434,1,1],[1435,1,1],[1436,1,1],[1437,1,1],[1438,1,1],[1439,1,1],[1440,1,1],[1441,1,1],[1442,1,1],[1443,1,1],[1444,1,1],[1445,1,1],[1446,1,1],[1447,1,1],[1448,1,1],[1449,1,1],[1450,1,1],[1451,1,1],[1452,1,1],[1453,1,1],[1454,1,1],[1455,1,1],[1456,1,1],[1457,1,1],[1458,1,1],[1459,1,1],[1460,1,1],[1461,1,1],[1462,1,1],[1463,1,1],[1464,1,1],[1465,1,1],[1466,1,1],[1467,1,1],[1468,1,1],[1469,1,1],[1471,1,1],[1473,1,1],[1474,1,1],[1476,1,1],[1477,1,1],[1479,1,1],[1552,1,1],[1553,1,1],[1554,1,1],[1555,1,1],[1556,1,1],[1557,1,1],[1558,1,1],[1559,1,1],[1560,1,1],[1561,1,1],[1562,1,1],[1570,0,1],[1571,0,1],[1572,0,1],[1573,0,1],[1574,0,1],[1611,1,1],[1612,1,1],[1613,1,1],[1614,1,1],[1615,1,1],[1616,1,1],[1617,1,1],[1618,1,1],[1619,1,1],[1620,1,1],[1621,1,1],[1622,1,1],[1623,1,1],[1624,1,1],[1625,1,1],[1626,1,1],[1627,1,1],[1628,1,1],[1629,1,1],[1630,1,1],[1631,1,1],[1648,1,1],[1728,0,1],[1730,0,1],[1747,0,1],[1750,1,1],[1751,1,1],[1752,1,1],[1753,1,1],[1754,1,1],[1755,1,1],[1756,1,1],[1759,1,1],[1760,1,1],[1761,1,1],[1762,1,1],[1763,1,1],[1764,1,1],[1767,1,1],[1768,1,1],[1770,1,1],[1771,1,1],[1772,1,1],[1773,1,1],[1809,1,1],[1840,1,1],[1841,1,1],[1842,1,1],[1843,1,1],[1844,1,1],[1845,1,1],[1846,1,1],[1847,1,1],[1848,1,1],[1849,1,1],[1850,1,1],[1851,1,1],[1852,1,1],[1853,1,1],[1854,1,1],[1855,1,1],[1856,1,1],[1857,1,1],[1858,1,1],[1859,1,1],[1860,1,1],[1861,1,1],[1862,1,1],[1863,1,1],[1864,1,1],[1865,1,1],[1866,1,1],[2027,1,1],[2028,1,1],[2029,1,1],[2030,1,1],[2031,1,1],[2032,1,1],[2033,1,1],[2034,1,1],[2035,1,1],[2045,1,1],[2070,1,1],[2071,1,1],[2072,1,1],[2073,1,1],[2075,1,1],[2076,1,1],[2077,1,1],[2078,1,1],[2079,1,1],[2080,1,1],[2081,1,1],[2082,1,1],[2083,1,1],[2085,1,1],[2086,1,1],[2087,1,1],[2089,1,1],[2090,1,1],[2091,1,1],[2092,1,1],[2093,1,1],[2137,1,1],[2138,1,1],[2139,1,1],[2200,1,1],[2201,1,1],[2202,1,1],[2203,1,1],[2204,1,1],[2205,1,1],[2206,1,1],[2207,1,1],[2250,1,1],[2251,1,1],[2252,1,1],[2253,1,1],[2254,1,1],[2255,1,1],[2256,1,1],[2257,1,1],[2258,1,1],[2259,1,1],[2260,1,1],[2261,1,1],[2262,1,1],[2263,1,1],[2264,1,1],[2265,1,1],[2266,1,1],[2267,1,1],[2268,1,1],[2269,1,1],[2270,1,1],[2271,1,1],[2272,1,1],[2273,1,1],[2275,1,1],[2276,1,1],[2277,1,1],[2278,1,1],[2279,1,1],[2280,1,1],[2281,1,1],[2282,1,1],[2283,1,1],[2284,1,1],[2285,1,1],[2286,1,1],[2287,1,1],[2288,1,1],[2289,1,1],[2290,1,1],[2291,1,1],[2292,1,1],[2293,1,1],[2294,1,1],[2295,1,1],[2296,1,1],[2297,1,1],[2298,1,1],[2299,1,1],[2300,1,1],[2301,1,1],[2302,1,1],[2303,1,1],[2345,0,1],[2353,0,1],[2356,0,1],[2364,1,1],[2381,1,1],[2385,1,1],[2386,1,1],[2387,1,1],[2388,1,1],[2392,0,1],[2393,0,1],[2394,0,1],[2395,0,1],[2396,0,1],[2397,0,1],[2398,0,1],[2399,0,1],[2492,1,1],[2494,1,1],[2507,0,1],[2508,0,1],[2509,1,1],[2519,1,1],[2524,0,1],[2525,0,1],[2527,0,1],[2558,1,1],[2611,0,1],[2614,0,1],[2620,1,1],[2637,1,1],[2649,0,1],[2650,0,1],[2651,0,1],[2654,0,1],[2748,1,1],[2765,1,1],[2876,1,1],[2878,1,1],[2888,0,1],[2891,0,1],[2892,0,1],[2893,1,1],[2902,1,1],[2903,1,1],[2908,0,1],[2909,0,1],[2964,0,1],[3006,1,1],[3018,0,1],[3019,0,1],[3020,0,1],[3021,1,1],[3031,1,1],[3132,1,1],[3144,0,1],[3149,1,1],[3157,1,1],[3158,1,1],[3260,1,1],[3264,0,1],[3266,1,1],[3271,0,1],[3272,0,1],[3274,0,1],[3275,0,2],[3277,1,1],[3285,1,1],[3286,1,1],[3387,1,1],[3388,1,1],[3390,1,1],[3402,0,1],[3403,0,1],[3404,0,1],[3405,1,1],[3415,1,1],[3530,1,1],[3535,1,1],[3546,0,1],[3548,0,1],[3549,0,2],[3550,0,1],[3551,1,1],[3640,1,1],[3641,1,1],[3642,1,1],[3656,1,1],[3657,1,1],[3658,1,1],[3659,1,1],[3768,1,1],[3769,1,1],[3770,1,1],[3784,1,1],[3785,1,1],[3786,1,1],[3787,1,1],[3864,1,1],[3865,1,1],[3893,1,1],[3895,1,1],[3897,1,1],[3953,1,1],[3954,1,1],[3955,2,2],[3956,1,1],[3957,2,2],[3958,0,1],[3959,0,2],[3960,0,1],[3961,0,2],[3962,1,1],[3963,1,1],[3964,1,1],[3965,1,1],[3968,1,1],[3969,2,2],[3970,1,1],[3971,1,1],[3972,1,1],[3974,1,1],[3975,1,1],[4038,1,1],[4134,0,1],[4142,1,1],[4151,1,1],[4153,1,1],[4154,1,1],[4237,1,1],[4449,1,1],[4450,1,1],[4451,1,1],[4452,1,1],[4453,1,1],[4454,1,1],[4455,1,1],[4456,1,1],[4457,1,1],[4458,1,1],[4459,1,1],[4460,1,1],[4461,1,1],[4462,1,1],[4463,1,1],[4464,1,1],[4465,1,1],[4466,1,1],[4467,1,1],[4468,1,1],[4469,1,1],[4520,1,1],[4521,1,1],[4522,1,1],[4523,1,1],[4524,1,1],[4525,1,1],[4526,1,1],[4527,1,1],[4528,1,1],[4529,1,1],[4530,1,1],[4531,1,1],[4532,1,1],[4533,1,1],[4534,1,1],[4535,1,1],[4536,1,1],[4537,1,1],[4538,1,1],[4539,1,1],[4540,1,1],[4541,1,1],[4542,1,1],[4543,1,1],[4544,1,1],[4545,1,1],[4546,1,1],[4957,1,1],[4958,1,1],[4959,1,1],[5908,1,1],[5909,1,1],[5940,1,1],[6098,1,1],[6109,1,1],[6313,1,1],[6457,1,1],[6458,1,1],[6459,1,1],[6679,1,1],[6680,1,1],[6752,1,1],[6773,1,1],[6774,1,1],[6775,1,1],[6776,1,1],[6777,1,1],[6778,1,1],[6779,1,1],[6780,1,1],[6783,1,1],[6832,1,1],[6833,1,1],[6834,1,1],[6835,1,1],[6836,1,1],[6837,1,1],[6838,1,1],[6839,1,1],[6840,1,1],[6841,1,1],[6842,1,1],[6843,1,1],[6844,1,1],[6845,1,1],[6847,1,1],[6848,1,1],[6849,1,1],[6850,1,1],[6851,1,1],[6852,1,1],[6853,1,1],[6854,1,1],[6855,1,1],[6856,1,1],[6857,1,1],[6858,1,1],[6859,1,1],[6860,1,1],[6861,1,1],[6862,1,1],[6918,0,1],[6920,0,1],[6922,0,1],[6924,0,1],[6926,0,1],[6930,0,1],[6964,1,1],[6965,1,1],[6971,0,1],[6973,0,1],[6976,0,1],[6977,0,1],[6979,0,1],[6980,1,1],[7019,1,1],[7020,1,1],[7021,1,1],[7022,1,1],[7023,1,1],[7024,1,1],[7025,1,1],[7026,1,1],[7027,1,1],[7082,1,1],[7083,1,1],[7142,1,1],[7154,1,1],[7155,1,1],[7223,1,1],[7376,1,1],[7377,1,1],[7378,1,1],[7380,1,1],[7381,1,1],[7382,1,1],[7383,1,1],[7384,1,1],[7385,1,1],[7386,1,1],[7387,1,1],[7388,1,1],[7389,1,1],[7390,1,1],[7391,1,1],[7392,1,1],[7394,1,1],[7395,1,1],[7396,1,1],[7397,1,1],[7398,1,1],[7399,1,1],[7400,1,1],[7405,1,1],[7412,1,1],[7416,1,1],[7417,1,1],[7616,1,1],[7617,1,1],[7618,1,1],[7619,1,1],[7620,1,1],[7621,1,1],[7622,1,1],[7623,1,1],[7624,1,1],[7625,1,1],[7626,1,1],[7627,1,1],[7628,1,1],[7629,1,1],[7630,1,1],[7631,1,1],[7632,1,1],[7633,1,1],[7634,1,1],[7635,1,1],[7636,1,1],[7637,1,1],[7638,1,1],[7639,1,1],[7640,1,1],[7641,1,1],[7642,1,1],[7643,1,1],[7644,1,1],[7645,1,1],[7646,1,1],[7647,1,1],[7648,1,1],[7649,1,1],[7650,1,1],[7651,1,1],[7652,1,1],[7653,1,1],[7654,1,1],[7655,1,1],[7656,1,1],[7657,1,1],[7658,1,1],[7659,1,1],[7660,1,1],[7661,1,1],[7662,1,1],[7663,1,1],[7664,1,1],[7665,1,1],[7666,1,1],[7667,1,1],[7668,1,1],[7669,1,1],[7670,1,1],[7671,1,1],[7672,1,1],[7673,1,1],[7674,1,1],[7675,1,1],[7676,1,1],[7677,1,1],[7678,1,1],[7679,1,1],[7680,0,1],[7681,0,1],[7682,0,1],[7683,0,1],[7684,0,1],[7685,0,1],[7686,0,1],[7687,0,1],[7688,0,2],[7689,0,2],[7690,0,1],[7691,0,1],[7692,0,1],[7693,0,1],[7694,0,1],[7695,0,1],[7696,0,1],[7697,0,1],[7698,0,1],[7699,0,1],[7700,0,2],[7701,0,2],[7702,0,2],[7703,0,2],[7704,0,1],[7705,0,1],[7706,0,1],[7707,0,1],[7708,0,2],[7709,0,2],[7710,0,1],[7711,0,1],[7712,0,1],[7713,0,1],[7714,0,1],[7715,0,1],[7716,0,1],[7717,0,1],[7718,0,1],[7719,0,1],[7720,0,1],[7721,0,1],[7722,0,1],[7723,0,1],[7724,0,1],[7725,0,1],[7726,0,2],[7727,0,2],[7728,0,1],[7729,0,1],[7730,0,1],[7731,0,1],[7732,0,1],[7733,0,1],[7734,0,1],[7735,0,1],[7736,0,2],[7737,0,2],[7738,0,1],[7739,0,1],[7740,0,1],[7741,0,1],[7742,0,1],[7743,0,1],[7744,0,1],[7745,0,1],[7746,0,1],[7747,0,1],[7748,0,1],[7749,0,1],[7750,0,1],[7751,0,1],[7752,0,1],[7753,0,1],[7754,0,1],[7755,0,1],[7756,0,2],[7757,0,2],[7758,0,2],[7759,0,2],[7760,0,2],[7761,0,2],[7762,0,2],[7763,0,2],[7764,0,1],[7765,0,1],[7766,0,1],[7767,0,1],[7768,0,1],[7769,0,1],[7770,0,1],[7771,0,1],[7772,0,2],[7773,0,2],[7774,0,1],[7775,0,1],[7776,0,1],[7777,0,1],[7778,0,1],[7779,0,1],[7780,0,2],[7781,0,2],[7782,0,2],[7783,0,2],[7784,0,2],[7785,0,2],[7786,0,1],[7787,0,1],[7788,0,1],[7789,0,1],[7790,0,1],[7791,0,1],[7792,0,1],[7793,0,1],[7794,0,1],[7795,0,1],[7796,0,1],[7797,0,1],[7798,0,1],[7799,0,1],[7800,0,2],[7801,0,2],[7802,0,2],[7803,0,2],[7804,0,1],[7805,0,1],[7806,0,1],[7807,0,1],[7808,0,1],[7809,0,1],[7810,0,1],[7811,0,1],[7812,0,1],[7813,0,1],[7814,0,1],[7815,0,1],[7816,0,1],[7817,0,1],[7818,0,1],[7819,0,1],[7820,0,1],[7821,0,1],[7822,0,1],[7823,0,1],[7824,0,1],[7825,0,1],[7826,0,1],[7827,0,1],[7828,0,1],[7829,0,1],[7830,0,1],[7831,0,1],[7832,0,1],[7833,0,1],[7835,0,1],[7840,0,1],[7841,0,1],[7842,0,1],[7843,0,1],[7844,0,2],[7845,0,2],[7846,0,2],[7847,0,2],[7848,0,2],[7849,0,2],[7850,0,2],[7851,0,2],[7852,0,2],[7853,0,2],[7854,0,2],[7855,0,2],[7856,0,2],[7857,0,2],[7858,0,2],[7859,0,2],[7860,0,2],[7861,0,2],[7862,0,2],[7863,0,2],[7864,0,1],[7865,0,1],[7866,0,1],[7867,0,1],[7868,0,1],[7869,0,1],[7870,0,2],[7871,0,2],[7872,0,2],[7873,0,2],[7874,0,2],[7875,0,2],[7876,0,2],[7877,0,2],[7878,0,2],[7879,0,2],[7880,0,1],[7881,0,1],[7882,0,1],[7883,0,1],[7884,0,1],[7885,0,1],[7886,0,1],[7887,0,1],[7888,0,2],[7889,0,2],[7890,0,2],[7891,0,2],[7892,0,2],[7893,0,2],[7894,0,2],[7895,0,2],[7896,0,2],[7897,0,2],[7898,0,2],[7899,0,2],[7900,0,2],[7901,0,2],[7902,0,2],[7903,0,2],[7904,0,2],[7905,0,2],[7906,0,2],[7907,0,2],[7908,0,1],[7909,0,1],[7910,0,1],[7911,0,1],[7912,0,2],[7913,0,2],[7914,0,2],[7915,0,2],[7916,0,2],[7917,0,2],[7918,0,2],[7919,0,2],[7920,0,2],[7921,0,2],[7922,0,1],[7923,0,1],[7924,0,1],[7925,0,1],[7926,0,1],[7927,0,1],[7928,0,1],[7929,0,1],[7936,0,1],[7937,0,1],[7938,0,2],[7939,0,2],[7940,0,2],[7941,0,2],[7942,0,2],[7943,0,2],[7944,0,1],[7945,0,1],[7946,0,2],[7947,0,2],[7948,0,2],[7949,0,2],[7950,0,2],[7951,0,2],[7952,0,1],[7953,0,1],[7954,0,2],[7955,0,2],[7956,0,2],[7957,0,2],[7960,0,1],[7961,0,1],[7962,0,2],[7963,0,2],[7964,0,2],[7965,0,2],[7968,0,1],[7969,0,1],[7970,0,2],[7971,0,2],[7972,0,2],[7973,0,2],[7974,0,2],[7975,0,2],[7976,0,1],[7977,0,1],[7978,0,2],[7979,0,2],[7980,0,2],[7981,0,2],[7982,0,2],[7983,0,2],[7984,0,1],[7985,0,1],[7986,0,2],[7987,0,2],[7988,0,2],[7989,0,2],[7990,0,2],[7991,0,2],[7992,0,1],[7993,0,1],[7994,0,2],[7995,0,2],[7996,0,2],[7997,0,2],[7998,0,2],[7999,0,2],[8000,0,1],[8001,0,1],[8002,0,2],[8003,0,2],[8004,0,2],[8005,0,2],[8008,0,1],[8009,0,1],[8010,0,2],[8011,0,2],[8012,0,2],[8013,0,2],[8016,0,1],[8017,0,1],[8018,0,2],[8019,0,2],[8020,0,2],[8021,0,2],[8022,0,2],[8023,0,2],[8025,0,1],[8027,0,2],[8029,0,2],[8031,0,2],[8032,0,1],[8033,0,1],[8034,0,2],[8035,0,2],[8036,0,2],[8037,0,2],[8038,0,2],[8039,0,2],[8040,0,1],[8041,0,1],[8042,0,2],[8043,0,2],[8044,0,2],[8045,0,2],[8046,0,2],[8047,0,2],[8048,0,1],[8049,0,1],[8050,0,1],[8051,0,1],[8052,0,1],[8053,0,1],[8054,0,1],[8055,0,1],[8056,0,1],[8057,0,1],[8058,0,1],[8059,0,1],[8060,0,1],[8061,0,1],[8064,0,2],[8065,0,2],[8066,0,3],[8067,0,3],[8068,0,3],[8069,0,3],[8070,0,3],[8071,0,3],[8072,0,2],[8073,0,2],[8074,0,3],[8075,0,3],[8076,0,3],[8077,0,3],[8078,0,3],[8079,0,3],[8080,0,2],[8081,0,2],[8082,0,3],[8083,0,3],[8084,0,3],[8085,0,3],[8086,0,3],[8087,0,3],[8088,0,2],[8089,0,2],[8090,0,3],[8091,0,3],[8092,0,3],[8093,0,3],[8094,0,3],[8095,0,3],[8096,0,2],[8097,0,2],[8098,0,3],[8099,0,3],[8100,0,3],[8101,0,3],[8102,0,3],[8103,0,3],[8104,0,2],[8105,0,2],[8106,0,3],[8107,0,3],[8108,0,3],[8109,0,3],[8110,0,3],[8111,0,3],[8112,0,1],[8113,0,1],[8114,0,2],[8115,0,1],[8116,0,2],[8118,0,1],[8119,0,2],[8120,0,1],[8121,0,1],[8122,0,1],[8123,0,1],[8124,0,1],[8125,0,1],[8127,0,1],[8128,0,1],[8129,0,2],[8130,0,2],[8131,0,1],[8132,0,2],[8134,0,1],[8135,0,2],[8136,0,1],[8137,0,1],[8138,0,1],[8139,0,1],[8140,0,1],[8141,0,2],[8142,0,2],[8143,0,2],[8144,0,1],[8145,0,1],[8146,0,2],[8147,0,2],[8150,0,1],[8151,0,2],[8152,0,1],[8153,0,1],[8154,0,1],[8155,0,1],[8157,0,2],[8158,0,2],[8159,0,2],[8160,0,1],[8161,0,1],[8162,0,2],[8163,0,2],[8164,0,1],[8165,0,1],[8166,0,1],[8167,0,2],[8168,0,1],[8169,0,1],[8170,0,1],[8171,0,1],[8172,0,1],[8173,0,2],[8174,0,2],[8178,0,2],[8179,0,1],[8180,0,2],[8182,0,1],[8183,0,2],[8184,0,1],[8185,0,1],[8186,0,1],[8187,0,1],[8188,0,1],[8189,0,1],[8190,0,1],[8215,0,1],[8254,0,1],[8400,1,1],[8401,1,1],[8402,1,1],[8403,1,1],[8404,1,1],[8405,1,1],[8406,1,1],[8407,1,1],[8408,1,1],[8409,1,1],[8410,1,1],[8411,1,1],[8412,1,1],[8417,1,1],[8421,1,1],[8422,1,1],[8423,1,1],[8424,1,1],[8425,1,1],[8426,1,1],[8427,1,1],[8428,1,1],[8429,1,1],[8430,1,1],[8431,1,1],[8432,1,1],[8491,0,1],[8602,0,1],[8603,0,1],[8622,0,1],[8653,0,1],[8654,0,1],[8655,0,1],[8708,0,1],[8713,0,1],[8716,0,1],[8740,0,1],[8742,0,1],[8769,0,1],[8772,0,1],[8775,0,1],[8777,0,1],[8800,0,1],[8802,0,1],[8813,0,1],[8814,0,1],[8815,0,1],[8816,0,1],[8817,0,1],[8820,0,1],[8821,0,1],[8824,0,1],[8825,0,1],[8832,0,1],[8833,0,1],[8836,0,1],[8837,0,1],[8840,0,1],[8841,0,1],[8876,0,1],[8877,0,1],[8878,0,1],[8879,0,1],[8928,0,1],[8929,0,1],[8930,0,1],[8931,0,1],[8938,0,1],[8939,0,1],[8940,0,1],[8941,0,1],[10972,0,1],[11503,1,1],[11504,1,1],[11505,1,1],[11647,1,1],[11744,1,1],[11745,1,1],[11746,1,1],[11747,1,1],[11748,1,1],[11749,1,1],[11750,1,1],[11751,1,1],[11752,1,1],[11753,1,1],[11754,1,1],[11755,1,1],[11756,1,1],[11757,1,1],[11758,1,1],[11759,1,1],[11760,1,1],[11761,1,1],[11762,1,1],[11763,1,1],[11764,1,1],[11765,1,1],[11766,1,1],[11767,1,1],[11768,1,1],[11769,1,1],[11770,1,1],[11771,1,1],[11772,1,1],[11773,1,1],[11774,1,1],[11775,1,1],[12330,1,1],[12331,1,1],[12332,1,1],[12333,1,1],[12334,1,1],[12335,1,1],[12364,0,1],[12366,0,1],[12368,0,1],[12370,0,1],[12372,0,1],[12374,0,1],[12376,0,1],[12378,0,1],[12380,0,1],[12382,0,1],[12384,0,1],[12386,0,1],[12389,0,1],[12391,0,1],[12393,0,1],[12400,0,1],[12401,0,1],[12403,0,1],[12404,0,1],[12406,0,1],[12407,0,1],[12409,0,1],[12410,0,1],[12412,0,1],[12413,0,1],[12436,0,1],[12441,1,1],[12442,1,1],[12443,0,1],[12444,0,1],[12446,0,1],[12460,0,1],[12462,0,1],[12464,0,1],[12466,0,1],[12468,0,1],[12470,0,1],[12472,0,1],[12474,0,1],[12476,0,1],[12478,0,1],[12480,0,1],[12482,0,1],[12485,0,1],[12487,0,1],[12489,0,1],[12496,0,1],[12497,0,1],[12499,0,1],[12500,0,1],[12502,0,1],[12503,0,1],[12505,0,1],[12506,0,1],[12508,0,1],[12509,0,1],[12532,0,1],[12535,0,1],[12536,0,1],[12537,0,1],[12538,0,1],[12542,0,1],[12595,1,1],[12597,1,1],[12598,1,1],[12602,1,1],[12603,1,1],[12604,1,1],[12605,1,1],[12606,1,1],[12607,1,1],[12623,1,1],[12624,1,1],[12625,1,1],[12626,1,1],[12627,1,1],[12628,1,1],[12629,1,1],[12630,1,1],[12631,1,1],[12632,1,1],[12633,1,1],[12634,1,1],[12635,1,1],[12636,1,1],[12637,1,1],[12638,1,1],[12639,1,1],[12640,1,1],[12641,1,1],[12642,1,1],[12643,1,1],[12910,0,1],[12911,0,1],[12912,0,1],[12913,0,1],[12914,0,1],[12915,0,1],[12916,0,1],[12917,0,1],[12918,0,1],[12919,0,1],[12920,0,1],[12921,0,1],[12922,0,1],[12923,0,1],[12924,0,1],[12925,0,1],[12926,0,1],[13060,0,1],[13063,0,1],[13072,0,1],[13086,0,1],[13089,0,1],[13106,0,1],[13115,0,1],[13120,0,1],[13131,0,1],[13134,0,1],[42607,1,1],[42612,1,1],[42613,1,1],[42614,1,1],[42615,1,1],[42616,1,1],[42617,1,1],[42618,1,1],[42619,1,1],[42620,1,1],[42621,1,1],[42654,1,1],[42655,1,1],[42736,1,1],[42737,1,1],[43014,1,1],[43052,1,1],[43204,1,1],[43232,1,1],[43233,1,1],[43234,1,1],[43235,1,1],[43236,1,1],[43237,1,1],[43238,1,1],[43239,1,1],[43240,1,1],[43241,1,1],[43242,1,1],[43243,1,1],[43244,1,1],[43245,1,1],[43246,1,1],[43247,1,1],[43248,1,1],[43249,1,1],[43307,1,1],[43308,1,1],[43309,1,1],[43347,1,1],[43443,1,1],[43456,1,1],[43696,1,1],[43698,1,1],[43699,1,1],[43700,1,1],[43703,1,1],[43704,1,1],[43710,1,1],[43711,1,1],[43713,1,1],[43766,1,1],[44013,1,1],[44032,0,1],[44033,0,2],[44034,0,2],[44035,0,2],[44036,0,2],[44037,0,2],[44038,0,2],[44039,0,2],[44040,0,2],[44041,0,2],[44042,0,2],[44043,0,2],[44044,0,2],[44045,0,2],[44046,0,2],[44047,0,2],[44048,0,2],[44049,0,2],[44050,0,2],[44051,0,2],[44052,0,2],[44053,0,2],[44054,0,2],[44055,0,2],[44056,0,2],[44057,0,2],[44058,0,2],[44059,0,2],[44060,0,1],[44061,0,2],[44062,0,2],[44063,0,2],[44064,0,2],[44065,0,2],[44066,0,2],[44067,0,2],[44068,0,2],[44069,0,2],[44070,0,2],[44071,0,2],[44072,0,2],[44073,0,2],[44074,0,2],[44075,0,2],[44076,0,2],[44077,0,2],[44078,0,2],[44079,0,2],[44080,0,2],[44081,0,2],[44082,0,2],[44083,0,2],[44084,0,2],[44085,0,2],[44086,0,2],[44087,0,2],[44088,0,1],[44089,0,2],[44090,0,2],[44091,0,2],[44092,0,2],[44093,0,2],[44094,0,2],[44095,0,2],[44096,0,2],[44097,0,2],[44098,0,2],[44099,0,2],[44100,0,2],[44101,0,2],[44102,0,2],[44103,0,2],[44104,0,2],[44105,0,2],[44106,0,2],[44107,0,2],[44108,0,2],[44109,0,2],[44110,0,2],[44111,0,2],[44112,0,2],[44113,0,2],[44114,0,2],[44115,0,2],[44116,0,1],[44117,0,2],[44118,0,2],[44119,0,2],[44120,0,2],[44121,0,2],[44122,0,2],[44123,0,2],[44124,0,2],[44125,0,2],[44126,0,2],[44127,0,2],[44128,0,2],[44129,0,2],[44130,0,2],[44131,0,2],[44132,0,2],[44133,0,2],[44134,0,2],[44135,0,2],[44136,0,2],[44137,0,2],[44138,0,2],[44139,0,2],[44140,0,2],[44141,0,2],[44142,0,2],[44143,0,2],[44144,0,1],[44145,0,2],[44146,0,2],[44147,0,2],[44148,0,2],[44149,0,2],[44150,0,2],[44151,0,2],[44152,0,2],[44153,0,2],[44154,0,2],[44155,0,2],[44156,0,2],[44157,0,2],[44158,0,2],[44159,0,2],[44160,0,2],[44161,0,2],[44162,0,2],[44163,0,2],[44164,0,2],[44165,0,2],[44166,0,2],[44167,0,2],[44168,0,2],[44169,0,2],[44170,0,2],[44171,0,2],[44172,0,1],[44173,0,2],[44174,0,2],[44175,0,2],[44176,0,2],[44177,0,2],[44178,0,2],[44179,0,2],[44180,0,2],[44181,0,2],[44182,0,2],[44183,0,2],[44184,0,2],[44185,0,2],[44186,0,2],[44187,0,2],[44188,0,2],[44189,0,2],[44190,0,2],[44191,0,2],[44192,0,2],[44193,0,2],[44194,0,2],[44195,0,2],[44196,0,2],[44197,0,2],[44198,0,2],[44199,0,2],[44200,0,1],[44201,0,2],[44202,0,2],[44203,0,2],[44204,0,2],[44205,0,2],[44206,0,2],[44207,0,2],[44208,0,2],[44209,0,2],[44210,0,2],[44211,0,2],[44212,0,2],[44213,0,2],[44214,0,2],[44215,0,2],[44216,0,2],[44217,0,2],[44218,0,2],[44219,0,2],[44220,0,2],[44221,0,2],[44222,0,2],[44223,0,2],[44224,0,2],[44225,0,2],[44226,0,2],[44227,0,2],[44228,0,1],[44229,0,2],[44230,0,2],[44231,0,2],[44232,0,2],[44233,0,2],[44234,0,2],[44235,0,2],[44236,0,2],[44237,0,2],[44238,0,2],[44239,0,2],[44240,0,2],[44241,0,2],[44242,0,2],[44243,0,2],[44244,0,2],[44245,0,2],[44246,0,2],[44247,0,2],[44248,0,2],[44249,0,2],[44250,0,2],[44251,0,2],[44252,0,2],[44253,0,2],[44254,0,2],[44255,0,2],[44256,0,1],[44257,0,2],[44258,0,2],[44259,0,2],[44260,0,2],[44261,0,2],[44262,0,2],[44263,0,2],[44264,0,2],[44265,0,2],[44266,0,2],[44267,0,2],[44268,0,2],[44269,0,2],[44270,0,2],[44271,0,2],[44272,0,2],[44273,0,2],[44274,0,2],[44275,0,2],[44276,0,2],[44277,0,2],[44278,0,2],[44279,0,2],[44280,0,2],[44281,0,2],[44282,0,2],[44283,0,2],[44284,0,1],[44285,0,2],[44286,0,2],[44287,0,2],[44288,0,2],[44289,0,2],[44290,0,2],[44291,0,2],[44292,0,2],[44293,0,2],[44294,0,2],[44295,0,2],[44296,0,2],[44297,0,2],[44298,0,2],[44299,0,2],[44300,0,2],[44301,0,2],[44302,0,2],[44303,0,2],[44304,0,2],[44305,0,2],[44306,0,2],[44307,0,2],[44308,0,2],[44309,0,2],[44310,0,2],[44311,0,2],[44312,0,1],[44313,0,2],[44314,0,2],[44315,0,2],[44316,0,2],[44317,0,2],[44318,0,2],[44319,0,2],[44320,0,2],[44321,0,2],[44322,0,2],[44323,0,2],[44324,0,2],[44325,0,2],[44326,0,2],[44327,0,2],[44328,0,2],[44329,0,2],[44330,0,2],[44331,0,2],[44332,0,2],[44333,0,2],[44334,0,2],[44335,0,2],[44336,0,2],[44337,0,2],[44338,0,2],[44339,0,2],[44340,0,1],[44341,0,2],[44342,0,2],[44343,0,2],[44344,0,2],[44345,0,2],[44346,0,2],[44347,0,2],[44348,0,2],[44349,0,2],[44350,0,2],[44351,0,2],[44352,0,2],[44353,0,2],[44354,0,2],[44355,0,2],[44356,0,2],[44357,0,2],[44358,0,2],[44359,0,2],[44360,0,2],[44361,0,2],[44362,0,2],[44363,0,2],[44364,0,2],[44365,0,2],[44366,0,2],[44367,0,2],[44368,0,1],[44369,0,2],[44370,0,2],[44371,0,2],[44372,0,2],[44373,0,2],[44374,0,2],[44375,0,2],[44376,0,2],[44377,0,2],[44378,0,2],[44379,0,2],[44380,0,2],[44381,0,2],[44382,0,2],[44383,0,2],[44384,0,2],[44385,0,2],[44386,0,2],[44387,0,2],[44388,0,2],[44389,0,2],[44390,0,2],[44391,0,2],[44392,0,2],[44393,0,2],[44394,0,2],[44395,0,2],[44396,0,1],[44397,0,2],[44398,0,2],[44399,0,2],[44400,0,2],[44401,0,2],[44402,0,2],[44403,0,2],[44404,0,2],[44405,0,2],[44406,0,2],[44407,0,2],[44408,0,2],[44409,0,2],[44410,0,2],[44411,0,2],[44412,0,2],[44413,0,2],[44414,0,2],[44415,0,2],[44416,0,2],[44417,0,2],[44418,0,2],[44419,0,2],[44420,0,2],[44421,0,2],[44422,0,2],[44423,0,2],[44424,0,1],[44425,0,2],[44426,0,2],[44427,0,2],[44428,0,2],[44429,0,2],[44430,0,2],[44431,0,2],[44432,0,2],[44433,0,2],[44434,0,2],[44435,0,2],[44436,0,2],[44437,0,2],[44438,0,2],[44439,0,2],[44440,0,2],[44441,0,2],[44442,0,2],[44443,0,2],[44444,0,2],[44445,0,2],[44446,0,2],[44447,0,2],[44448,0,2],[44449,0,2],[44450,0,2],[44451,0,2],[44452,0,1],[44453,0,2],[44454,0,2],[44455,0,2],[44456,0,2],[44457,0,2],[44458,0,2],[44459,0,2],[44460,0,2],[44461,0,2],[44462,0,2],[44463,0,2],[44464,0,2],[44465,0,2],[44466,0,2],[44467,0,2],[44468,0,2],[44469,0,2],[44470,0,2],[44471,0,2],[44472,0,2],[44473,0,2],[44474,0,2],[44475,0,2],[44476,0,2],[44477,0,2],[44478,0,2],[44479,0,2],[44480,0,1],[44481,0,2],[44482,0,2],[44483,0,2],[44484,0,2],[44485,0,2],[44486,0,2],[44487,0,2],[44488,0,2],[44489,0,2],[44490,0,2],[44491,0,2],[44492,0,2],[44493,0,2],[44494,0,2],[44495,0,2],[44496,0,2],[44497,0,2],[44498,0,2],[44499,0,2],[44500,0,2],[44501,0,2],[44502,0,2],[44503,0,2],[44504,0,2],[44505,0,2],[44506,0,2],[44507,0,2],[44508,0,1],[44509,0,2],[44510,0,2],[44511,0,2],[44512,0,2],[44513,0,2],[44514,0,2],[44515,0,2],[44516,0,2],[44517,0,2],[44518,0,2],[44519,0,2],[44520,0,2],[44521,0,2],[44522,0,2],[44523,0,2],[44524,0,2],[44525,0,2],[44526,0,2],[44527,0,2],[44528,0,2],[44529,0,2],[44530,0,2],[44531,0,2],[44532,0,2],[44533,0,2],[44534,0,2],[44535,0,2],[44536,0,1],[44537,0,2],[44538,0,2],[44539,0,2],[44540,0,2],[44541,0,2],[44542,0,2],[44543,0,2],[44544,0,2],[44545,0,2],[44546,0,2],[44547,0,2],[44548,0,2],[44549,0,2],[44550,0,2],[44551,0,2],[44552,0,2],[44553,0,2],[44554,0,2],[44555,0,2],[44556,0,2],[44557,0,2],[44558,0,2],[44559,0,2],[44560,0,2],[44561,0,2],[44562,0,2],[44563,0,2],[44564,0,1],[44565,0,2],[44566,0,2],[44567,0,2],[44568,0,2],[44569,0,2],[44570,0,2],[44571,0,2],[44572,0,2],[44573,0,2],[44574,0,2],[44575,0,2],[44576,0,2],[44577,0,2],[44578,0,2],[44579,0,2],[44580,0,2],[44581,0,2],[44582,0,2],[44583,0,2],[44584,0,2],[44585,0,2],[44586,0,2],[44587,0,2],[44588,0,2],[44589,0,2],[44590,0,2],[44591,0,2],[44592,0,1],[44593,0,2],[44594,0,2],[44595,0,2],[44596,0,2],[44597,0,2],[44598,0,2],[44599,0,2],[44600,0,2],[44601,0,2],[44602,0,2],[44603,0,2],[44604,0,2],[44605,0,2],[44606,0,2],[44607,0,2],[44608,0,2],[44609,0,2],[44610,0,2],[44611,0,2],[44612,0,2],[44613,0,2],[44614,0,2],[44615,0,2],[44616,0,2],[44617,0,2],[44618,0,2],[44619,0,2],[44620,0,1],[44621,0,2],[44622,0,2],[44623,0,2],[44624,0,2],[44625,0,2],[44626,0,2],[44627,0,2],[44628,0,2],[44629,0,2],[44630,0,2],[44631,0,2],[44632,0,2],[44633,0,2],[44634,0,2],[44635,0,2],[44636,0,2],[44637,0,2],[44638,0,2],[44639,0,2],[44640,0,2],[44641,0,2],[44642,0,2],[44643,0,2],[44644,0,2],[44645,0,2],[44646,0,2],[44647,0,2],[44648,0,1],[44649,0,2],[44650,0,2],[44651,0,2],[44652,0,2],[44653,0,2],[44654,0,2],[44655,0,2],[44656,0,2],[44657,0,2],[44658,0,2],[44659,0,2],[44660,0,2],[44661,0,2],[44662,0,2],[44663,0,2],[44664,0,2],[44665,0,2],[44666,0,2],[44667,0,2],[44668,0,2],[44669,0,2],[44670,0,2],[44671,0,2],[44672,0,2],[44673,0,2],[44674,0,2],[44675,0,2],[44676,0,1],[44677,0,2],[44678,0,2],[44679,0,2],[44680,0,2],[44681,0,2],[44682,0,2],[44683,0,2],[44684,0,2],[44685,0,2],[44686,0,2],[44687,0,2],[44688,0,2],[44689,0,2],[44690,0,2],[44691,0,2],[44692,0,2],[44693,0,2],[44694,0,2],[44695,0,2],[44696,0,2],[44697,0,2],[44698,0,2],[44699,0,2],[44700,0,2],[44701,0,2],[44702,0,2],[44703,0,2],[44704,0,1],[44705,0,2],[44706,0,2],[44707,0,2],[44708,0,2],[44709,0,2],[44710,0,2],[44711,0,2],[44712,0,2],[44713,0,2],[44714,0,2],[44715,0,2],[44716,0,2],[44717,0,2],[44718,0,2],[44719,0,2],[44720,0,2],[44721,0,2],[44722,0,2],[44723,0,2],[44724,0,2],[44725,0,2],[44726,0,2],[44727,0,2],[44728,0,2],[44729,0,2],[44730,0,2],[44731,0,2],[44732,0,1],[44733,0,2],[44734,0,2],[44735,0,2],[44736,0,2],[44737,0,2],[44738,0,2],[44739,0,2],[44740,0,2],[44741,0,2],[44742,0,2],[44743,0,2],[44744,0,2],[44745,0,2],[44746,0,2],[44747,0,2],[44748,0,2],[44749,0,2],[44750,0,2],[44751,0,2],[44752,0,2],[44753,0,2],[44754,0,2],[44755,0,2],[44756,0,2],[44757,0,2],[44758,0,2],[44759,0,2],[44760,0,1],[44761,0,2],[44762,0,2],[44763,0,2],[44764,0,2],[44765,0,2],[44766,0,2],[44767,0,2],[44768,0,2],[44769,0,2],[44770,0,2],[44771,0,2],[44772,0,2],[44773,0,2],[44774,0,2],[44775,0,2],[44776,0,2],[44777,0,2],[44778,0,2],[44779,0,2],[44780,0,2],[44781,0,2],[44782,0,2],[44783,0,2],[44784,0,2],[44785,0,2],[44786,0,2],[44787,0,2],[44788,0,1],[44789,0,2],[44790,0,2],[44791,0,2],[44792,0,2],[44793,0,2],[44794,0,2],[44795,0,2],[44796,0,2],[44797,0,2],[44798,0,2],[44799,0,2],[44800,0,2],[44801,0,2],[44802,0,2],[44803,0,2],[44804,0,2],[44805,0,2],[44806,0,2],[44807,0,2],[44808,0,2],[44809,0,2],[44810,0,2],[44811,0,2],[44812,0,2],[44813,0,2],[44814,0,2],[44815,0,2],[44816,0,1],[44817,0,2],[44818,0,2],[44819,0,2],[44820,0,2],[44821,0,2],[44822,0,2],[44823,0,2],[44824,0,2],[44825,0,2],[44826,0,2],[44827,0,2],[44828,0,2],[44829,0,2],[44830,0,2],[44831,0,2],[44832,0,2],[44833,0,2],[44834,0,2],[44835,0,2],[44836,0,2],[44837,0,2],[44838,0,2],[44839,0,2],[44840,0,2],[44841,0,2],[44842,0,2],[44843,0,2],[44844,0,1],[44845,0,2],[44846,0,2],[44847,0,2],[44848,0,2],[44849,0,2],[44850,0,2],[44851,0,2],[44852,0,2],[44853,0,2],[44854,0,2],[44855,0,2],[44856,0,2],[44857,0,2],[44858,0,2],[44859,0,2],[44860,0,2],[44861,0,2],[44862,0,2],[44863,0,2],[44864,0,2],[44865,0,2],[44866,0,2],[44867,0,2],[44868,0,2],[44869,0,2],[44870,0,2],[44871,0,2],[44872,0,1],[44873,0,2],[44874,0,2],[44875,0,2],[44876,0,2],[44877,0,2],[44878,0,2],[44879,0,2],[44880,0,2],[44881,0,2],[44882,0,2],[44883,0,2],[44884,0,2],[44885,0,2],[44886,0,2],[44887,0,2],[44888,0,2],[44889,0,2],[44890,0,2],[44891,0,2],[44892,0,2],[44893,0,2],[44894,0,2],[44895,0,2],[44896,0,2],[44897,0,2],[44898,0,2],[44899,0,2],[44900,0,1],[44901,0,2],[44902,0,2],[44903,0,2],[44904,0,2],[44905,0,2],[44906,0,2],[44907,0,2],[44908,0,2],[44909,0,2],[44910,0,2],[44911,0,2],[44912,0,2],[44913,0,2],[44914,0,2],[44915,0,2],[44916,0,2],[44917,0,2],[44918,0,2],[44919,0,2],[44920,0,2],[44921,0,2],[44922,0,2],[44923,0,2],[44924,0,2],[44925,0,2],[44926,0,2],[44927,0,2],[44928,0,1],[44929,0,2],[44930,0,2],[44931,0,2],[44932,0,2],[44933,0,2],[44934,0,2],[44935,0,2],[44936,0,2],[44937,0,2],[44938,0,2],[44939,0,2],[44940,0,2],[44941,0,2],[44942,0,2],[44943,0,2],[44944,0,2],[44945,0,2],[44946,0,2],[44947,0,2],[44948,0,2],[44949,0,2],[44950,0,2],[44951,0,2],[44952,0,2],[44953,0,2],[44954,0,2],[44955,0,2],[44956,0,1],[44957,0,2],[44958,0,2],[44959,0,2],[44960,0,2],[44961,0,2],[44962,0,2],[44963,0,2],[44964,0,2],[44965,0,2],[44966,0,2],[44967,0,2],[44968,0,2],[44969,0,2],[44970,0,2],[44971,0,2],[44972,0,2],[44973,0,2],[44974,0,2],[44975,0,2],[44976,0,2],[44977,0,2],[44978,0,2],[44979,0,2],[44980,0,2],[44981,0,2],[44982,0,2],[44983,0,2],[44984,0,1],[44985,0,2],[44986,0,2],[44987,0,2],[44988,0,2],[44989,0,2],[44990,0,2],[44991,0,2],[44992,0,2],[44993,0,2],[44994,0,2],[44995,0,2],[44996,0,2],[44997,0,2],[44998,0,2],[44999,0,2],[45000,0,2],[45001,0,2],[45002,0,2],[45003,0,2],[45004,0,2],[45005,0,2],[45006,0,2],[45007,0,2],[45008,0,2],[45009,0,2],[45010,0,2],[45011,0,2],[45012,0,1],[45013,0,2],[45014,0,2],[45015,0,2],[45016,0,2],[45017,0,2],[45018,0,2],[45019,0,2],[45020,0,2],[45021,0,2],[45022,0,2],[45023,0,2],[45024,0,2],[45025,0,2],[45026,0,2],[45027,0,2],[45028,0,2],[45029,0,2],[45030,0,2],[45031,0,2],[45032,0,2],[45033,0,2],[45034,0,2],[45035,0,2],[45036,0,2],[45037,0,2],[45038,0,2],[45039,0,2],[45040,0,1],[45041,0,2],[45042,0,2],[45043,0,2],[45044,0,2],[45045,0,2],[45046,0,2],[45047,0,2],[45048,0,2],[45049,0,2],[45050,0,2],[45051,0,2],[45052,0,2],[45053,0,2],[45054,0,2],[45055,0,2],[45056,0,2],[45057,0,2],[45058,0,2],[45059,0,2],[45060,0,2],[45061,0,2],[45062,0,2],[45063,0,2],[45064,0,2],[45065,0,2],[45066,0,2],[45067,0,2],[45068,0,1],[45069,0,2],[45070,0,2],[45071,0,2],[45072,0,2],[45073,0,2],[45074,0,2],[45075,0,2],[45076,0,2],[45077,0,2],[45078,0,2],[45079,0,2],[45080,0,2],[45081,0,2],[45082,0,2],[45083,0,2],[45084,0,2],[45085,0,2],[45086,0,2],[45087,0,2],[45088,0,2],[45089,0,2],[45090,0,2],[45091,0,2],[45092,0,2],[45093,0,2],[45094,0,2],[45095,0,2],[45096,0,1],[45097,0,2],[45098,0,2],[45099,0,2],[45100,0,2],[45101,0,2],[45102,0,2],[45103,0,2],[45104,0,2],[45105,0,2],[45106,0,2],[45107,0,2],[45108,0,2],[45109,0,2],[45110,0,2],[45111,0,2],[45112,0,2],[45113,0,2],[45114,0,2],[45115,0,2],[45116,0,2],[45117,0,2],[45118,0,2],[45119,0,2],[45120,0,2],[45121,0,2],[45122,0,2],[45123,0,2],[45124,0,1],[45125,0,2],[45126,0,2],[45127,0,2],[45128,0,2],[45129,0,2],[45130,0,2],[45131,0,2],[45132,0,2],[45133,0,2],[45134,0,2],[45135,0,2],[45136,0,2],[45137,0,2],[45138,0,2],[45139,0,2],[45140,0,2],[45141,0,2],[45142,0,2],[45143,0,2],[45144,0,2],[45145,0,2],[45146,0,2],[45147,0,2],[45148,0,2],[45149,0,2],[45150,0,2],[45151,0,2],[45152,0,1],[45153,0,2],[45154,0,2],[45155,0,2],[45156,0,2],[45157,0,2],[45158,0,2],[45159,0,2],[45160,0,2],[45161,0,2],[45162,0,2],[45163,0,2],[45164,0,2],[45165,0,2],[45166,0,2],[45167,0,2],[45168,0,2],[45169,0,2],[45170,0,2],[45171,0,2],[45172,0,2],[45173,0,2],[45174,0,2],[45175,0,2],[45176,0,2],[45177,0,2],[45178,0,2],[45179,0,2],[45180,0,1],[45181,0,2],[45182,0,2],[45183,0,2],[45184,0,2],[45185,0,2],[45186,0,2],[45187,0,2],[45188,0,2],[45189,0,2],[45190,0,2],[45191,0,2],[45192,0,2],[45193,0,2],[45194,0,2],[45195,0,2],[45196,0,2],[45197,0,2],[45198,0,2],[45199,0,2],[45200,0,2],[45201,0,2],[45202,0,2],[45203,0,2],[45204,0,2],[45205,0,2],[45206,0,2],[45207,0,2],[45208,0,1],[45209,0,2],[45210,0,2],[45211,0,2],[45212,0,2],[45213,0,2],[45214,0,2],[45215,0,2],[45216,0,2],[45217,0,2],[45218,0,2],[45219,0,2],[45220,0,2],[45221,0,2],[45222,0,2],[45223,0,2],[45224,0,2],[45225,0,2],[45226,0,2],[45227,0,2],[45228,0,2],[45229,0,2],[45230,0,2],[45231,0,2],[45232,0,2],[45233,0,2],[45234,0,2],[45235,0,2],[45236,0,1],[45237,0,2],[45238,0,2],[45239,0,2],[45240,0,2],[45241,0,2],[45242,0,2],[45243,0,2],[45244,0,2],[45245,0,2],[45246,0,2],[45247,0,2],[45248,0,2],[45249,0,2],[45250,0,2],[45251,0,2],[45252,0,2],[45253,0,2],[45254,0,2],[45255,0,2],[45256,0,2],[45257,0,2],[45258,0,2],[45259,0,2],[45260,0,2],[45261,0,2],[45262,0,2],[45263,0,2],[45264,0,1],[45265,0,2],[45266,0,2],[45267,0,2],[45268,0,2],[45269,0,2],[45270,0,2],[45271,0,2],[45272,0,2],[45273,0,2],[45274,0,2],[45275,0,2],[45276,0,2],[45277,0,2],[45278,0,2],[45279,0,2],[45280,0,2],[45281,0,2],[45282,0,2],[45283,0,2],[45284,0,2],[45285,0,2],[45286,0,2],[45287,0,2],[45288,0,2],[45289,0,2],[45290,0,2],[45291,0,2],[45292,0,1],[45293,0,2],[45294,0,2],[45295,0,2],[45296,0,2],[45297,0,2],[45298,0,2],[45299,0,2],[45300,0,2],[45301,0,2],[45302,0,2],[45303,0,2],[45304,0,2],[45305,0,2],[45306,0,2],[45307,0,2],[45308,0,2],[45309,0,2],[45310,0,2],[45311,0,2],[45312,0,2],[45313,0,2],[45314,0,2],[45315,0,2],[45316,0,2],[45317,0,2],[45318,0,2],[45319,0,2],[45320,0,1],[45321,0,2],[45322,0,2],[45323,0,2],[45324,0,2],[45325,0,2],[45326,0,2],[45327,0,2],[45328,0,2],[45329,0,2],[45330,0,2],[45331,0,2],[45332,0,2],[45333,0,2],[45334,0,2],[45335,0,2],[45336,0,2],[45337,0,2],[45338,0,2],[45339,0,2],[45340,0,2],[45341,0,2],[45342,0,2],[45343,0,2],[45344,0,2],[45345,0,2],[45346,0,2],[45347,0,2],[45348,0,1],[45349,0,2],[45350,0,2],[45351,0,2],[45352,0,2],[45353,0,2],[45354,0,2],[45355,0,2],[45356,0,2],[45357,0,2],[45358,0,2],[45359,0,2],[45360,0,2],[45361,0,2],[45362,0,2],[45363,0,2],[45364,0,2],[45365,0,2],[45366,0,2],[45367,0,2],[45368,0,2],[45369,0,2],[45370,0,2],[45371,0,2],[45372,0,2],[45373,0,2],[45374,0,2],[45375,0,2],[45376,0,1],[45377,0,2],[45378,0,2],[45379,0,2],[45380,0,2],[45381,0,2],[45382,0,2],[45383,0,2],[45384,0,2],[45385,0,2],[45386,0,2],[45387,0,2],[45388,0,2],[45389,0,2],[45390,0,2],[45391,0,2],[45392,0,2],[45393,0,2],[45394,0,2],[45395,0,2],[45396,0,2],[45397,0,2],[45398,0,2],[45399,0,2],[45400,0,2],[45401,0,2],[45402,0,2],[45403,0,2],[45404,0,1],[45405,0,2],[45406,0,2],[45407,0,2],[45408,0,2],[45409,0,2],[45410,0,2],[45411,0,2],[45412,0,2],[45413,0,2],[45414,0,2],[45415,0,2],[45416,0,2],[45417,0,2],[45418,0,2],[45419,0,2],[45420,0,2],[45421,0,2],[45422,0,2],[45423,0,2],[45424,0,2],[45425,0,2],[45426,0,2],[45427,0,2],[45428,0,2],[45429,0,2],[45430,0,2],[45431,0,2],[45432,0,1],[45433,0,2],[45434,0,2],[45435,0,2],[45436,0,2],[45437,0,2],[45438,0,2],[45439,0,2],[45440,0,2],[45441,0,2],[45442,0,2],[45443,0,2],[45444,0,2],[45445,0,2],[45446,0,2],[45447,0,2],[45448,0,2],[45449,0,2],[45450,0,2],[45451,0,2],[45452,0,2],[45453,0,2],[45454,0,2],[45455,0,2],[45456,0,2],[45457,0,2],[45458,0,2],[45459,0,2],[45460,0,1],[45461,0,2],[45462,0,2],[45463,0,2],[45464,0,2],[45465,0,2],[45466,0,2],[45467,0,2],[45468,0,2],[45469,0,2],[45470,0,2],[45471,0,2],[45472,0,2],[45473,0,2],[45474,0,2],[45475,0,2],[45476,0,2],[45477,0,2],[45478,0,2],[45479,0,2],[45480,0,2],[45481,0,2],[45482,0,2],[45483,0,2],[45484,0,2],[45485,0,2],[45486,0,2],[45487,0,2],[45488,0,1],[45489,0,2],[45490,0,2],[45491,0,2],[45492,0,2],[45493,0,2],[45494,0,2],[45495,0,2],[45496,0,2],[45497,0,2],[45498,0,2],[45499,0,2],[45500,0,2],[45501,0,2],[45502,0,2],[45503,0,2],[45504,0,2],[45505,0,2],[45506,0,2],[45507,0,2],[45508,0,2],[45509,0,2],[45510,0,2],[45511,0,2],[45512,0,2],[45513,0,2],[45514,0,2],[45515,0,2],[45516,0,1],[45517,0,2],[45518,0,2],[45519,0,2],[45520,0,2],[45521,0,2],[45522,0,2],[45523,0,2],[45524,0,2],[45525,0,2],[45526,0,2],[45527,0,2],[45528,0,2],[45529,0,2],[45530,0,2],[45531,0,2],[45532,0,2],[45533,0,2],[45534,0,2],[45535,0,2],[45536,0,2],[45537,0,2],[45538,0,2],[45539,0,2],[45540,0,2],[45541,0,2],[45542,0,2],[45543,0,2],[45544,0,1],[45545,0,2],[45546,0,2],[45547,0,2],[45548,0,2],[45549,0,2],[45550,0,2],[45551,0,2],[45552,0,2],[45553,0,2],[45554,0,2],[45555,0,2],[45556,0,2],[45557,0,2],[45558,0,2],[45559,0,2],[45560,0,2],[45561,0,2],[45562,0,2],[45563,0,2],[45564,0,2],[45565,0,2],[45566,0,2],[45567,0,2],[45568,0,2],[45569,0,2],[45570,0,2],[45571,0,2],[45572,0,1],[45573,0,2],[45574,0,2],[45575,0,2],[45576,0,2],[45577,0,2],[45578,0,2],[45579,0,2],[45580,0,2],[45581,0,2],[45582,0,2],[45583,0,2],[45584,0,2],[45585,0,2],[45586,0,2],[45587,0,2],[45588,0,2],[45589,0,2],[45590,0,2],[45591,0,2],[45592,0,2],[45593,0,2],[45594,0,2],[45595,0,2],[45596,0,2],[45597,0,2],[45598,0,2],[45599,0,2],[45600,0,1],[45601,0,2],[45602,0,2],[45603,0,2],[45604,0,2],[45605,0,2],[45606,0,2],[45607,0,2],[45608,0,2],[45609,0,2],[45610,0,2],[45611,0,2],[45612,0,2],[45613,0,2],[45614,0,2],[45615,0,2],[45616,0,2],[45617,0,2],[45618,0,2],[45619,0,2],[45620,0,2],[45621,0,2],[45622,0,2],[45623,0,2],[45624,0,2],[45625,0,2],[45626,0,2],[45627,0,2],[45628,0,1],[45629,0,2],[45630,0,2],[45631,0,2],[45632,0,2],[45633,0,2],[45634,0,2],[45635,0,2],[45636,0,2],[45637,0,2],[45638,0,2],[45639,0,2],[45640,0,2],[45641,0,2],[45642,0,2],[45643,0,2],[45644,0,2],[45645,0,2],[45646,0,2],[45647,0,2],[45648,0,2],[45649,0,2],[45650,0,2],[45651,0,2],[45652,0,2],[45653,0,2],[45654,0,2],[45655,0,2],[45656,0,1],[45657,0,2],[45658,0,2],[45659,0,2],[45660,0,2],[45661,0,2],[45662,0,2],[45663,0,2],[45664,0,2],[45665,0,2],[45666,0,2],[45667,0,2],[45668,0,2],[45669,0,2],[45670,0,2],[45671,0,2],[45672,0,2],[45673,0,2],[45674,0,2],[45675,0,2],[45676,0,2],[45677,0,2],[45678,0,2],[45679,0,2],[45680,0,2],[45681,0,2],[45682,0,2],[45683,0,2],[45684,0,1],[45685,0,2],[45686,0,2],[45687,0,2],[45688,0,2],[45689,0,2],[45690,0,2],[45691,0,2],[45692,0,2],[45693,0,2],[45694,0,2],[45695,0,2],[45696,0,2],[45697,0,2],[45698,0,2],[45699,0,2],[45700,0,2],[45701,0,2],[45702,0,2],[45703,0,2],[45704,0,2],[45705,0,2],[45706,0,2],[45707,0,2],[45708,0,2],[45709,0,2],[45710,0,2],[45711,0,2],[45712,0,1],[45713,0,2],[45714,0,2],[45715,0,2],[45716,0,2],[45717,0,2],[45718,0,2],[45719,0,2],[45720,0,2],[45721,0,2],[45722,0,2],[45723,0,2],[45724,0,2],[45725,0,2],[45726,0,2],[45727,0,2],[45728,0,2],[45729,0,2],[45730,0,2],[45731,0,2],[45732,0,2],[45733,0,2],[45734,0,2],[45735,0,2],[45736,0,2],[45737,0,2],[45738,0,2],[45739,0,2],[45740,0,1],[45741,0,2],[45742,0,2],[45743,0,2],[45744,0,2],[45745,0,2],[45746,0,2],[45747,0,2],[45748,0,2],[45749,0,2],[45750,0,2],[45751,0,2],[45752,0,2],[45753,0,2],[45754,0,2],[45755,0,2],[45756,0,2],[45757,0,2],[45758,0,2],[45759,0,2],[45760,0,2],[45761,0,2],[45762,0,2],[45763,0,2],[45764,0,2],[45765,0,2],[45766,0,2],[45767,0,2],[45768,0,1],[45769,0,2],[45770,0,2],[45771,0,2],[45772,0,2],[45773,0,2],[45774,0,2],[45775,0,2],[45776,0,2],[45777,0,2],[45778,0,2],[45779,0,2],[45780,0,2],[45781,0,2],[45782,0,2],[45783,0,2],[45784,0,2],[45785,0,2],[45786,0,2],[45787,0,2],[45788,0,2],[45789,0,2],[45790,0,2],[45791,0,2],[45792,0,2],[45793,0,2],[45794,0,2],[45795,0,2],[45796,0,1],[45797,0,2],[45798,0,2],[45799,0,2],[45800,0,2],[45801,0,2],[45802,0,2],[45803,0,2],[45804,0,2],[45805,0,2],[45806,0,2],[45807,0,2],[45808,0,2],[45809,0,2],[45810,0,2],[45811,0,2],[45812,0,2],[45813,0,2],[45814,0,2],[45815,0,2],[45816,0,2],[45817,0,2],[45818,0,2],[45819,0,2],[45820,0,2],[45821,0,2],[45822,0,2],[45823,0,2],[45824,0,1],[45825,0,2],[45826,0,2],[45827,0,2],[45828,0,2],[45829,0,2],[45830,0,2],[45831,0,2],[45832,0,2],[45833,0,2],[45834,0,2],[45835,0,2],[45836,0,2],[45837,0,2],[45838,0,2],[45839,0,2],[45840,0,2],[45841,0,2],[45842,0,2],[45843,0,2],[45844,0,2],[45845,0,2],[45846,0,2],[45847,0,2],[45848,0,2],[45849,0,2],[45850,0,2],[45851,0,2],[45852,0,1],[45853,0,2],[45854,0,2],[45855,0,2],[45856,0,2],[45857,0,2],[45858,0,2],[45859,0,2],[45860,0,2],[45861,0,2],[45862,0,2],[45863,0,2],[45864,0,2],[45865,0,2],[45866,0,2],[45867,0,2],[45868,0,2],[45869,0,2],[45870,0,2],[45871,0,2],[45872,0,2],[45873,0,2],[45874,0,2],[45875,0,2],[45876,0,2],[45877,0,2],[45878,0,2],[45879,0,2],[45880,0,1],[45881,0,2],[45882,0,2],[45883,0,2],[45884,0,2],[45885,0,2],[45886,0,2],[45887,0,2],[45888,0,2],[45889,0,2],[45890,0,2],[45891,0,2],[45892,0,2],[45893,0,2],[45894,0,2],[45895,0,2],[45896,0,2],[45897,0,2],[45898,0,2],[45899,0,2],[45900,0,2],[45901,0,2],[45902,0,2],[45903,0,2],[45904,0,2],[45905,0,2],[45906,0,2],[45907,0,2],[45908,0,1],[45909,0,2],[45910,0,2],[45911,0,2],[45912,0,2],[45913,0,2],[45914,0,2],[45915,0,2],[45916,0,2],[45917,0,2],[45918,0,2],[45919,0,2],[45920,0,2],[45921,0,2],[45922,0,2],[45923,0,2],[45924,0,2],[45925,0,2],[45926,0,2],[45927,0,2],[45928,0,2],[45929,0,2],[45930,0,2],[45931,0,2],[45932,0,2],[45933,0,2],[45934,0,2],[45935,0,2],[45936,0,1],[45937,0,2],[45938,0,2],[45939,0,2],[45940,0,2],[45941,0,2],[45942,0,2],[45943,0,2],[45944,0,2],[45945,0,2],[45946,0,2],[45947,0,2],[45948,0,2],[45949,0,2],[45950,0,2],[45951,0,2],[45952,0,2],[45953,0,2],[45954,0,2],[45955,0,2],[45956,0,2],[45957,0,2],[45958,0,2],[45959,0,2],[45960,0,2],[45961,0,2],[45962,0,2],[45963,0,2],[45964,0,1],[45965,0,2],[45966,0,2],[45967,0,2],[45968,0,2],[45969,0,2],[45970,0,2],[45971,0,2],[45972,0,2],[45973,0,2],[45974,0,2],[45975,0,2],[45976,0,2],[45977,0,2],[45978,0,2],[45979,0,2],[45980,0,2],[45981,0,2],[45982,0,2],[45983,0,2],[45984,0,2],[45985,0,2],[45986,0,2],[45987,0,2],[45988,0,2],[45989,0,2],[45990,0,2],[45991,0,2],[45992,0,1],[45993,0,2],[45994,0,2],[45995,0,2],[45996,0,2],[45997,0,2],[45998,0,2],[45999,0,2],[46000,0,2],[46001,0,2],[46002,0,2],[46003,0,2],[46004,0,2],[46005,0,2],[46006,0,2],[46007,0,2],[46008,0,2],[46009,0,2],[46010,0,2],[46011,0,2],[46012,0,2],[46013,0,2],[46014,0,2],[46015,0,2],[46016,0,2],[46017,0,2],[46018,0,2],[46019,0,2],[46020,0,1],[46021,0,2],[46022,0,2],[46023,0,2],[46024,0,2],[46025,0,2],[46026,0,2],[46027,0,2],[46028,0,2],[46029,0,2],[46030,0,2],[46031,0,2],[46032,0,2],[46033,0,2],[46034,0,2],[46035,0,2],[46036,0,2],[46037,0,2],[46038,0,2],[46039,0,2],[46040,0,2],[46041,0,2],[46042,0,2],[46043,0,2],[46044,0,2],[46045,0,2],[46046,0,2],[46047,0,2],[46048,0,1],[46049,0,2],[46050,0,2],[46051,0,2],[46052,0,2],[46053,0,2],[46054,0,2],[46055,0,2],[46056,0,2],[46057,0,2],[46058,0,2],[46059,0,2],[46060,0,2],[46061,0,2],[46062,0,2],[46063,0,2],[46064,0,2],[46065,0,2],[46066,0,2],[46067,0,2],[46068,0,2],[46069,0,2],[46070,0,2],[46071,0,2],[46072,0,2],[46073,0,2],[46074,0,2],[46075,0,2],[46076,0,1],[46077,0,2],[46078,0,2],[46079,0,2],[46080,0,2],[46081,0,2],[46082,0,2],[46083,0,2],[46084,0,2],[46085,0,2],[46086,0,2],[46087,0,2],[46088,0,2],[46089,0,2],[46090,0,2],[46091,0,2],[46092,0,2],[46093,0,2],[46094,0,2],[46095,0,2],[46096,0,2],[46097,0,2],[46098,0,2],[46099,0,2],[46100,0,2],[46101,0,2],[46102,0,2],[46103,0,2],[46104,0,1],[46105,0,2],[46106,0,2],[46107,0,2],[46108,0,2],[46109,0,2],[46110,0,2],[46111,0,2],[46112,0,2],[46113,0,2],[46114,0,2],[46115,0,2],[46116,0,2],[46117,0,2],[46118,0,2],[46119,0,2],[46120,0,2],[46121,0,2],[46122,0,2],[46123,0,2],[46124,0,2],[46125,0,2],[46126,0,2],[46127,0,2],[46128,0,2],[46129,0,2],[46130,0,2],[46131,0,2],[46132,0,1],[46133,0,2],[46134,0,2],[46135,0,2],[46136,0,2],[46137,0,2],[46138,0,2],[46139,0,2],[46140,0,2],[46141,0,2],[46142,0,2],[46143,0,2],[46144,0,2],[46145,0,2],[46146,0,2],[46147,0,2],[46148,0,2],[46149,0,2],[46150,0,2],[46151,0,2],[46152,0,2],[46153,0,2],[46154,0,2],[46155,0,2],[46156,0,2],[46157,0,2],[46158,0,2],[46159,0,2],[46160,0,1],[46161,0,2],[46162,0,2],[46163,0,2],[46164,0,2],[46165,0,2],[46166,0,2],[46167,0,2],[46168,0,2],[46169,0,2],[46170,0,2],[46171,0,2],[46172,0,2],[46173,0,2],[46174,0,2],[46175,0,2],[46176,0,2],[46177,0,2],[46178,0,2],[46179,0,2],[46180,0,2],[46181,0,2],[46182,0,2],[46183,0,2],[46184,0,2],[46185,0,2],[46186,0,2],[46187,0,2],[46188,0,1],[46189,0,2],[46190,0,2],[46191,0,2],[46192,0,2],[46193,0,2],[46194,0,2],[46195,0,2],[46196,0,2],[46197,0,2],[46198,0,2],[46199,0,2],[46200,0,2],[46201,0,2],[46202,0,2],[46203,0,2],[46204,0,2],[46205,0,2],[46206,0,2],[46207,0,2],[46208,0,2],[46209,0,2],[46210,0,2],[46211,0,2],[46212,0,2],[46213,0,2],[46214,0,2],[46215,0,2],[46216,0,1],[46217,0,2],[46218,0,2],[46219,0,2],[46220,0,2],[46221,0,2],[46222,0,2],[46223,0,2],[46224,0,2],[46225,0,2],[46226,0,2],[46227,0,2],[46228,0,2],[46229,0,2],[46230,0,2],[46231,0,2],[46232,0,2],[46233,0,2],[46234,0,2],[46235,0,2],[46236,0,2],[46237,0,2],[46238,0,2],[46239,0,2],[46240,0,2],[46241,0,2],[46242,0,2],[46243,0,2],[46244,0,1],[46245,0,2],[46246,0,2],[46247,0,2],[46248,0,2],[46249,0,2],[46250,0,2],[46251,0,2],[46252,0,2],[46253,0,2],[46254,0,2],[46255,0,2],[46256,0,2],[46257,0,2],[46258,0,2],[46259,0,2],[46260,0,2],[46261,0,2],[46262,0,2],[46263,0,2],[46264,0,2],[46265,0,2],[46266,0,2],[46267,0,2],[46268,0,2],[46269,0,2],[46270,0,2],[46271,0,2],[46272,0,1],[46273,0,2],[46274,0,2],[46275,0,2],[46276,0,2],[46277,0,2],[46278,0,2],[46279,0,2],[46280,0,2],[46281,0,2],[46282,0,2],[46283,0,2],[46284,0,2],[46285,0,2],[46286,0,2],[46287,0,2],[46288,0,2],[46289,0,2],[46290,0,2],[46291,0,2],[46292,0,2],[46293,0,2],[46294,0,2],[46295,0,2],[46296,0,2],[46297,0,2],[46298,0,2],[46299,0,2],[46300,0,1],[46301,0,2],[46302,0,2],[46303,0,2],[46304,0,2],[46305,0,2],[46306,0,2],[46307,0,2],[46308,0,2],[46309,0,2],[46310,0,2],[46311,0,2],[46312,0,2],[46313,0,2],[46314,0,2],[46315,0,2],[46316,0,2],[46317,0,2],[46318,0,2],[46319,0,2],[46320,0,2],[46321,0,2],[46322,0,2],[46323,0,2],[46324,0,2],[46325,0,2],[46326,0,2],[46327,0,2],[46328,0,1],[46329,0,2],[46330,0,2],[46331,0,2],[46332,0,2],[46333,0,2],[46334,0,2],[46335,0,2],[46336,0,2],[46337,0,2],[46338,0,2],[46339,0,2],[46340,0,2],[46341,0,2],[46342,0,2],[46343,0,2],[46344,0,2],[46345,0,2],[46346,0,2],[46347,0,2],[46348,0,2],[46349,0,2],[46350,0,2],[46351,0,2],[46352,0,2],[46353,0,2],[46354,0,2],[46355,0,2],[46356,0,1],[46357,0,2],[46358,0,2],[46359,0,2],[46360,0,2],[46361,0,2],[46362,0,2],[46363,0,2],[46364,0,2],[46365,0,2],[46366,0,2],[46367,0,2],[46368,0,2],[46369,0,2],[46370,0,2],[46371,0,2],[46372,0,2],[46373,0,2],[46374,0,2],[46375,0,2],[46376,0,2],[46377,0,2],[46378,0,2],[46379,0,2],[46380,0,2],[46381,0,2],[46382,0,2],[46383,0,2],[46384,0,1],[46385,0,2],[46386,0,2],[46387,0,2],[46388,0,2],[46389,0,2],[46390,0,2],[46391,0,2],[46392,0,2],[46393,0,2],[46394,0,2],[46395,0,2],[46396,0,2],[46397,0,2],[46398,0,2],[46399,0,2],[46400,0,2],[46401,0,2],[46402,0,2],[46403,0,2],[46404,0,2],[46405,0,2],[46406,0,2],[46407,0,2],[46408,0,2],[46409,0,2],[46410,0,2],[46411,0,2],[46412,0,1],[46413,0,2],[46414,0,2],[46415,0,2],[46416,0,2],[46417,0,2],[46418,0,2],[46419,0,2],[46420,0,2],[46421,0,2],[46422,0,2],[46423,0,2],[46424,0,2],[46425,0,2],[46426,0,2],[46427,0,2],[46428,0,2],[46429,0,2],[46430,0,2],[46431,0,2],[46432,0,2],[46433,0,2],[46434,0,2],[46435,0,2],[46436,0,2],[46437,0,2],[46438,0,2],[46439,0,2],[46440,0,1],[46441,0,2],[46442,0,2],[46443,0,2],[46444,0,2],[46445,0,2],[46446,0,2],[46447,0,2],[46448,0,2],[46449,0,2],[46450,0,2],[46451,0,2],[46452,0,2],[46453,0,2],[46454,0,2],[46455,0,2],[46456,0,2],[46457,0,2],[46458,0,2],[46459,0,2],[46460,0,2],[46461,0,2],[46462,0,2],[46463,0,2],[46464,0,2],[46465,0,2],[46466,0,2],[46467,0,2],[46468,0,1],[46469,0,2],[46470,0,2],[46471,0,2],[46472,0,2],[46473,0,2],[46474,0,2],[46475,0,2],[46476,0,2],[46477,0,2],[46478,0,2],[46479,0,2],[46480,0,2],[46481,0,2],[46482,0,2],[46483,0,2],[46484,0,2],[46485,0,2],[46486,0,2],[46487,0,2],[46488,0,2],[46489,0,2],[46490,0,2],[46491,0,2],[46492,0,2],[46493,0,2],[46494,0,2],[46495,0,2],[46496,0,1],[46497,0,2],[46498,0,2],[46499,0,2],[46500,0,2],[46501,0,2],[46502,0,2],[46503,0,2],[46504,0,2],[46505,0,2],[46506,0,2],[46507,0,2],[46508,0,2],[46509,0,2],[46510,0,2],[46511,0,2],[46512,0,2],[46513,0,2],[46514,0,2],[46515,0,2],[46516,0,2],[46517,0,2],[46518,0,2],[46519,0,2],[46520,0,2],[46521,0,2],[46522,0,2],[46523,0,2],[46524,0,1],[46525,0,2],[46526,0,2],[46527,0,2],[46528,0,2],[46529,0,2],[46530,0,2],[46531,0,2],[46532,0,2],[46533,0,2],[46534,0,2],[46535,0,2],[46536,0,2],[46537,0,2],[46538,0,2],[46539,0,2],[46540,0,2],[46541,0,2],[46542,0,2],[46543,0,2],[46544,0,2],[46545,0,2],[46546,0,2],[46547,0,2],[46548,0,2],[46549,0,2],[46550,0,2],[46551,0,2],[46552,0,1],[46553,0,2],[46554,0,2],[46555,0,2],[46556,0,2],[46557,0,2],[46558,0,2],[46559,0,2],[46560,0,2],[46561,0,2],[46562,0,2],[46563,0,2],[46564,0,2],[46565,0,2],[46566,0,2],[46567,0,2],[46568,0,2],[46569,0,2],[46570,0,2],[46571,0,2],[46572,0,2],[46573,0,2],[46574,0,2],[46575,0,2],[46576,0,2],[46577,0,2],[46578,0,2],[46579,0,2],[46580,0,1],[46581,0,2],[46582,0,2],[46583,0,2],[46584,0,2],[46585,0,2],[46586,0,2],[46587,0,2],[46588,0,2],[46589,0,2],[46590,0,2],[46591,0,2],[46592,0,2],[46593,0,2],[46594,0,2],[46595,0,2],[46596,0,2],[46597,0,2],[46598,0,2],[46599,0,2],[46600,0,2],[46601,0,2],[46602,0,2],[46603,0,2],[46604,0,2],[46605,0,2],[46606,0,2],[46607,0,2],[46608,0,1],[46609,0,2],[46610,0,2],[46611,0,2],[46612,0,2],[46613,0,2],[46614,0,2],[46615,0,2],[46616,0,2],[46617,0,2],[46618,0,2],[46619,0,2],[46620,0,2],[46621,0,2],[46622,0,2],[46623,0,2],[46624,0,2],[46625,0,2],[46626,0,2],[46627,0,2],[46628,0,2],[46629,0,2],[46630,0,2],[46631,0,2],[46632,0,2],[46633,0,2],[46634,0,2],[46635,0,2],[46636,0,1],[46637,0,2],[46638,0,2],[46639,0,2],[46640,0,2],[46641,0,2],[46642,0,2],[46643,0,2],[46644,0,2],[46645,0,2],[46646,0,2],[46647,0,2],[46648,0,2],[46649,0,2],[46650,0,2],[46651,0,2],[46652,0,2],[46653,0,2],[46654,0,2],[46655,0,2],[46656,0,2],[46657,0,2],[46658,0,2],[46659,0,2],[46660,0,2],[46661,0,2],[46662,0,2],[46663,0,2],[46664,0,1],[46665,0,2],[46666,0,2],[46667,0,2],[46668,0,2],[46669,0,2],[46670,0,2],[46671,0,2],[46672,0,2],[46673,0,2],[46674,0,2],[46675,0,2],[46676,0,2],[46677,0,2],[46678,0,2],[46679,0,2],[46680,0,2],[46681,0,2],[46682,0,2],[46683,0,2],[46684,0,2],[46685,0,2],[46686,0,2],[46687,0,2],[46688,0,2],[46689,0,2],[46690,0,2],[46691,0,2],[46692,0,1],[46693,0,2],[46694,0,2],[46695,0,2],[46696,0,2],[46697,0,2],[46698,0,2],[46699,0,2],[46700,0,2],[46701,0,2],[46702,0,2],[46703,0,2],[46704,0,2],[46705,0,2],[46706,0,2],[46707,0,2],[46708,0,2],[46709,0,2],[46710,0,2],[46711,0,2],[46712,0,2],[46713,0,2],[46714,0,2],[46715,0,2],[46716,0,2],[46717,0,2],[46718,0,2],[46719,0,2],[46720,0,1],[46721,0,2],[46722,0,2],[46723,0,2],[46724,0,2],[46725,0,2],[46726,0,2],[46727,0,2],[46728,0,2],[46729,0,2],[46730,0,2],[46731,0,2],[46732,0,2],[46733,0,2],[46734,0,2],[46735,0,2],[46736,0,2],[46737,0,2],[46738,0,2],[46739,0,2],[46740,0,2],[46741,0,2],[46742,0,2],[46743,0,2],[46744,0,2],[46745,0,2],[46746,0,2],[46747,0,2],[46748,0,1],[46749,0,2],[46750,0,2],[46751,0,2],[46752,0,2],[46753,0,2],[46754,0,2],[46755,0,2],[46756,0,2],[46757,0,2],[46758,0,2],[46759,0,2],[46760,0,2],[46761,0,2],[46762,0,2],[46763,0,2],[46764,0,2],[46765,0,2],[46766,0,2],[46767,0,2],[46768,0,2],[46769,0,2],[46770,0,2],[46771,0,2],[46772,0,2],[46773,0,2],[46774,0,2],[46775,0,2],[46776,0,1],[46777,0,2],[46778,0,2],[46779,0,2],[46780,0,2],[46781,0,2],[46782,0,2],[46783,0,2],[46784,0,2],[46785,0,2],[46786,0,2],[46787,0,2],[46788,0,2],[46789,0,2],[46790,0,2],[46791,0,2],[46792,0,2],[46793,0,2],[46794,0,2],[46795,0,2],[46796,0,2],[46797,0,2],[46798,0,2],[46799,0,2],[46800,0,2],[46801,0,2],[46802,0,2],[46803,0,2],[46804,0,1],[46805,0,2],[46806,0,2],[46807,0,2],[46808,0,2],[46809,0,2],[46810,0,2],[46811,0,2],[46812,0,2],[46813,0,2],[46814,0,2],[46815,0,2],[46816,0,2],[46817,0,2],[46818,0,2],[46819,0,2],[46820,0,2],[46821,0,2],[46822,0,2],[46823,0,2],[46824,0,2],[46825,0,2],[46826,0,2],[46827,0,2],[46828,0,2],[46829,0,2],[46830,0,2],[46831,0,2],[46832,0,1],[46833,0,2],[46834,0,2],[46835,0,2],[46836,0,2],[46837,0,2],[46838,0,2],[46839,0,2],[46840,0,2],[46841,0,2],[46842,0,2],[46843,0,2],[46844,0,2],[46845,0,2],[46846,0,2],[46847,0,2],[46848,0,2],[46849,0,2],[46850,0,2],[46851,0,2],[46852,0,2],[46853,0,2],[46854,0,2],[46855,0,2],[46856,0,2],[46857,0,2],[46858,0,2],[46859,0,2],[46860,0,1],[46861,0,2],[46862,0,2],[46863,0,2],[46864,0,2],[46865,0,2],[46866,0,2],[46867,0,2],[46868,0,2],[46869,0,2],[46870,0,2],[46871,0,2],[46872,0,2],[46873,0,2],[46874,0,2],[46875,0,2],[46876,0,2],[46877,0,2],[46878,0,2],[46879,0,2],[46880,0,2],[46881,0,2],[46882,0,2],[46883,0,2],[46884,0,2],[46885,0,2],[46886,0,2],[46887,0,2],[46888,0,1],[46889,0,2],[46890,0,2],[46891,0,2],[46892,0,2],[46893,0,2],[46894,0,2],[46895,0,2],[46896,0,2],[46897,0,2],[46898,0,2],[46899,0,2],[46900,0,2],[46901,0,2],[46902,0,2],[46903,0,2],[46904,0,2],[46905,0,2],[46906,0,2],[46907,0,2],[46908,0,2],[46909,0,2],[46910,0,2],[46911,0,2],[46912,0,2],[46913,0,2],[46914,0,2],[46915,0,2],[46916,0,1],[46917,0,2],[46918,0,2],[46919,0,2],[46920,0,2],[46921,0,2],[46922,0,2],[46923,0,2],[46924,0,2],[46925,0,2],[46926,0,2],[46927,0,2],[46928,0,2],[46929,0,2],[46930,0,2],[46931,0,2],[46932,0,2],[46933,0,2],[46934,0,2],[46935,0,2],[46936,0,2],[46937,0,2],[46938,0,2],[46939,0,2],[46940,0,2],[46941,0,2],[46942,0,2],[46943,0,2],[46944,0,1],[46945,0,2],[46946,0,2],[46947,0,2],[46948,0,2],[46949,0,2],[46950,0,2],[46951,0,2],[46952,0,2],[46953,0,2],[46954,0,2],[46955,0,2],[46956,0,2],[46957,0,2],[46958,0,2],[46959,0,2],[46960,0,2],[46961,0,2],[46962,0,2],[46963,0,2],[46964,0,2],[46965,0,2],[46966,0,2],[46967,0,2],[46968,0,2],[46969,0,2],[46970,0,2],[46971,0,2],[46972,0,1],[46973,0,2],[46974,0,2],[46975,0,2],[46976,0,2],[46977,0,2],[46978,0,2],[46979,0,2],[46980,0,2],[46981,0,2],[46982,0,2],[46983,0,2],[46984,0,2],[46985,0,2],[46986,0,2],[46987,0,2],[46988,0,2],[46989,0,2],[46990,0,2],[46991,0,2],[46992,0,2],[46993,0,2],[46994,0,2],[46995,0,2],[46996,0,2],[46997,0,2],[46998,0,2],[46999,0,2],[47000,0,1],[47001,0,2],[47002,0,2],[47003,0,2],[47004,0,2],[47005,0,2],[47006,0,2],[47007,0,2],[47008,0,2],[47009,0,2],[47010,0,2],[47011,0,2],[47012,0,2],[47013,0,2],[47014,0,2],[47015,0,2],[47016,0,2],[47017,0,2],[47018,0,2],[47019,0,2],[47020,0,2],[47021,0,2],[47022,0,2],[47023,0,2],[47024,0,2],[47025,0,2],[47026,0,2],[47027,0,2],[47028,0,1],[47029,0,2],[47030,0,2],[47031,0,2],[47032,0,2],[47033,0,2],[47034,0,2],[47035,0,2],[47036,0,2],[47037,0,2],[47038,0,2],[47039,0,2],[47040,0,2],[47041,0,2],[47042,0,2],[47043,0,2],[47044,0,2],[47045,0,2],[47046,0,2],[47047,0,2],[47048,0,2],[47049,0,2],[47050,0,2],[47051,0,2],[47052,0,2],[47053,0,2],[47054,0,2],[47055,0,2],[47056,0,1],[47057,0,2],[47058,0,2],[47059,0,2],[47060,0,2],[47061,0,2],[47062,0,2],[47063,0,2],[47064,0,2],[47065,0,2],[47066,0,2],[47067,0,2],[47068,0,2],[47069,0,2],[47070,0,2],[47071,0,2],[47072,0,2],[47073,0,2],[47074,0,2],[47075,0,2],[47076,0,2],[47077,0,2],[47078,0,2],[47079,0,2],[47080,0,2],[47081,0,2],[47082,0,2],[47083,0,2],[47084,0,1],[47085,0,2],[47086,0,2],[47087,0,2],[47088,0,2],[47089,0,2],[47090,0,2],[47091,0,2],[47092,0,2],[47093,0,2],[47094,0,2],[47095,0,2],[47096,0,2],[47097,0,2],[47098,0,2],[47099,0,2],[47100,0,2],[47101,0,2],[47102,0,2],[47103,0,2],[47104,0,2],[47105,0,2],[47106,0,2],[47107,0,2],[47108,0,2],[47109,0,2],[47110,0,2],[47111,0,2],[47112,0,1],[47113,0,2],[47114,0,2],[47115,0,2],[47116,0,2],[47117,0,2],[47118,0,2],[47119,0,2],[47120,0,2],[47121,0,2],[47122,0,2],[47123,0,2],[47124,0,2],[47125,0,2],[47126,0,2],[47127,0,2],[47128,0,2],[47129,0,2],[47130,0,2],[47131,0,2],[47132,0,2],[47133,0,2],[47134,0,2],[47135,0,2],[47136,0,2],[47137,0,2],[47138,0,2],[47139,0,2],[47140,0,1],[47141,0,2],[47142,0,2],[47143,0,2],[47144,0,2],[47145,0,2],[47146,0,2],[47147,0,2],[47148,0,2],[47149,0,2],[47150,0,2],[47151,0,2],[47152,0,2],[47153,0,2],[47154,0,2],[47155,0,2],[47156,0,2],[47157,0,2],[47158,0,2],[47159,0,2],[47160,0,2],[47161,0,2],[47162,0,2],[47163,0,2],[47164,0,2],[47165,0,2],[47166,0,2],[47167,0,2],[47168,0,1],[47169,0,2],[47170,0,2],[47171,0,2],[47172,0,2],[47173,0,2],[47174,0,2],[47175,0,2],[47176,0,2],[47177,0,2],[47178,0,2],[47179,0,2],[47180,0,2],[47181,0,2],[47182,0,2],[47183,0,2],[47184,0,2],[47185,0,2],[47186,0,2],[47187,0,2],[47188,0,2],[47189,0,2],[47190,0,2],[47191,0,2],[47192,0,2],[47193,0,2],[47194,0,2],[47195,0,2],[47196,0,1],[47197,0,2],[47198,0,2],[47199,0,2],[47200,0,2],[47201,0,2],[47202,0,2],[47203,0,2],[47204,0,2],[47205,0,2],[47206,0,2],[47207,0,2],[47208,0,2],[47209,0,2],[47210,0,2],[47211,0,2],[47212,0,2],[47213,0,2],[47214,0,2],[47215,0,2],[47216,0,2],[47217,0,2],[47218,0,2],[47219,0,2],[47220,0,2],[47221,0,2],[47222,0,2],[47223,0,2],[47224,0,1],[47225,0,2],[47226,0,2],[47227,0,2],[47228,0,2],[47229,0,2],[47230,0,2],[47231,0,2],[47232,0,2],[47233,0,2],[47234,0,2],[47235,0,2],[47236,0,2],[47237,0,2],[47238,0,2],[47239,0,2],[47240,0,2],[47241,0,2],[47242,0,2],[47243,0,2],[47244,0,2],[47245,0,2],[47246,0,2],[47247,0,2],[47248,0,2],[47249,0,2],[47250,0,2],[47251,0,2],[47252,0,1],[47253,0,2],[47254,0,2],[47255,0,2],[47256,0,2],[47257,0,2],[47258,0,2],[47259,0,2],[47260,0,2],[47261,0,2],[47262,0,2],[47263,0,2],[47264,0,2],[47265,0,2],[47266,0,2],[47267,0,2],[47268,0,2],[47269,0,2],[47270,0,2],[47271,0,2],[47272,0,2],[47273,0,2],[47274,0,2],[47275,0,2],[47276,0,2],[47277,0,2],[47278,0,2],[47279,0,2],[47280,0,1],[47281,0,2],[47282,0,2],[47283,0,2],[47284,0,2],[47285,0,2],[47286,0,2],[47287,0,2],[47288,0,2],[47289,0,2],[47290,0,2],[47291,0,2],[47292,0,2],[47293,0,2],[47294,0,2],[47295,0,2],[47296,0,2],[47297,0,2],[47298,0,2],[47299,0,2],[47300,0,2],[47301,0,2],[47302,0,2],[47303,0,2],[47304,0,2],[47305,0,2],[47306,0,2],[47307,0,2],[47308,0,1],[47309,0,2],[47310,0,2],[47311,0,2],[47312,0,2],[47313,0,2],[47314,0,2],[47315,0,2],[47316,0,2],[47317,0,2],[47318,0,2],[47319,0,2],[47320,0,2],[47321,0,2],[47322,0,2],[47323,0,2],[47324,0,2],[47325,0,2],[47326,0,2],[47327,0,2],[47328,0,2],[47329,0,2],[47330,0,2],[47331,0,2],[47332,0,2],[47333,0,2],[47334,0,2],[47335,0,2],[47336,0,1],[47337,0,2],[47338,0,2],[47339,0,2],[47340,0,2],[47341,0,2],[47342,0,2],[47343,0,2],[47344,0,2],[47345,0,2],[47346,0,2],[47347,0,2],[47348,0,2],[47349,0,2],[47350,0,2],[47351,0,2],[47352,0,2],[47353,0,2],[47354,0,2],[47355,0,2],[47356,0,2],[47357,0,2],[47358,0,2],[47359,0,2],[47360,0,2],[47361,0,2],[47362,0,2],[47363,0,2],[47364,0,1],[47365,0,2],[47366,0,2],[47367,0,2],[47368,0,2],[47369,0,2],[47370,0,2],[47371,0,2],[47372,0,2],[47373,0,2],[47374,0,2],[47375,0,2],[47376,0,2],[47377,0,2],[47378,0,2],[47379,0,2],[47380,0,2],[47381,0,2],[47382,0,2],[47383,0,2],[47384,0,2],[47385,0,2],[47386,0,2],[47387,0,2],[47388,0,2],[47389,0,2],[47390,0,2],[47391,0,2],[47392,0,1],[47393,0,2],[47394,0,2],[47395,0,2],[47396,0,2],[47397,0,2],[47398,0,2],[47399,0,2],[47400,0,2],[47401,0,2],[47402,0,2],[47403,0,2],[47404,0,2],[47405,0,2],[47406,0,2],[47407,0,2],[47408,0,2],[47409,0,2],[47410,0,2],[47411,0,2],[47412,0,2],[47413,0,2],[47414,0,2],[47415,0,2],[47416,0,2],[47417,0,2],[47418,0,2],[47419,0,2],[47420,0,1],[47421,0,2],[47422,0,2],[47423,0,2],[47424,0,2],[47425,0,2],[47426,0,2],[47427,0,2],[47428,0,2],[47429,0,2],[47430,0,2],[47431,0,2],[47432,0,2],[47433,0,2],[47434,0,2],[47435,0,2],[47436,0,2],[47437,0,2],[47438,0,2],[47439,0,2],[47440,0,2],[47441,0,2],[47442,0,2],[47443,0,2],[47444,0,2],[47445,0,2],[47446,0,2],[47447,0,2],[47448,0,1],[47449,0,2],[47450,0,2],[47451,0,2],[47452,0,2],[47453,0,2],[47454,0,2],[47455,0,2],[47456,0,2],[47457,0,2],[47458,0,2],[47459,0,2],[47460,0,2],[47461,0,2],[47462,0,2],[47463,0,2],[47464,0,2],[47465,0,2],[47466,0,2],[47467,0,2],[47468,0,2],[47469,0,2],[47470,0,2],[47471,0,2],[47472,0,2],[47473,0,2],[47474,0,2],[47475,0,2],[47476,0,1],[47477,0,2],[47478,0,2],[47479,0,2],[47480,0,2],[47481,0,2],[47482,0,2],[47483,0,2],[47484,0,2],[47485,0,2],[47486,0,2],[47487,0,2],[47488,0,2],[47489,0,2],[47490,0,2],[47491,0,2],[47492,0,2],[47493,0,2],[47494,0,2],[47495,0,2],[47496,0,2],[47497,0,2],[47498,0,2],[47499,0,2],[47500,0,2],[47501,0,2],[47502,0,2],[47503,0,2],[47504,0,1],[47505,0,2],[47506,0,2],[47507,0,2],[47508,0,2],[47509,0,2],[47510,0,2],[47511,0,2],[47512,0,2],[47513,0,2],[47514,0,2],[47515,0,2],[47516,0,2],[47517,0,2],[47518,0,2],[47519,0,2],[47520,0,2],[47521,0,2],[47522,0,2],[47523,0,2],[47524,0,2],[47525,0,2],[47526,0,2],[47527,0,2],[47528,0,2],[47529,0,2],[47530,0,2],[47531,0,2],[47532,0,1],[47533,0,2],[47534,0,2],[47535,0,2],[47536,0,2],[47537,0,2],[47538,0,2],[47539,0,2],[47540,0,2],[47541,0,2],[47542,0,2],[47543,0,2],[47544,0,2],[47545,0,2],[47546,0,2],[47547,0,2],[47548,0,2],[47549,0,2],[47550,0,2],[47551,0,2],[47552,0,2],[47553,0,2],[47554,0,2],[47555,0,2],[47556,0,2],[47557,0,2],[47558,0,2],[47559,0,2],[47560,0,1],[47561,0,2],[47562,0,2],[47563,0,2],[47564,0,2],[47565,0,2],[47566,0,2],[47567,0,2],[47568,0,2],[47569,0,2],[47570,0,2],[47571,0,2],[47572,0,2],[47573,0,2],[47574,0,2],[47575,0,2],[47576,0,2],[47577,0,2],[47578,0,2],[47579,0,2],[47580,0,2],[47581,0,2],[47582,0,2],[47583,0,2],[47584,0,2],[47585,0,2],[47586,0,2],[47587,0,2],[47588,0,1],[47589,0,2],[47590,0,2],[47591,0,2],[47592,0,2],[47593,0,2],[47594,0,2],[47595,0,2],[47596,0,2],[47597,0,2],[47598,0,2],[47599,0,2],[47600,0,2],[47601,0,2],[47602,0,2],[47603,0,2],[47604,0,2],[47605,0,2],[47606,0,2],[47607,0,2],[47608,0,2],[47609,0,2],[47610,0,2],[47611,0,2],[47612,0,2],[47613,0,2],[47614,0,2],[47615,0,2],[47616,0,1],[47617,0,2],[47618,0,2],[47619,0,2],[47620,0,2],[47621,0,2],[47622,0,2],[47623,0,2],[47624,0,2],[47625,0,2],[47626,0,2],[47627,0,2],[47628,0,2],[47629,0,2],[47630,0,2],[47631,0,2],[47632,0,2],[47633,0,2],[47634,0,2],[47635,0,2],[47636,0,2],[47637,0,2],[47638,0,2],[47639,0,2],[47640,0,2],[47641,0,2],[47642,0,2],[47643,0,2],[47644,0,1],[47645,0,2],[47646,0,2],[47647,0,2],[47648,0,2],[47649,0,2],[47650,0,2],[47651,0,2],[47652,0,2],[47653,0,2],[47654,0,2],[47655,0,2],[47656,0,2],[47657,0,2],[47658,0,2],[47659,0,2],[47660,0,2],[47661,0,2],[47662,0,2],[47663,0,2],[47664,0,2],[47665,0,2],[47666,0,2],[47667,0,2],[47668,0,2],[47669,0,2],[47670,0,2],[47671,0,2],[47672,0,1],[47673,0,2],[47674,0,2],[47675,0,2],[47676,0,2],[47677,0,2],[47678,0,2],[47679,0,2],[47680,0,2],[47681,0,2],[47682,0,2],[47683,0,2],[47684,0,2],[47685,0,2],[47686,0,2],[47687,0,2],[47688,0,2],[47689,0,2],[47690,0,2],[47691,0,2],[47692,0,2],[47693,0,2],[47694,0,2],[47695,0,2],[47696,0,2],[47697,0,2],[47698,0,2],[47699,0,2],[47700,0,1],[47701,0,2],[47702,0,2],[47703,0,2],[47704,0,2],[47705,0,2],[47706,0,2],[47707,0,2],[47708,0,2],[47709,0,2],[47710,0,2],[47711,0,2],[47712,0,2],[47713,0,2],[47714,0,2],[47715,0,2],[47716,0,2],[47717,0,2],[47718,0,2],[47719,0,2],[47720,0,2],[47721,0,2],[47722,0,2],[47723,0,2],[47724,0,2],[47725,0,2],[47726,0,2],[47727,0,2],[47728,0,1],[47729,0,2],[47730,0,2],[47731,0,2],[47732,0,2],[47733,0,2],[47734,0,2],[47735,0,2],[47736,0,2],[47737,0,2],[47738,0,2],[47739,0,2],[47740,0,2],[47741,0,2],[47742,0,2],[47743,0,2],[47744,0,2],[47745,0,2],[47746,0,2],[47747,0,2],[47748,0,2],[47749,0,2],[47750,0,2],[47751,0,2],[47752,0,2],[47753,0,2],[47754,0,2],[47755,0,2],[47756,0,1],[47757,0,2],[47758,0,2],[47759,0,2],[47760,0,2],[47761,0,2],[47762,0,2],[47763,0,2],[47764,0,2],[47765,0,2],[47766,0,2],[47767,0,2],[47768,0,2],[47769,0,2],[47770,0,2],[47771,0,2],[47772,0,2],[47773,0,2],[47774,0,2],[47775,0,2],[47776,0,2],[47777,0,2],[47778,0,2],[47779,0,2],[47780,0,2],[47781,0,2],[47782,0,2],[47783,0,2],[47784,0,1],[47785,0,2],[47786,0,2],[47787,0,2],[47788,0,2],[47789,0,2],[47790,0,2],[47791,0,2],[47792,0,2],[47793,0,2],[47794,0,2],[47795,0,2],[47796,0,2],[47797,0,2],[47798,0,2],[47799,0,2],[47800,0,2],[47801,0,2],[47802,0,2],[47803,0,2],[47804,0,2],[47805,0,2],[47806,0,2],[47807,0,2],[47808,0,2],[47809,0,2],[47810,0,2],[47811,0,2],[47812,0,1],[47813,0,2],[47814,0,2],[47815,0,2],[47816,0,2],[47817,0,2],[47818,0,2],[47819,0,2],[47820,0,2],[47821,0,2],[47822,0,2],[47823,0,2],[47824,0,2],[47825,0,2],[47826,0,2],[47827,0,2],[47828,0,2],[47829,0,2],[47830,0,2],[47831,0,2],[47832,0,2],[47833,0,2],[47834,0,2],[47835,0,2],[47836,0,2],[47837,0,2],[47838,0,2],[47839,0,2],[47840,0,1],[47841,0,2],[47842,0,2],[47843,0,2],[47844,0,2],[47845,0,2],[47846,0,2],[47847,0,2],[47848,0,2],[47849,0,2],[47850,0,2],[47851,0,2],[47852,0,2],[47853,0,2],[47854,0,2],[47855,0,2],[47856,0,2],[47857,0,2],[47858,0,2],[47859,0,2],[47860,0,2],[47861,0,2],[47862,0,2],[47863,0,2],[47864,0,2],[47865,0,2],[47866,0,2],[47867,0,2],[47868,0,1],[47869,0,2],[47870,0,2],[47871,0,2],[47872,0,2],[47873,0,2],[47874,0,2],[47875,0,2],[47876,0,2],[47877,0,2],[47878,0,2],[47879,0,2],[47880,0,2],[47881,0,2],[47882,0,2],[47883,0,2],[47884,0,2],[47885,0,2],[47886,0,2],[47887,0,2],[47888,0,2],[47889,0,2],[47890,0,2],[47891,0,2],[47892,0,2],[47893,0,2],[47894,0,2],[47895,0,2],[47896,0,1],[47897,0,2],[47898,0,2],[47899,0,2],[47900,0,2],[47901,0,2],[47902,0,2],[47903,0,2],[47904,0,2],[47905,0,2],[47906,0,2],[47907,0,2],[47908,0,2],[47909,0,2],[47910,0,2],[47911,0,2],[47912,0,2],[47913,0,2],[47914,0,2],[47915,0,2],[47916,0,2],[47917,0,2],[47918,0,2],[47919,0,2],[47920,0,2],[47921,0,2],[47922,0,2],[47923,0,2],[47924,0,1],[47925,0,2],[47926,0,2],[47927,0,2],[47928,0,2],[47929,0,2],[47930,0,2],[47931,0,2],[47932,0,2],[47933,0,2],[47934,0,2],[47935,0,2],[47936,0,2],[47937,0,2],[47938,0,2],[47939,0,2],[47940,0,2],[47941,0,2],[47942,0,2],[47943,0,2],[47944,0,2],[47945,0,2],[47946,0,2],[47947,0,2],[47948,0,2],[47949,0,2],[47950,0,2],[47951,0,2],[47952,0,1],[47953,0,2],[47954,0,2],[47955,0,2],[47956,0,2],[47957,0,2],[47958,0,2],[47959,0,2],[47960,0,2],[47961,0,2],[47962,0,2],[47963,0,2],[47964,0,2],[47965,0,2],[47966,0,2],[47967,0,2],[47968,0,2],[47969,0,2],[47970,0,2],[47971,0,2],[47972,0,2],[47973,0,2],[47974,0,2],[47975,0,2],[47976,0,2],[47977,0,2],[47978,0,2],[47979,0,2],[47980,0,1],[47981,0,2],[47982,0,2],[47983,0,2],[47984,0,2],[47985,0,2],[47986,0,2],[47987,0,2],[47988,0,2],[47989,0,2],[47990,0,2],[47991,0,2],[47992,0,2],[47993,0,2],[47994,0,2],[47995,0,2],[47996,0,2],[47997,0,2],[47998,0,2],[47999,0,2],[48000,0,2],[48001,0,2],[48002,0,2],[48003,0,2],[48004,0,2],[48005,0,2],[48006,0,2],[48007,0,2],[48008,0,1],[48009,0,2],[48010,0,2],[48011,0,2],[48012,0,2],[48013,0,2],[48014,0,2],[48015,0,2],[48016,0,2],[48017,0,2],[48018,0,2],[48019,0,2],[48020,0,2],[48021,0,2],[48022,0,2],[48023,0,2],[48024,0,2],[48025,0,2],[48026,0,2],[48027,0,2],[48028,0,2],[48029,0,2],[48030,0,2],[48031,0,2],[48032,0,2],[48033,0,2],[48034,0,2],[48035,0,2],[48036,0,1],[48037,0,2],[48038,0,2],[48039,0,2],[48040,0,2],[48041,0,2],[48042,0,2],[48043,0,2],[48044,0,2],[48045,0,2],[48046,0,2],[48047,0,2],[48048,0,2],[48049,0,2],[48050,0,2],[48051,0,2],[48052,0,2],[48053,0,2],[48054,0,2],[48055,0,2],[48056,0,2],[48057,0,2],[48058,0,2],[48059,0,2],[48060,0,2],[48061,0,2],[48062,0,2],[48063,0,2],[48064,0,1],[48065,0,2],[48066,0,2],[48067,0,2],[48068,0,2],[48069,0,2],[48070,0,2],[48071,0,2],[48072,0,2],[48073,0,2],[48074,0,2],[48075,0,2],[48076,0,2],[48077,0,2],[48078,0,2],[48079,0,2],[48080,0,2],[48081,0,2],[48082,0,2],[48083,0,2],[48084,0,2],[48085,0,2],[48086,0,2],[48087,0,2],[48088,0,2],[48089,0,2],[48090,0,2],[48091,0,2],[48092,0,1],[48093,0,2],[48094,0,2],[48095,0,2],[48096,0,2],[48097,0,2],[48098,0,2],[48099,0,2],[48100,0,2],[48101,0,2],[48102,0,2],[48103,0,2],[48104,0,2],[48105,0,2],[48106,0,2],[48107,0,2],[48108,0,2],[48109,0,2],[48110,0,2],[48111,0,2],[48112,0,2],[48113,0,2],[48114,0,2],[48115,0,2],[48116,0,2],[48117,0,2],[48118,0,2],[48119,0,2],[48120,0,1],[48121,0,2],[48122,0,2],[48123,0,2],[48124,0,2],[48125,0,2],[48126,0,2],[48127,0,2],[48128,0,2],[48129,0,2],[48130,0,2],[48131,0,2],[48132,0,2],[48133,0,2],[48134,0,2],[48135,0,2],[48136,0,2],[48137,0,2],[48138,0,2],[48139,0,2],[48140,0,2],[48141,0,2],[48142,0,2],[48143,0,2],[48144,0,2],[48145,0,2],[48146,0,2],[48147,0,2],[48148,0,1],[48149,0,2],[48150,0,2],[48151,0,2],[48152,0,2],[48153,0,2],[48154,0,2],[48155,0,2],[48156,0,2],[48157,0,2],[48158,0,2],[48159,0,2],[48160,0,2],[48161,0,2],[48162,0,2],[48163,0,2],[48164,0,2],[48165,0,2],[48166,0,2],[48167,0,2],[48168,0,2],[48169,0,2],[48170,0,2],[48171,0,2],[48172,0,2],[48173,0,2],[48174,0,2],[48175,0,2],[48176,0,1],[48177,0,2],[48178,0,2],[48179,0,2],[48180,0,2],[48181,0,2],[48182,0,2],[48183,0,2],[48184,0,2],[48185,0,2],[48186,0,2],[48187,0,2],[48188,0,2],[48189,0,2],[48190,0,2],[48191,0,2],[48192,0,2],[48193,0,2],[48194,0,2],[48195,0,2],[48196,0,2],[48197,0,2],[48198,0,2],[48199,0,2],[48200,0,2],[48201,0,2],[48202,0,2],[48203,0,2],[48204,0,1],[48205,0,2],[48206,0,2],[48207,0,2],[48208,0,2],[48209,0,2],[48210,0,2],[48211,0,2],[48212,0,2],[48213,0,2],[48214,0,2],[48215,0,2],[48216,0,2],[48217,0,2],[48218,0,2],[48219,0,2],[48220,0,2],[48221,0,2],[48222,0,2],[48223,0,2],[48224,0,2],[48225,0,2],[48226,0,2],[48227,0,2],[48228,0,2],[48229,0,2],[48230,0,2],[48231,0,2],[48232,0,1],[48233,0,2],[48234,0,2],[48235,0,2],[48236,0,2],[48237,0,2],[48238,0,2],[48239,0,2],[48240,0,2],[48241,0,2],[48242,0,2],[48243,0,2],[48244,0,2],[48245,0,2],[48246,0,2],[48247,0,2],[48248,0,2],[48249,0,2],[48250,0,2],[48251,0,2],[48252,0,2],[48253,0,2],[48254,0,2],[48255,0,2],[48256,0,2],[48257,0,2],[48258,0,2],[48259,0,2],[48260,0,1],[48261,0,2],[48262,0,2],[48263,0,2],[48264,0,2],[48265,0,2],[48266,0,2],[48267,0,2],[48268,0,2],[48269,0,2],[48270,0,2],[48271,0,2],[48272,0,2],[48273,0,2],[48274,0,2],[48275,0,2],[48276,0,2],[48277,0,2],[48278,0,2],[48279,0,2],[48280,0,2],[48281,0,2],[48282,0,2],[48283,0,2],[48284,0,2],[48285,0,2],[48286,0,2],[48287,0,2],[48288,0,1],[48289,0,2],[48290,0,2],[48291,0,2],[48292,0,2],[48293,0,2],[48294,0,2],[48295,0,2],[48296,0,2],[48297,0,2],[48298,0,2],[48299,0,2],[48300,0,2],[48301,0,2],[48302,0,2],[48303,0,2],[48304,0,2],[48305,0,2],[48306,0,2],[48307,0,2],[48308,0,2],[48309,0,2],[48310,0,2],[48311,0,2],[48312,0,2],[48313,0,2],[48314,0,2],[48315,0,2],[48316,0,1],[48317,0,2],[48318,0,2],[48319,0,2],[48320,0,2],[48321,0,2],[48322,0,2],[48323,0,2],[48324,0,2],[48325,0,2],[48326,0,2],[48327,0,2],[48328,0,2],[48329,0,2],[48330,0,2],[48331,0,2],[48332,0,2],[48333,0,2],[48334,0,2],[48335,0,2],[48336,0,2],[48337,0,2],[48338,0,2],[48339,0,2],[48340,0,2],[48341,0,2],[48342,0,2],[48343,0,2],[48344,0,1],[48345,0,2],[48346,0,2],[48347,0,2],[48348,0,2],[48349,0,2],[48350,0,2],[48351,0,2],[48352,0,2],[48353,0,2],[48354,0,2],[48355,0,2],[48356,0,2],[48357,0,2],[48358,0,2],[48359,0,2],[48360,0,2],[48361,0,2],[48362,0,2],[48363,0,2],[48364,0,2],[48365,0,2],[48366,0,2],[48367,0,2],[48368,0,2],[48369,0,2],[48370,0,2],[48371,0,2],[48372,0,1],[48373,0,2],[48374,0,2],[48375,0,2],[48376,0,2],[48377,0,2],[48378,0,2],[48379,0,2],[48380,0,2],[48381,0,2],[48382,0,2],[48383,0,2],[48384,0,2],[48385,0,2],[48386,0,2],[48387,0,2],[48388,0,2],[48389,0,2],[48390,0,2],[48391,0,2],[48392,0,2],[48393,0,2],[48394,0,2],[48395,0,2],[48396,0,2],[48397,0,2],[48398,0,2],[48399,0,2],[48400,0,1],[48401,0,2],[48402,0,2],[48403,0,2],[48404,0,2],[48405,0,2],[48406,0,2],[48407,0,2],[48408,0,2],[48409,0,2],[48410,0,2],[48411,0,2],[48412,0,2],[48413,0,2],[48414,0,2],[48415,0,2],[48416,0,2],[48417,0,2],[48418,0,2],[48419,0,2],[48420,0,2],[48421,0,2],[48422,0,2],[48423,0,2],[48424,0,2],[48425,0,2],[48426,0,2],[48427,0,2],[48428,0,1],[48429,0,2],[48430,0,2],[48431,0,2],[48432,0,2],[48433,0,2],[48434,0,2],[48435,0,2],[48436,0,2],[48437,0,2],[48438,0,2],[48439,0,2],[48440,0,2],[48441,0,2],[48442,0,2],[48443,0,2],[48444,0,2],[48445,0,2],[48446,0,2],[48447,0,2],[48448,0,2],[48449,0,2],[48450,0,2],[48451,0,2],[48452,0,2],[48453,0,2],[48454,0,2],[48455,0,2],[48456,0,1],[48457,0,2],[48458,0,2],[48459,0,2],[48460,0,2],[48461,0,2],[48462,0,2],[48463,0,2],[48464,0,2],[48465,0,2],[48466,0,2],[48467,0,2],[48468,0,2],[48469,0,2],[48470,0,2],[48471,0,2],[48472,0,2],[48473,0,2],[48474,0,2],[48475,0,2],[48476,0,2],[48477,0,2],[48478,0,2],[48479,0,2],[48480,0,2],[48481,0,2],[48482,0,2],[48483,0,2],[48484,0,1],[48485,0,2],[48486,0,2],[48487,0,2],[48488,0,2],[48489,0,2],[48490,0,2],[48491,0,2],[48492,0,2],[48493,0,2],[48494,0,2],[48495,0,2],[48496,0,2],[48497,0,2],[48498,0,2],[48499,0,2],[48500,0,2],[48501,0,2],[48502,0,2],[48503,0,2],[48504,0,2],[48505,0,2],[48506,0,2],[48507,0,2],[48508,0,2],[48509,0,2],[48510,0,2],[48511,0,2],[48512,0,1],[48513,0,2],[48514,0,2],[48515,0,2],[48516,0,2],[48517,0,2],[48518,0,2],[48519,0,2],[48520,0,2],[48521,0,2],[48522,0,2],[48523,0,2],[48524,0,2],[48525,0,2],[48526,0,2],[48527,0,2],[48528,0,2],[48529,0,2],[48530,0,2],[48531,0,2],[48532,0,2],[48533,0,2],[48534,0,2],[48535,0,2],[48536,0,2],[48537,0,2],[48538,0,2],[48539,0,2],[48540,0,1],[48541,0,2],[48542,0,2],[48543,0,2],[48544,0,2],[48545,0,2],[48546,0,2],[48547,0,2],[48548,0,2],[48549,0,2],[48550,0,2],[48551,0,2],[48552,0,2],[48553,0,2],[48554,0,2],[48555,0,2],[48556,0,2],[48557,0,2],[48558,0,2],[48559,0,2],[48560,0,2],[48561,0,2],[48562,0,2],[48563,0,2],[48564,0,2],[48565,0,2],[48566,0,2],[48567,0,2],[48568,0,1],[48569,0,2],[48570,0,2],[48571,0,2],[48572,0,2],[48573,0,2],[48574,0,2],[48575,0,2],[48576,0,2],[48577,0,2],[48578,0,2],[48579,0,2],[48580,0,2],[48581,0,2],[48582,0,2],[48583,0,2],[48584,0,2],[48585,0,2],[48586,0,2],[48587,0,2],[48588,0,2],[48589,0,2],[48590,0,2],[48591,0,2],[48592,0,2],[48593,0,2],[48594,0,2],[48595,0,2],[48596,0,1],[48597,0,2],[48598,0,2],[48599,0,2],[48600,0,2],[48601,0,2],[48602,0,2],[48603,0,2],[48604,0,2],[48605,0,2],[48606,0,2],[48607,0,2],[48608,0,2],[48609,0,2],[48610,0,2],[48611,0,2],[48612,0,2],[48613,0,2],[48614,0,2],[48615,0,2],[48616,0,2],[48617,0,2],[48618,0,2],[48619,0,2],[48620,0,2],[48621,0,2],[48622,0,2],[48623,0,2],[48624,0,1],[48625,0,2],[48626,0,2],[48627,0,2],[48628,0,2],[48629,0,2],[48630,0,2],[48631,0,2],[48632,0,2],[48633,0,2],[48634,0,2],[48635,0,2],[48636,0,2],[48637,0,2],[48638,0,2],[48639,0,2],[48640,0,2],[48641,0,2],[48642,0,2],[48643,0,2],[48644,0,2],[48645,0,2],[48646,0,2],[48647,0,2],[48648,0,2],[48649,0,2],[48650,0,2],[48651,0,2],[48652,0,1],[48653,0,2],[48654,0,2],[48655,0,2],[48656,0,2],[48657,0,2],[48658,0,2],[48659,0,2],[48660,0,2],[48661,0,2],[48662,0,2],[48663,0,2],[48664,0,2],[48665,0,2],[48666,0,2],[48667,0,2],[48668,0,2],[48669,0,2],[48670,0,2],[48671,0,2],[48672,0,2],[48673,0,2],[48674,0,2],[48675,0,2],[48676,0,2],[48677,0,2],[48678,0,2],[48679,0,2],[48680,0,1],[48681,0,2],[48682,0,2],[48683,0,2],[48684,0,2],[48685,0,2],[48686,0,2],[48687,0,2],[48688,0,2],[48689,0,2],[48690,0,2],[48691,0,2],[48692,0,2],[48693,0,2],[48694,0,2],[48695,0,2],[48696,0,2],[48697,0,2],[48698,0,2],[48699,0,2],[48700,0,2],[48701,0,2],[48702,0,2],[48703,0,2],[48704,0,2],[48705,0,2],[48706,0,2],[48707,0,2],[48708,0,1],[48709,0,2],[48710,0,2],[48711,0,2],[48712,0,2],[48713,0,2],[48714,0,2],[48715,0,2],[48716,0,2],[48717,0,2],[48718,0,2],[48719,0,2],[48720,0,2],[48721,0,2],[48722,0,2],[48723,0,2],[48724,0,2],[48725,0,2],[48726,0,2],[48727,0,2],[48728,0,2],[48729,0,2],[48730,0,2],[48731,0,2],[48732,0,2],[48733,0,2],[48734,0,2],[48735,0,2],[48736,0,1],[48737,0,2],[48738,0,2],[48739,0,2],[48740,0,2],[48741,0,2],[48742,0,2],[48743,0,2],[48744,0,2],[48745,0,2],[48746,0,2],[48747,0,2],[48748,0,2],[48749,0,2],[48750,0,2],[48751,0,2],[48752,0,2],[48753,0,2],[48754,0,2],[48755,0,2],[48756,0,2],[48757,0,2],[48758,0,2],[48759,0,2],[48760,0,2],[48761,0,2],[48762,0,2],[48763,0,2],[48764,0,1],[48765,0,2],[48766,0,2],[48767,0,2],[48768,0,2],[48769,0,2],[48770,0,2],[48771,0,2],[48772,0,2],[48773,0,2],[48774,0,2],[48775,0,2],[48776,0,2],[48777,0,2],[48778,0,2],[48779,0,2],[48780,0,2],[48781,0,2],[48782,0,2],[48783,0,2],[48784,0,2],[48785,0,2],[48786,0,2],[48787,0,2],[48788,0,2],[48789,0,2],[48790,0,2],[48791,0,2],[48792,0,1],[48793,0,2],[48794,0,2],[48795,0,2],[48796,0,2],[48797,0,2],[48798,0,2],[48799,0,2],[48800,0,2],[48801,0,2],[48802,0,2],[48803,0,2],[48804,0,2],[48805,0,2],[48806,0,2],[48807,0,2],[48808,0,2],[48809,0,2],[48810,0,2],[48811,0,2],[48812,0,2],[48813,0,2],[48814,0,2],[48815,0,2],[48816,0,2],[48817,0,2],[48818,0,2],[48819,0,2],[48820,0,1],[48821,0,2],[48822,0,2],[48823,0,2],[48824,0,2],[48825,0,2],[48826,0,2],[48827,0,2],[48828,0,2],[48829,0,2],[48830,0,2],[48831,0,2],[48832,0,2],[48833,0,2],[48834,0,2],[48835,0,2],[48836,0,2],[48837,0,2],[48838,0,2],[48839,0,2],[48840,0,2],[48841,0,2],[48842,0,2],[48843,0,2],[48844,0,2],[48845,0,2],[48846,0,2],[48847,0,2],[48848,0,1],[48849,0,2],[48850,0,2],[48851,0,2],[48852,0,2],[48853,0,2],[48854,0,2],[48855,0,2],[48856,0,2],[48857,0,2],[48858,0,2],[48859,0,2],[48860,0,2],[48861,0,2],[48862,0,2],[48863,0,2],[48864,0,2],[48865,0,2],[48866,0,2],[48867,0,2],[48868,0,2],[48869,0,2],[48870,0,2],[48871,0,2],[48872,0,2],[48873,0,2],[48874,0,2],[48875,0,2],[48876,0,1],[48877,0,2],[48878,0,2],[48879,0,2],[48880,0,2],[48881,0,2],[48882,0,2],[48883,0,2],[48884,0,2],[48885,0,2],[48886,0,2],[48887,0,2],[48888,0,2],[48889,0,2],[48890,0,2],[48891,0,2],[48892,0,2],[48893,0,2],[48894,0,2],[48895,0,2],[48896,0,2],[48897,0,2],[48898,0,2],[48899,0,2],[48900,0,2],[48901,0,2],[48902,0,2],[48903,0,2],[48904,0,1],[48905,0,2],[48906,0,2],[48907,0,2],[48908,0,2],[48909,0,2],[48910,0,2],[48911,0,2],[48912,0,2],[48913,0,2],[48914,0,2],[48915,0,2],[48916,0,2],[48917,0,2],[48918,0,2],[48919,0,2],[48920,0,2],[48921,0,2],[48922,0,2],[48923,0,2],[48924,0,2],[48925,0,2],[48926,0,2],[48927,0,2],[48928,0,2],[48929,0,2],[48930,0,2],[48931,0,2],[48932,0,1],[48933,0,2],[48934,0,2],[48935,0,2],[48936,0,2],[48937,0,2],[48938,0,2],[48939,0,2],[48940,0,2],[48941,0,2],[48942,0,2],[48943,0,2],[48944,0,2],[48945,0,2],[48946,0,2],[48947,0,2],[48948,0,2],[48949,0,2],[48950,0,2],[48951,0,2],[48952,0,2],[48953,0,2],[48954,0,2],[48955,0,2],[48956,0,2],[48957,0,2],[48958,0,2],[48959,0,2],[48960,0,1],[48961,0,2],[48962,0,2],[48963,0,2],[48964,0,2],[48965,0,2],[48966,0,2],[48967,0,2],[48968,0,2],[48969,0,2],[48970,0,2],[48971,0,2],[48972,0,2],[48973,0,2],[48974,0,2],[48975,0,2],[48976,0,2],[48977,0,2],[48978,0,2],[48979,0,2],[48980,0,2],[48981,0,2],[48982,0,2],[48983,0,2],[48984,0,2],[48985,0,2],[48986,0,2],[48987,0,2],[48988,0,1],[48989,0,2],[48990,0,2],[48991,0,2],[48992,0,2],[48993,0,2],[48994,0,2],[48995,0,2],[48996,0,2],[48997,0,2],[48998,0,2],[48999,0,2],[49000,0,2],[49001,0,2],[49002,0,2],[49003,0,2],[49004,0,2],[49005,0,2],[49006,0,2],[49007,0,2],[49008,0,2],[49009,0,2],[49010,0,2],[49011,0,2],[49012,0,2],[49013,0,2],[49014,0,2],[49015,0,2],[49016,0,1],[49017,0,2],[49018,0,2],[49019,0,2],[49020,0,2],[49021,0,2],[49022,0,2],[49023,0,2],[49024,0,2],[49025,0,2],[49026,0,2],[49027,0,2],[49028,0,2],[49029,0,2],[49030,0,2],[49031,0,2],[49032,0,2],[49033,0,2],[49034,0,2],[49035,0,2],[49036,0,2],[49037,0,2],[49038,0,2],[49039,0,2],[49040,0,2],[49041,0,2],[49042,0,2],[49043,0,2],[49044,0,1],[49045,0,2],[49046,0,2],[49047,0,2],[49048,0,2],[49049,0,2],[49050,0,2],[49051,0,2],[49052,0,2],[49053,0,2],[49054,0,2],[49055,0,2],[49056,0,2],[49057,0,2],[49058,0,2],[49059,0,2],[49060,0,2],[49061,0,2],[49062,0,2],[49063,0,2],[49064,0,2],[49065,0,2],[49066,0,2],[49067,0,2],[49068,0,2],[49069,0,2],[49070,0,2],[49071,0,2],[49072,0,1],[49073,0,2],[49074,0,2],[49075,0,2],[49076,0,2],[49077,0,2],[49078,0,2],[49079,0,2],[49080,0,2],[49081,0,2],[49082,0,2],[49083,0,2],[49084,0,2],[49085,0,2],[49086,0,2],[49087,0,2],[49088,0,2],[49089,0,2],[49090,0,2],[49091,0,2],[49092,0,2],[49093,0,2],[49094,0,2],[49095,0,2],[49096,0,2],[49097,0,2],[49098,0,2],[49099,0,2],[49100,0,1],[49101,0,2],[49102,0,2],[49103,0,2],[49104,0,2],[49105,0,2],[49106,0,2],[49107,0,2],[49108,0,2],[49109,0,2],[49110,0,2],[49111,0,2],[49112,0,2],[49113,0,2],[49114,0,2],[49115,0,2],[49116,0,2],[49117,0,2],[49118,0,2],[49119,0,2],[49120,0,2],[49121,0,2],[49122,0,2],[49123,0,2],[49124,0,2],[49125,0,2],[49126,0,2],[49127,0,2],[49128,0,1],[49129,0,2],[49130,0,2],[49131,0,2],[49132,0,2],[49133,0,2],[49134,0,2],[49135,0,2],[49136,0,2],[49137,0,2],[49138,0,2],[49139,0,2],[49140,0,2],[49141,0,2],[49142,0,2],[49143,0,2],[49144,0,2],[49145,0,2],[49146,0,2],[49147,0,2],[49148,0,2],[49149,0,2],[49150,0,2],[49151,0,2],[49152,0,2],[49153,0,2],[49154,0,2],[49155,0,2],[49156,0,1],[49157,0,2],[49158,0,2],[49159,0,2],[49160,0,2],[49161,0,2],[49162,0,2],[49163,0,2],[49164,0,2],[49165,0,2],[49166,0,2],[49167,0,2],[49168,0,2],[49169,0,2],[49170,0,2],[49171,0,2],[49172,0,2],[49173,0,2],[49174,0,2],[49175,0,2],[49176,0,2],[49177,0,2],[49178,0,2],[49179,0,2],[49180,0,2],[49181,0,2],[49182,0,2],[49183,0,2],[49184,0,1],[49185,0,2],[49186,0,2],[49187,0,2],[49188,0,2],[49189,0,2],[49190,0,2],[49191,0,2],[49192,0,2],[49193,0,2],[49194,0,2],[49195,0,2],[49196,0,2],[49197,0,2],[49198,0,2],[49199,0,2],[49200,0,2],[49201,0,2],[49202,0,2],[49203,0,2],[49204,0,2],[49205,0,2],[49206,0,2],[49207,0,2],[49208,0,2],[49209,0,2],[49210,0,2],[49211,0,2],[49212,0,1],[49213,0,2],[49214,0,2],[49215,0,2],[49216,0,2],[49217,0,2],[49218,0,2],[49219,0,2],[49220,0,2],[49221,0,2],[49222,0,2],[49223,0,2],[49224,0,2],[49225,0,2],[49226,0,2],[49227,0,2],[49228,0,2],[49229,0,2],[49230,0,2],[49231,0,2],[49232,0,2],[49233,0,2],[49234,0,2],[49235,0,2],[49236,0,2],[49237,0,2],[49238,0,2],[49239,0,2],[49240,0,1],[49241,0,2],[49242,0,2],[49243,0,2],[49244,0,2],[49245,0,2],[49246,0,2],[49247,0,2],[49248,0,2],[49249,0,2],[49250,0,2],[49251,0,2],[49252,0,2],[49253,0,2],[49254,0,2],[49255,0,2],[49256,0,2],[49257,0,2],[49258,0,2],[49259,0,2],[49260,0,2],[49261,0,2],[49262,0,2],[49263,0,2],[49264,0,2],[49265,0,2],[49266,0,2],[49267,0,2],[49268,0,1],[49269,0,2],[49270,0,2],[49271,0,2],[49272,0,2],[49273,0,2],[49274,0,2],[49275,0,2],[49276,0,2],[49277,0,2],[49278,0,2],[49279,0,2],[49280,0,2],[49281,0,2],[49282,0,2],[49283,0,2],[49284,0,2],[49285,0,2],[49286,0,2],[49287,0,2],[49288,0,2],[49289,0,2],[49290,0,2],[49291,0,2],[49292,0,2],[49293,0,2],[49294,0,2],[49295,0,2],[49296,0,1],[49297,0,2],[49298,0,2],[49299,0,2],[49300,0,2],[49301,0,2],[49302,0,2],[49303,0,2],[49304,0,2],[49305,0,2],[49306,0,2],[49307,0,2],[49308,0,2],[49309,0,2],[49310,0,2],[49311,0,2],[49312,0,2],[49313,0,2],[49314,0,2],[49315,0,2],[49316,0,2],[49317,0,2],[49318,0,2],[49319,0,2],[49320,0,2],[49321,0,2],[49322,0,2],[49323,0,2],[49324,0,1],[49325,0,2],[49326,0,2],[49327,0,2],[49328,0,2],[49329,0,2],[49330,0,2],[49331,0,2],[49332,0,2],[49333,0,2],[49334,0,2],[49335,0,2],[49336,0,2],[49337,0,2],[49338,0,2],[49339,0,2],[49340,0,2],[49341,0,2],[49342,0,2],[49343,0,2],[49344,0,2],[49345,0,2],[49346,0,2],[49347,0,2],[49348,0,2],[49349,0,2],[49350,0,2],[49351,0,2],[49352,0,1],[49353,0,2],[49354,0,2],[49355,0,2],[49356,0,2],[49357,0,2],[49358,0,2],[49359,0,2],[49360,0,2],[49361,0,2],[49362,0,2],[49363,0,2],[49364,0,2],[49365,0,2],[49366,0,2],[49367,0,2],[49368,0,2],[49369,0,2],[49370,0,2],[49371,0,2],[49372,0,2],[49373,0,2],[49374,0,2],[49375,0,2],[49376,0,2],[49377,0,2],[49378,0,2],[49379,0,2],[49380,0,1],[49381,0,2],[49382,0,2],[49383,0,2],[49384,0,2],[49385,0,2],[49386,0,2],[49387,0,2],[49388,0,2],[49389,0,2],[49390,0,2],[49391,0,2],[49392,0,2],[49393,0,2],[49394,0,2],[49395,0,2],[49396,0,2],[49397,0,2],[49398,0,2],[49399,0,2],[49400,0,2],[49401,0,2],[49402,0,2],[49403,0,2],[49404,0,2],[49405,0,2],[49406,0,2],[49407,0,2],[49408,0,1],[49409,0,2],[49410,0,2],[49411,0,2],[49412,0,2],[49413,0,2],[49414,0,2],[49415,0,2],[49416,0,2],[49417,0,2],[49418,0,2],[49419,0,2],[49420,0,2],[49421,0,2],[49422,0,2],[49423,0,2],[49424,0,2],[49425,0,2],[49426,0,2],[49427,0,2],[49428,0,2],[49429,0,2],[49430,0,2],[49431,0,2],[49432,0,2],[49433,0,2],[49434,0,2],[49435,0,2],[49436,0,1],[49437,0,2],[49438,0,2],[49439,0,2],[49440,0,2],[49441,0,2],[49442,0,2],[49443,0,2],[49444,0,2],[49445,0,2],[49446,0,2],[49447,0,2],[49448,0,2],[49449,0,2],[49450,0,2],[49451,0,2],[49452,0,2],[49453,0,2],[49454,0,2],[49455,0,2],[49456,0,2],[49457,0,2],[49458,0,2],[49459,0,2],[49460,0,2],[49461,0,2],[49462,0,2],[49463,0,2],[49464,0,1],[49465,0,2],[49466,0,2],[49467,0,2],[49468,0,2],[49469,0,2],[49470,0,2],[49471,0,2],[49472,0,2],[49473,0,2],[49474,0,2],[49475,0,2],[49476,0,2],[49477,0,2],[49478,0,2],[49479,0,2],[49480,0,2],[49481,0,2],[49482,0,2],[49483,0,2],[49484,0,2],[49485,0,2],[49486,0,2],[49487,0,2],[49488,0,2],[49489,0,2],[49490,0,2],[49491,0,2],[49492,0,1],[49493,0,2],[49494,0,2],[49495,0,2],[49496,0,2],[49497,0,2],[49498,0,2],[49499,0,2],[49500,0,2],[49501,0,2],[49502,0,2],[49503,0,2],[49504,0,2],[49505,0,2],[49506,0,2],[49507,0,2],[49508,0,2],[49509,0,2],[49510,0,2],[49511,0,2],[49512,0,2],[49513,0,2],[49514,0,2],[49515,0,2],[49516,0,2],[49517,0,2],[49518,0,2],[49519,0,2],[49520,0,1],[49521,0,2],[49522,0,2],[49523,0,2],[49524,0,2],[49525,0,2],[49526,0,2],[49527,0,2],[49528,0,2],[49529,0,2],[49530,0,2],[49531,0,2],[49532,0,2],[49533,0,2],[49534,0,2],[49535,0,2],[49536,0,2],[49537,0,2],[49538,0,2],[49539,0,2],[49540,0,2],[49541,0,2],[49542,0,2],[49543,0,2],[49544,0,2],[49545,0,2],[49546,0,2],[49547,0,2],[49548,0,1],[49549,0,2],[49550,0,2],[49551,0,2],[49552,0,2],[49553,0,2],[49554,0,2],[49555,0,2],[49556,0,2],[49557,0,2],[49558,0,2],[49559,0,2],[49560,0,2],[49561,0,2],[49562,0,2],[49563,0,2],[49564,0,2],[49565,0,2],[49566,0,2],[49567,0,2],[49568,0,2],[49569,0,2],[49570,0,2],[49571,0,2],[49572,0,2],[49573,0,2],[49574,0,2],[49575,0,2],[49576,0,1],[49577,0,2],[49578,0,2],[49579,0,2],[49580,0,2],[49581,0,2],[49582,0,2],[49583,0,2],[49584,0,2],[49585,0,2],[49586,0,2],[49587,0,2],[49588,0,2],[49589,0,2],[49590,0,2],[49591,0,2],[49592,0,2],[49593,0,2],[49594,0,2],[49595,0,2],[49596,0,2],[49597,0,2],[49598,0,2],[49599,0,2],[49600,0,2],[49601,0,2],[49602,0,2],[49603,0,2],[49604,0,1],[49605,0,2],[49606,0,2],[49607,0,2],[49608,0,2],[49609,0,2],[49610,0,2],[49611,0,2],[49612,0,2],[49613,0,2],[49614,0,2],[49615,0,2],[49616,0,2],[49617,0,2],[49618,0,2],[49619,0,2],[49620,0,2],[49621,0,2],[49622,0,2],[49623,0,2],[49624,0,2],[49625,0,2],[49626,0,2],[49627,0,2],[49628,0,2],[49629,0,2],[49630,0,2],[49631,0,2],[49632,0,1],[49633,0,2],[49634,0,2],[49635,0,2],[49636,0,2],[49637,0,2],[49638,0,2],[49639,0,2],[49640,0,2],[49641,0,2],[49642,0,2],[49643,0,2],[49644,0,2],[49645,0,2],[49646,0,2],[49647,0,2],[49648,0,2],[49649,0,2],[49650,0,2],[49651,0,2],[49652,0,2],[49653,0,2],[49654,0,2],[49655,0,2],[49656,0,2],[49657,0,2],[49658,0,2],[49659,0,2],[49660,0,1],[49661,0,2],[49662,0,2],[49663,0,2],[49664,0,2],[49665,0,2],[49666,0,2],[49667,0,2],[49668,0,2],[49669,0,2],[49670,0,2],[49671,0,2],[49672,0,2],[49673,0,2],[49674,0,2],[49675,0,2],[49676,0,2],[49677,0,2],[49678,0,2],[49679,0,2],[49680,0,2],[49681,0,2],[49682,0,2],[49683,0,2],[49684,0,2],[49685,0,2],[49686,0,2],[49687,0,2],[49688,0,1],[49689,0,2],[49690,0,2],[49691,0,2],[49692,0,2],[49693,0,2],[49694,0,2],[49695,0,2],[49696,0,2],[49697,0,2],[49698,0,2],[49699,0,2],[49700,0,2],[49701,0,2],[49702,0,2],[49703,0,2],[49704,0,2],[49705,0,2],[49706,0,2],[49707,0,2],[49708,0,2],[49709,0,2],[49710,0,2],[49711,0,2],[49712,0,2],[49713,0,2],[49714,0,2],[49715,0,2],[49716,0,1],[49717,0,2],[49718,0,2],[49719,0,2],[49720,0,2],[49721,0,2],[49722,0,2],[49723,0,2],[49724,0,2],[49725,0,2],[49726,0,2],[49727,0,2],[49728,0,2],[49729,0,2],[49730,0,2],[49731,0,2],[49732,0,2],[49733,0,2],[49734,0,2],[49735,0,2],[49736,0,2],[49737,0,2],[49738,0,2],[49739,0,2],[49740,0,2],[49741,0,2],[49742,0,2],[49743,0,2],[49744,0,1],[49745,0,2],[49746,0,2],[49747,0,2],[49748,0,2],[49749,0,2],[49750,0,2],[49751,0,2],[49752,0,2],[49753,0,2],[49754,0,2],[49755,0,2],[49756,0,2],[49757,0,2],[49758,0,2],[49759,0,2],[49760,0,2],[49761,0,2],[49762,0,2],[49763,0,2],[49764,0,2],[49765,0,2],[49766,0,2],[49767,0,2],[49768,0,2],[49769,0,2],[49770,0,2],[49771,0,2],[49772,0,1],[49773,0,2],[49774,0,2],[49775,0,2],[49776,0,2],[49777,0,2],[49778,0,2],[49779,0,2],[49780,0,2],[49781,0,2],[49782,0,2],[49783,0,2],[49784,0,2],[49785,0,2],[49786,0,2],[49787,0,2],[49788,0,2],[49789,0,2],[49790,0,2],[49791,0,2],[49792,0,2],[49793,0,2],[49794,0,2],[49795,0,2],[49796,0,2],[49797,0,2],[49798,0,2],[49799,0,2],[49800,0,1],[49801,0,2],[49802,0,2],[49803,0,2],[49804,0,2],[49805,0,2],[49806,0,2],[49807,0,2],[49808,0,2],[49809,0,2],[49810,0,2],[49811,0,2],[49812,0,2],[49813,0,2],[49814,0,2],[49815,0,2],[49816,0,2],[49817,0,2],[49818,0,2],[49819,0,2],[49820,0,2],[49821,0,2],[49822,0,2],[49823,0,2],[49824,0,2],[49825,0,2],[49826,0,2],[49827,0,2],[49828,0,1],[49829,0,2],[49830,0,2],[49831,0,2],[49832,0,2],[49833,0,2],[49834,0,2],[49835,0,2],[49836,0,2],[49837,0,2],[49838,0,2],[49839,0,2],[49840,0,2],[49841,0,2],[49842,0,2],[49843,0,2],[49844,0,2],[49845,0,2],[49846,0,2],[49847,0,2],[49848,0,2],[49849,0,2],[49850,0,2],[49851,0,2],[49852,0,2],[49853,0,2],[49854,0,2],[49855,0,2],[49856,0,1],[49857,0,2],[49858,0,2],[49859,0,2],[49860,0,2],[49861,0,2],[49862,0,2],[49863,0,2],[49864,0,2],[49865,0,2],[49866,0,2],[49867,0,2],[49868,0,2],[49869,0,2],[49870,0,2],[49871,0,2],[49872,0,2],[49873,0,2],[49874,0,2],[49875,0,2],[49876,0,2],[49877,0,2],[49878,0,2],[49879,0,2],[49880,0,2],[49881,0,2],[49882,0,2],[49883,0,2],[49884,0,1],[49885,0,2],[49886,0,2],[49887,0,2],[49888,0,2],[49889,0,2],[49890,0,2],[49891,0,2],[49892,0,2],[49893,0,2],[49894,0,2],[49895,0,2],[49896,0,2],[49897,0,2],[49898,0,2],[49899,0,2],[49900,0,2],[49901,0,2],[49902,0,2],[49903,0,2],[49904,0,2],[49905,0,2],[49906,0,2],[49907,0,2],[49908,0,2],[49909,0,2],[49910,0,2],[49911,0,2],[49912,0,1],[49913,0,2],[49914,0,2],[49915,0,2],[49916,0,2],[49917,0,2],[49918,0,2],[49919,0,2],[49920,0,2],[49921,0,2],[49922,0,2],[49923,0,2],[49924,0,2],[49925,0,2],[49926,0,2],[49927,0,2],[49928,0,2],[49929,0,2],[49930,0,2],[49931,0,2],[49932,0,2],[49933,0,2],[49934,0,2],[49935,0,2],[49936,0,2],[49937,0,2],[49938,0,2],[49939,0,2],[49940,0,1],[49941,0,2],[49942,0,2],[49943,0,2],[49944,0,2],[49945,0,2],[49946,0,2],[49947,0,2],[49948,0,2],[49949,0,2],[49950,0,2],[49951,0,2],[49952,0,2],[49953,0,2],[49954,0,2],[49955,0,2],[49956,0,2],[49957,0,2],[49958,0,2],[49959,0,2],[49960,0,2],[49961,0,2],[49962,0,2],[49963,0,2],[49964,0,2],[49965,0,2],[49966,0,2],[49967,0,2],[49968,0,1],[49969,0,2],[49970,0,2],[49971,0,2],[49972,0,2],[49973,0,2],[49974,0,2],[49975,0,2],[49976,0,2],[49977,0,2],[49978,0,2],[49979,0,2],[49980,0,2],[49981,0,2],[49982,0,2],[49983,0,2],[49984,0,2],[49985,0,2],[49986,0,2],[49987,0,2],[49988,0,2],[49989,0,2],[49990,0,2],[49991,0,2],[49992,0,2],[49993,0,2],[49994,0,2],[49995,0,2],[49996,0,1],[49997,0,2],[49998,0,2],[49999,0,2],[50000,0,2],[50001,0,2],[50002,0,2],[50003,0,2],[50004,0,2],[50005,0,2],[50006,0,2],[50007,0,2],[50008,0,2],[50009,0,2],[50010,0,2],[50011,0,2],[50012,0,2],[50013,0,2],[50014,0,2],[50015,0,2],[50016,0,2],[50017,0,2],[50018,0,2],[50019,0,2],[50020,0,2],[50021,0,2],[50022,0,2],[50023,0,2],[50024,0,1],[50025,0,2],[50026,0,2],[50027,0,2],[50028,0,2],[50029,0,2],[50030,0,2],[50031,0,2],[50032,0,2],[50033,0,2],[50034,0,2],[50035,0,2],[50036,0,2],[50037,0,2],[50038,0,2],[50039,0,2],[50040,0,2],[50041,0,2],[50042,0,2],[50043,0,2],[50044,0,2],[50045,0,2],[50046,0,2],[50047,0,2],[50048,0,2],[50049,0,2],[50050,0,2],[50051,0,2],[50052,0,1],[50053,0,2],[50054,0,2],[50055,0,2],[50056,0,2],[50057,0,2],[50058,0,2],[50059,0,2],[50060,0,2],[50061,0,2],[50062,0,2],[50063,0,2],[50064,0,2],[50065,0,2],[50066,0,2],[50067,0,2],[50068,0,2],[50069,0,2],[50070,0,2],[50071,0,2],[50072,0,2],[50073,0,2],[50074,0,2],[50075,0,2],[50076,0,2],[50077,0,2],[50078,0,2],[50079,0,2],[50080,0,1],[50081,0,2],[50082,0,2],[50083,0,2],[50084,0,2],[50085,0,2],[50086,0,2],[50087,0,2],[50088,0,2],[50089,0,2],[50090,0,2],[50091,0,2],[50092,0,2],[50093,0,2],[50094,0,2],[50095,0,2],[50096,0,2],[50097,0,2],[50098,0,2],[50099,0,2],[50100,0,2],[50101,0,2],[50102,0,2],[50103,0,2],[50104,0,2],[50105,0,2],[50106,0,2],[50107,0,2],[50108,0,1],[50109,0,2],[50110,0,2],[50111,0,2],[50112,0,2],[50113,0,2],[50114,0,2],[50115,0,2],[50116,0,2],[50117,0,2],[50118,0,2],[50119,0,2],[50120,0,2],[50121,0,2],[50122,0,2],[50123,0,2],[50124,0,2],[50125,0,2],[50126,0,2],[50127,0,2],[50128,0,2],[50129,0,2],[50130,0,2],[50131,0,2],[50132,0,2],[50133,0,2],[50134,0,2],[50135,0,2],[50136,0,1],[50137,0,2],[50138,0,2],[50139,0,2],[50140,0,2],[50141,0,2],[50142,0,2],[50143,0,2],[50144,0,2],[50145,0,2],[50146,0,2],[50147,0,2],[50148,0,2],[50149,0,2],[50150,0,2],[50151,0,2],[50152,0,2],[50153,0,2],[50154,0,2],[50155,0,2],[50156,0,2],[50157,0,2],[50158,0,2],[50159,0,2],[50160,0,2],[50161,0,2],[50162,0,2],[50163,0,2],[50164,0,1],[50165,0,2],[50166,0,2],[50167,0,2],[50168,0,2],[50169,0,2],[50170,0,2],[50171,0,2],[50172,0,2],[50173,0,2],[50174,0,2],[50175,0,2],[50176,0,2],[50177,0,2],[50178,0,2],[50179,0,2],[50180,0,2],[50181,0,2],[50182,0,2],[50183,0,2],[50184,0,2],[50185,0,2],[50186,0,2],[50187,0,2],[50188,0,2],[50189,0,2],[50190,0,2],[50191,0,2],[50192,0,1],[50193,0,2],[50194,0,2],[50195,0,2],[50196,0,2],[50197,0,2],[50198,0,2],[50199,0,2],[50200,0,2],[50201,0,2],[50202,0,2],[50203,0,2],[50204,0,2],[50205,0,2],[50206,0,2],[50207,0,2],[50208,0,2],[50209,0,2],[50210,0,2],[50211,0,2],[50212,0,2],[50213,0,2],[50214,0,2],[50215,0,2],[50216,0,2],[50217,0,2],[50218,0,2],[50219,0,2],[50220,0,1],[50221,0,2],[50222,0,2],[50223,0,2],[50224,0,2],[50225,0,2],[50226,0,2],[50227,0,2],[50228,0,2],[50229,0,2],[50230,0,2],[50231,0,2],[50232,0,2],[50233,0,2],[50234,0,2],[50235,0,2],[50236,0,2],[50237,0,2],[50238,0,2],[50239,0,2],[50240,0,2],[50241,0,2],[50242,0,2],[50243,0,2],[50244,0,2],[50245,0,2],[50246,0,2],[50247,0,2],[50248,0,1],[50249,0,2],[50250,0,2],[50251,0,2],[50252,0,2],[50253,0,2],[50254,0,2],[50255,0,2],[50256,0,2],[50257,0,2],[50258,0,2],[50259,0,2],[50260,0,2],[50261,0,2],[50262,0,2],[50263,0,2],[50264,0,2],[50265,0,2],[50266,0,2],[50267,0,2],[50268,0,2],[50269,0,2],[50270,0,2],[50271,0,2],[50272,0,2],[50273,0,2],[50274,0,2],[50275,0,2],[50276,0,1],[50277,0,2],[50278,0,2],[50279,0,2],[50280,0,2],[50281,0,2],[50282,0,2],[50283,0,2],[50284,0,2],[50285,0,2],[50286,0,2],[50287,0,2],[50288,0,2],[50289,0,2],[50290,0,2],[50291,0,2],[50292,0,2],[50293,0,2],[50294,0,2],[50295,0,2],[50296,0,2],[50297,0,2],[50298,0,2],[50299,0,2],[50300,0,2],[50301,0,2],[50302,0,2],[50303,0,2],[50304,0,1],[50305,0,2],[50306,0,2],[50307,0,2],[50308,0,2],[50309,0,2],[50310,0,2],[50311,0,2],[50312,0,2],[50313,0,2],[50314,0,2],[50315,0,2],[50316,0,2],[50317,0,2],[50318,0,2],[50319,0,2],[50320,0,2],[50321,0,2],[50322,0,2],[50323,0,2],[50324,0,2],[50325,0,2],[50326,0,2],[50327,0,2],[50328,0,2],[50329,0,2],[50330,0,2],[50331,0,2],[50332,0,1],[50333,0,2],[50334,0,2],[50335,0,2],[50336,0,2],[50337,0,2],[50338,0,2],[50339,0,2],[50340,0,2],[50341,0,2],[50342,0,2],[50343,0,2],[50344,0,2],[50345,0,2],[50346,0,2],[50347,0,2],[50348,0,2],[50349,0,2],[50350,0,2],[50351,0,2],[50352,0,2],[50353,0,2],[50354,0,2],[50355,0,2],[50356,0,2],[50357,0,2],[50358,0,2],[50359,0,2],[50360,0,1],[50361,0,2],[50362,0,2],[50363,0,2],[50364,0,2],[50365,0,2],[50366,0,2],[50367,0,2],[50368,0,2],[50369,0,2],[50370,0,2],[50371,0,2],[50372,0,2],[50373,0,2],[50374,0,2],[50375,0,2],[50376,0,2],[50377,0,2],[50378,0,2],[50379,0,2],[50380,0,2],[50381,0,2],[50382,0,2],[50383,0,2],[50384,0,2],[50385,0,2],[50386,0,2],[50387,0,2],[50388,0,1],[50389,0,2],[50390,0,2],[50391,0,2],[50392,0,2],[50393,0,2],[50394,0,2],[50395,0,2],[50396,0,2],[50397,0,2],[50398,0,2],[50399,0,2],[50400,0,2],[50401,0,2],[50402,0,2],[50403,0,2],[50404,0,2],[50405,0,2],[50406,0,2],[50407,0,2],[50408,0,2],[50409,0,2],[50410,0,2],[50411,0,2],[50412,0,2],[50413,0,2],[50414,0,2],[50415,0,2],[50416,0,1],[50417,0,2],[50418,0,2],[50419,0,2],[50420,0,2],[50421,0,2],[50422,0,2],[50423,0,2],[50424,0,2],[50425,0,2],[50426,0,2],[50427,0,2],[50428,0,2],[50429,0,2],[50430,0,2],[50431,0,2],[50432,0,2],[50433,0,2],[50434,0,2],[50435,0,2],[50436,0,2],[50437,0,2],[50438,0,2],[50439,0,2],[50440,0,2],[50441,0,2],[50442,0,2],[50443,0,2],[50444,0,1],[50445,0,2],[50446,0,2],[50447,0,2],[50448,0,2],[50449,0,2],[50450,0,2],[50451,0,2],[50452,0,2],[50453,0,2],[50454,0,2],[50455,0,2],[50456,0,2],[50457,0,2],[50458,0,2],[50459,0,2],[50460,0,2],[50461,0,2],[50462,0,2],[50463,0,2],[50464,0,2],[50465,0,2],[50466,0,2],[50467,0,2],[50468,0,2],[50469,0,2],[50470,0,2],[50471,0,2],[50472,0,1],[50473,0,2],[50474,0,2],[50475,0,2],[50476,0,2],[50477,0,2],[50478,0,2],[50479,0,2],[50480,0,2],[50481,0,2],[50482,0,2],[50483,0,2],[50484,0,2],[50485,0,2],[50486,0,2],[50487,0,2],[50488,0,2],[50489,0,2],[50490,0,2],[50491,0,2],[50492,0,2],[50493,0,2],[50494,0,2],[50495,0,2],[50496,0,2],[50497,0,2],[50498,0,2],[50499,0,2],[50500,0,1],[50501,0,2],[50502,0,2],[50503,0,2],[50504,0,2],[50505,0,2],[50506,0,2],[50507,0,2],[50508,0,2],[50509,0,2],[50510,0,2],[50511,0,2],[50512,0,2],[50513,0,2],[50514,0,2],[50515,0,2],[50516,0,2],[50517,0,2],[50518,0,2],[50519,0,2],[50520,0,2],[50521,0,2],[50522,0,2],[50523,0,2],[50524,0,2],[50525,0,2],[50526,0,2],[50527,0,2],[50528,0,1],[50529,0,2],[50530,0,2],[50531,0,2],[50532,0,2],[50533,0,2],[50534,0,2],[50535,0,2],[50536,0,2],[50537,0,2],[50538,0,2],[50539,0,2],[50540,0,2],[50541,0,2],[50542,0,2],[50543,0,2],[50544,0,2],[50545,0,2],[50546,0,2],[50547,0,2],[50548,0,2],[50549,0,2],[50550,0,2],[50551,0,2],[50552,0,2],[50553,0,2],[50554,0,2],[50555,0,2],[50556,0,1],[50557,0,2],[50558,0,2],[50559,0,2],[50560,0,2],[50561,0,2],[50562,0,2],[50563,0,2],[50564,0,2],[50565,0,2],[50566,0,2],[50567,0,2],[50568,0,2],[50569,0,2],[50570,0,2],[50571,0,2],[50572,0,2],[50573,0,2],[50574,0,2],[50575,0,2],[50576,0,2],[50577,0,2],[50578,0,2],[50579,0,2],[50580,0,2],[50581,0,2],[50582,0,2],[50583,0,2],[50584,0,1],[50585,0,2],[50586,0,2],[50587,0,2],[50588,0,2],[50589,0,2],[50590,0,2],[50591,0,2],[50592,0,2],[50593,0,2],[50594,0,2],[50595,0,2],[50596,0,2],[50597,0,2],[50598,0,2],[50599,0,2],[50600,0,2],[50601,0,2],[50602,0,2],[50603,0,2],[50604,0,2],[50605,0,2],[50606,0,2],[50607,0,2],[50608,0,2],[50609,0,2],[50610,0,2],[50611,0,2],[50612,0,1],[50613,0,2],[50614,0,2],[50615,0,2],[50616,0,2],[50617,0,2],[50618,0,2],[50619,0,2],[50620,0,2],[50621,0,2],[50622,0,2],[50623,0,2],[50624,0,2],[50625,0,2],[50626,0,2],[50627,0,2],[50628,0,2],[50629,0,2],[50630,0,2],[50631,0,2],[50632,0,2],[50633,0,2],[50634,0,2],[50635,0,2],[50636,0,2],[50637,0,2],[50638,0,2],[50639,0,2],[50640,0,1],[50641,0,2],[50642,0,2],[50643,0,2],[50644,0,2],[50645,0,2],[50646,0,2],[50647,0,2],[50648,0,2],[50649,0,2],[50650,0,2],[50651,0,2],[50652,0,2],[50653,0,2],[50654,0,2],[50655,0,2],[50656,0,2],[50657,0,2],[50658,0,2],[50659,0,2],[50660,0,2],[50661,0,2],[50662,0,2],[50663,0,2],[50664,0,2],[50665,0,2],[50666,0,2],[50667,0,2],[50668,0,1],[50669,0,2],[50670,0,2],[50671,0,2],[50672,0,2],[50673,0,2],[50674,0,2],[50675,0,2],[50676,0,2],[50677,0,2],[50678,0,2],[50679,0,2],[50680,0,2],[50681,0,2],[50682,0,2],[50683,0,2],[50684,0,2],[50685,0,2],[50686,0,2],[50687,0,2],[50688,0,2],[50689,0,2],[50690,0,2],[50691,0,2],[50692,0,2],[50693,0,2],[50694,0,2],[50695,0,2],[50696,0,1],[50697,0,2],[50698,0,2],[50699,0,2],[50700,0,2],[50701,0,2],[50702,0,2],[50703,0,2],[50704,0,2],[50705,0,2],[50706,0,2],[50707,0,2],[50708,0,2],[50709,0,2],[50710,0,2],[50711,0,2],[50712,0,2],[50713,0,2],[50714,0,2],[50715,0,2],[50716,0,2],[50717,0,2],[50718,0,2],[50719,0,2],[50720,0,2],[50721,0,2],[50722,0,2],[50723,0,2],[50724,0,1],[50725,0,2],[50726,0,2],[50727,0,2],[50728,0,2],[50729,0,2],[50730,0,2],[50731,0,2],[50732,0,2],[50733,0,2],[50734,0,2],[50735,0,2],[50736,0,2],[50737,0,2],[50738,0,2],[50739,0,2],[50740,0,2],[50741,0,2],[50742,0,2],[50743,0,2],[50744,0,2],[50745,0,2],[50746,0,2],[50747,0,2],[50748,0,2],[50749,0,2],[50750,0,2],[50751,0,2],[50752,0,1],[50753,0,2],[50754,0,2],[50755,0,2],[50756,0,2],[50757,0,2],[50758,0,2],[50759,0,2],[50760,0,2],[50761,0,2],[50762,0,2],[50763,0,2],[50764,0,2],[50765,0,2],[50766,0,2],[50767,0,2],[50768,0,2],[50769,0,2],[50770,0,2],[50771,0,2],[50772,0,2],[50773,0,2],[50774,0,2],[50775,0,2],[50776,0,2],[50777,0,2],[50778,0,2],[50779,0,2],[50780,0,1],[50781,0,2],[50782,0,2],[50783,0,2],[50784,0,2],[50785,0,2],[50786,0,2],[50787,0,2],[50788,0,2],[50789,0,2],[50790,0,2],[50791,0,2],[50792,0,2],[50793,0,2],[50794,0,2],[50795,0,2],[50796,0,2],[50797,0,2],[50798,0,2],[50799,0,2],[50800,0,2],[50801,0,2],[50802,0,2],[50803,0,2],[50804,0,2],[50805,0,2],[50806,0,2],[50807,0,2],[50808,0,1],[50809,0,2],[50810,0,2],[50811,0,2],[50812,0,2],[50813,0,2],[50814,0,2],[50815,0,2],[50816,0,2],[50817,0,2],[50818,0,2],[50819,0,2],[50820,0,2],[50821,0,2],[50822,0,2],[50823,0,2],[50824,0,2],[50825,0,2],[50826,0,2],[50827,0,2],[50828,0,2],[50829,0,2],[50830,0,2],[50831,0,2],[50832,0,2],[50833,0,2],[50834,0,2],[50835,0,2],[50836,0,1],[50837,0,2],[50838,0,2],[50839,0,2],[50840,0,2],[50841,0,2],[50842,0,2],[50843,0,2],[50844,0,2],[50845,0,2],[50846,0,2],[50847,0,2],[50848,0,2],[50849,0,2],[50850,0,2],[50851,0,2],[50852,0,2],[50853,0,2],[50854,0,2],[50855,0,2],[50856,0,2],[50857,0,2],[50858,0,2],[50859,0,2],[50860,0,2],[50861,0,2],[50862,0,2],[50863,0,2],[50864,0,1],[50865,0,2],[50866,0,2],[50867,0,2],[50868,0,2],[50869,0,2],[50870,0,2],[50871,0,2],[50872,0,2],[50873,0,2],[50874,0,2],[50875,0,2],[50876,0,2],[50877,0,2],[50878,0,2],[50879,0,2],[50880,0,2],[50881,0,2],[50882,0,2],[50883,0,2],[50884,0,2],[50885,0,2],[50886,0,2],[50887,0,2],[50888,0,2],[50889,0,2],[50890,0,2],[50891,0,2],[50892,0,1],[50893,0,2],[50894,0,2],[50895,0,2],[50896,0,2],[50897,0,2],[50898,0,2],[50899,0,2],[50900,0,2],[50901,0,2],[50902,0,2],[50903,0,2],[50904,0,2],[50905,0,2],[50906,0,2],[50907,0,2],[50908,0,2],[50909,0,2],[50910,0,2],[50911,0,2],[50912,0,2],[50913,0,2],[50914,0,2],[50915,0,2],[50916,0,2],[50917,0,2],[50918,0,2],[50919,0,2],[50920,0,1],[50921,0,2],[50922,0,2],[50923,0,2],[50924,0,2],[50925,0,2],[50926,0,2],[50927,0,2],[50928,0,2],[50929,0,2],[50930,0,2],[50931,0,2],[50932,0,2],[50933,0,2],[50934,0,2],[50935,0,2],[50936,0,2],[50937,0,2],[50938,0,2],[50939,0,2],[50940,0,2],[50941,0,2],[50942,0,2],[50943,0,2],[50944,0,2],[50945,0,2],[50946,0,2],[50947,0,2],[50948,0,1],[50949,0,2],[50950,0,2],[50951,0,2],[50952,0,2],[50953,0,2],[50954,0,2],[50955,0,2],[50956,0,2],[50957,0,2],[50958,0,2],[50959,0,2],[50960,0,2],[50961,0,2],[50962,0,2],[50963,0,2],[50964,0,2],[50965,0,2],[50966,0,2],[50967,0,2],[50968,0,2],[50969,0,2],[50970,0,2],[50971,0,2],[50972,0,2],[50973,0,2],[50974,0,2],[50975,0,2],[50976,0,1],[50977,0,2],[50978,0,2],[50979,0,2],[50980,0,2],[50981,0,2],[50982,0,2],[50983,0,2],[50984,0,2],[50985,0,2],[50986,0,2],[50987,0,2],[50988,0,2],[50989,0,2],[50990,0,2],[50991,0,2],[50992,0,2],[50993,0,2],[50994,0,2],[50995,0,2],[50996,0,2],[50997,0,2],[50998,0,2],[50999,0,2],[51000,0,2],[51001,0,2],[51002,0,2],[51003,0,2],[51004,0,1],[51005,0,2],[51006,0,2],[51007,0,2],[51008,0,2],[51009,0,2],[51010,0,2],[51011,0,2],[51012,0,2],[51013,0,2],[51014,0,2],[51015,0,2],[51016,0,2],[51017,0,2],[51018,0,2],[51019,0,2],[51020,0,2],[51021,0,2],[51022,0,2],[51023,0,2],[51024,0,2],[51025,0,2],[51026,0,2],[51027,0,2],[51028,0,2],[51029,0,2],[51030,0,2],[51031,0,2],[51032,0,1],[51033,0,2],[51034,0,2],[51035,0,2],[51036,0,2],[51037,0,2],[51038,0,2],[51039,0,2],[51040,0,2],[51041,0,2],[51042,0,2],[51043,0,2],[51044,0,2],[51045,0,2],[51046,0,2],[51047,0,2],[51048,0,2],[51049,0,2],[51050,0,2],[51051,0,2],[51052,0,2],[51053,0,2],[51054,0,2],[51055,0,2],[51056,0,2],[51057,0,2],[51058,0,2],[51059,0,2],[51060,0,1],[51061,0,2],[51062,0,2],[51063,0,2],[51064,0,2],[51065,0,2],[51066,0,2],[51067,0,2],[51068,0,2],[51069,0,2],[51070,0,2],[51071,0,2],[51072,0,2],[51073,0,2],[51074,0,2],[51075,0,2],[51076,0,2],[51077,0,2],[51078,0,2],[51079,0,2],[51080,0,2],[51081,0,2],[51082,0,2],[51083,0,2],[51084,0,2],[51085,0,2],[51086,0,2],[51087,0,2],[51088,0,1],[51089,0,2],[51090,0,2],[51091,0,2],[51092,0,2],[51093,0,2],[51094,0,2],[51095,0,2],[51096,0,2],[51097,0,2],[51098,0,2],[51099,0,2],[51100,0,2],[51101,0,2],[51102,0,2],[51103,0,2],[51104,0,2],[51105,0,2],[51106,0,2],[51107,0,2],[51108,0,2],[51109,0,2],[51110,0,2],[51111,0,2],[51112,0,2],[51113,0,2],[51114,0,2],[51115,0,2],[51116,0,1],[51117,0,2],[51118,0,2],[51119,0,2],[51120,0,2],[51121,0,2],[51122,0,2],[51123,0,2],[51124,0,2],[51125,0,2],[51126,0,2],[51127,0,2],[51128,0,2],[51129,0,2],[51130,0,2],[51131,0,2],[51132,0,2],[51133,0,2],[51134,0,2],[51135,0,2],[51136,0,2],[51137,0,2],[51138,0,2],[51139,0,2],[51140,0,2],[51141,0,2],[51142,0,2],[51143,0,2],[51144,0,1],[51145,0,2],[51146,0,2],[51147,0,2],[51148,0,2],[51149,0,2],[51150,0,2],[51151,0,2],[51152,0,2],[51153,0,2],[51154,0,2],[51155,0,2],[51156,0,2],[51157,0,2],[51158,0,2],[51159,0,2],[51160,0,2],[51161,0,2],[51162,0,2],[51163,0,2],[51164,0,2],[51165,0,2],[51166,0,2],[51167,0,2],[51168,0,2],[51169,0,2],[51170,0,2],[51171,0,2],[51172,0,1],[51173,0,2],[51174,0,2],[51175,0,2],[51176,0,2],[51177,0,2],[51178,0,2],[51179,0,2],[51180,0,2],[51181,0,2],[51182,0,2],[51183,0,2],[51184,0,2],[51185,0,2],[51186,0,2],[51187,0,2],[51188,0,2],[51189,0,2],[51190,0,2],[51191,0,2],[51192,0,2],[51193,0,2],[51194,0,2],[51195,0,2],[51196,0,2],[51197,0,2],[51198,0,2],[51199,0,2],[51200,0,1],[51201,0,2],[51202,0,2],[51203,0,2],[51204,0,2],[51205,0,2],[51206,0,2],[51207,0,2],[51208,0,2],[51209,0,2],[51210,0,2],[51211,0,2],[51212,0,2],[51213,0,2],[51214,0,2],[51215,0,2],[51216,0,2],[51217,0,2],[51218,0,2],[51219,0,2],[51220,0,2],[51221,0,2],[51222,0,2],[51223,0,2],[51224,0,2],[51225,0,2],[51226,0,2],[51227,0,2],[51228,0,1],[51229,0,2],[51230,0,2],[51231,0,2],[51232,0,2],[51233,0,2],[51234,0,2],[51235,0,2],[51236,0,2],[51237,0,2],[51238,0,2],[51239,0,2],[51240,0,2],[51241,0,2],[51242,0,2],[51243,0,2],[51244,0,2],[51245,0,2],[51246,0,2],[51247,0,2],[51248,0,2],[51249,0,2],[51250,0,2],[51251,0,2],[51252,0,2],[51253,0,2],[51254,0,2],[51255,0,2],[51256,0,1],[51257,0,2],[51258,0,2],[51259,0,2],[51260,0,2],[51261,0,2],[51262,0,2],[51263,0,2],[51264,0,2],[51265,0,2],[51266,0,2],[51267,0,2],[51268,0,2],[51269,0,2],[51270,0,2],[51271,0,2],[51272,0,2],[51273,0,2],[51274,0,2],[51275,0,2],[51276,0,2],[51277,0,2],[51278,0,2],[51279,0,2],[51280,0,2],[51281,0,2],[51282,0,2],[51283,0,2],[51284,0,1],[51285,0,2],[51286,0,2],[51287,0,2],[51288,0,2],[51289,0,2],[51290,0,2],[51291,0,2],[51292,0,2],[51293,0,2],[51294,0,2],[51295,0,2],[51296,0,2],[51297,0,2],[51298,0,2],[51299,0,2],[51300,0,2],[51301,0,2],[51302,0,2],[51303,0,2],[51304,0,2],[51305,0,2],[51306,0,2],[51307,0,2],[51308,0,2],[51309,0,2],[51310,0,2],[51311,0,2],[51312,0,1],[51313,0,2],[51314,0,2],[51315,0,2],[51316,0,2],[51317,0,2],[51318,0,2],[51319,0,2],[51320,0,2],[51321,0,2],[51322,0,2],[51323,0,2],[51324,0,2],[51325,0,2],[51326,0,2],[51327,0,2],[51328,0,2],[51329,0,2],[51330,0,2],[51331,0,2],[51332,0,2],[51333,0,2],[51334,0,2],[51335,0,2],[51336,0,2],[51337,0,2],[51338,0,2],[51339,0,2],[51340,0,1],[51341,0,2],[51342,0,2],[51343,0,2],[51344,0,2],[51345,0,2],[51346,0,2],[51347,0,2],[51348,0,2],[51349,0,2],[51350,0,2],[51351,0,2],[51352,0,2],[51353,0,2],[51354,0,2],[51355,0,2],[51356,0,2],[51357,0,2],[51358,0,2],[51359,0,2],[51360,0,2],[51361,0,2],[51362,0,2],[51363,0,2],[51364,0,2],[51365,0,2],[51366,0,2],[51367,0,2],[51368,0,1],[51369,0,2],[51370,0,2],[51371,0,2],[51372,0,2],[51373,0,2],[51374,0,2],[51375,0,2],[51376,0,2],[51377,0,2],[51378,0,2],[51379,0,2],[51380,0,2],[51381,0,2],[51382,0,2],[51383,0,2],[51384,0,2],[51385,0,2],[51386,0,2],[51387,0,2],[51388,0,2],[51389,0,2],[51390,0,2],[51391,0,2],[51392,0,2],[51393,0,2],[51394,0,2],[51395,0,2],[51396,0,1],[51397,0,2],[51398,0,2],[51399,0,2],[51400,0,2],[51401,0,2],[51402,0,2],[51403,0,2],[51404,0,2],[51405,0,2],[51406,0,2],[51407,0,2],[51408,0,2],[51409,0,2],[51410,0,2],[51411,0,2],[51412,0,2],[51413,0,2],[51414,0,2],[51415,0,2],[51416,0,2],[51417,0,2],[51418,0,2],[51419,0,2],[51420,0,2],[51421,0,2],[51422,0,2],[51423,0,2],[51424,0,1],[51425,0,2],[51426,0,2],[51427,0,2],[51428,0,2],[51429,0,2],[51430,0,2],[51431,0,2],[51432,0,2],[51433,0,2],[51434,0,2],[51435,0,2],[51436,0,2],[51437,0,2],[51438,0,2],[51439,0,2],[51440,0,2],[51441,0,2],[51442,0,2],[51443,0,2],[51444,0,2],[51445,0,2],[51446,0,2],[51447,0,2],[51448,0,2],[51449,0,2],[51450,0,2],[51451,0,2],[51452,0,1],[51453,0,2],[51454,0,2],[51455,0,2],[51456,0,2],[51457,0,2],[51458,0,2],[51459,0,2],[51460,0,2],[51461,0,2],[51462,0,2],[51463,0,2],[51464,0,2],[51465,0,2],[51466,0,2],[51467,0,2],[51468,0,2],[51469,0,2],[51470,0,2],[51471,0,2],[51472,0,2],[51473,0,2],[51474,0,2],[51475,0,2],[51476,0,2],[51477,0,2],[51478,0,2],[51479,0,2],[51480,0,1],[51481,0,2],[51482,0,2],[51483,0,2],[51484,0,2],[51485,0,2],[51486,0,2],[51487,0,2],[51488,0,2],[51489,0,2],[51490,0,2],[51491,0,2],[51492,0,2],[51493,0,2],[51494,0,2],[51495,0,2],[51496,0,2],[51497,0,2],[51498,0,2],[51499,0,2],[51500,0,2],[51501,0,2],[51502,0,2],[51503,0,2],[51504,0,2],[51505,0,2],[51506,0,2],[51507,0,2],[51508,0,1],[51509,0,2],[51510,0,2],[51511,0,2],[51512,0,2],[51513,0,2],[51514,0,2],[51515,0,2],[51516,0,2],[51517,0,2],[51518,0,2],[51519,0,2],[51520,0,2],[51521,0,2],[51522,0,2],[51523,0,2],[51524,0,2],[51525,0,2],[51526,0,2],[51527,0,2],[51528,0,2],[51529,0,2],[51530,0,2],[51531,0,2],[51532,0,2],[51533,0,2],[51534,0,2],[51535,0,2],[51536,0,1],[51537,0,2],[51538,0,2],[51539,0,2],[51540,0,2],[51541,0,2],[51542,0,2],[51543,0,2],[51544,0,2],[51545,0,2],[51546,0,2],[51547,0,2],[51548,0,2],[51549,0,2],[51550,0,2],[51551,0,2],[51552,0,2],[51553,0,2],[51554,0,2],[51555,0,2],[51556,0,2],[51557,0,2],[51558,0,2],[51559,0,2],[51560,0,2],[51561,0,2],[51562,0,2],[51563,0,2],[51564,0,1],[51565,0,2],[51566,0,2],[51567,0,2],[51568,0,2],[51569,0,2],[51570,0,2],[51571,0,2],[51572,0,2],[51573,0,2],[51574,0,2],[51575,0,2],[51576,0,2],[51577,0,2],[51578,0,2],[51579,0,2],[51580,0,2],[51581,0,2],[51582,0,2],[51583,0,2],[51584,0,2],[51585,0,2],[51586,0,2],[51587,0,2],[51588,0,2],[51589,0,2],[51590,0,2],[51591,0,2],[51592,0,1],[51593,0,2],[51594,0,2],[51595,0,2],[51596,0,2],[51597,0,2],[51598,0,2],[51599,0,2],[51600,0,2],[51601,0,2],[51602,0,2],[51603,0,2],[51604,0,2],[51605,0,2],[51606,0,2],[51607,0,2],[51608,0,2],[51609,0,2],[51610,0,2],[51611,0,2],[51612,0,2],[51613,0,2],[51614,0,2],[51615,0,2],[51616,0,2],[51617,0,2],[51618,0,2],[51619,0,2],[51620,0,1],[51621,0,2],[51622,0,2],[51623,0,2],[51624,0,2],[51625,0,2],[51626,0,2],[51627,0,2],[51628,0,2],[51629,0,2],[51630,0,2],[51631,0,2],[51632,0,2],[51633,0,2],[51634,0,2],[51635,0,2],[51636,0,2],[51637,0,2],[51638,0,2],[51639,0,2],[51640,0,2],[51641,0,2],[51642,0,2],[51643,0,2],[51644,0,2],[51645,0,2],[51646,0,2],[51647,0,2],[51648,0,1],[51649,0,2],[51650,0,2],[51651,0,2],[51652,0,2],[51653,0,2],[51654,0,2],[51655,0,2],[51656,0,2],[51657,0,2],[51658,0,2],[51659,0,2],[51660,0,2],[51661,0,2],[51662,0,2],[51663,0,2],[51664,0,2],[51665,0,2],[51666,0,2],[51667,0,2],[51668,0,2],[51669,0,2],[51670,0,2],[51671,0,2],[51672,0,2],[51673,0,2],[51674,0,2],[51675,0,2],[51676,0,1],[51677,0,2],[51678,0,2],[51679,0,2],[51680,0,2],[51681,0,2],[51682,0,2],[51683,0,2],[51684,0,2],[51685,0,2],[51686,0,2],[51687,0,2],[51688,0,2],[51689,0,2],[51690,0,2],[51691,0,2],[51692,0,2],[51693,0,2],[51694,0,2],[51695,0,2],[51696,0,2],[51697,0,2],[51698,0,2],[51699,0,2],[51700,0,2],[51701,0,2],[51702,0,2],[51703,0,2],[51704,0,1],[51705,0,2],[51706,0,2],[51707,0,2],[51708,0,2],[51709,0,2],[51710,0,2],[51711,0,2],[51712,0,2],[51713,0,2],[51714,0,2],[51715,0,2],[51716,0,2],[51717,0,2],[51718,0,2],[51719,0,2],[51720,0,2],[51721,0,2],[51722,0,2],[51723,0,2],[51724,0,2],[51725,0,2],[51726,0,2],[51727,0,2],[51728,0,2],[51729,0,2],[51730,0,2],[51731,0,2],[51732,0,1],[51733,0,2],[51734,0,2],[51735,0,2],[51736,0,2],[51737,0,2],[51738,0,2],[51739,0,2],[51740,0,2],[51741,0,2],[51742,0,2],[51743,0,2],[51744,0,2],[51745,0,2],[51746,0,2],[51747,0,2],[51748,0,2],[51749,0,2],[51750,0,2],[51751,0,2],[51752,0,2],[51753,0,2],[51754,0,2],[51755,0,2],[51756,0,2],[51757,0,2],[51758,0,2],[51759,0,2],[51760,0,1],[51761,0,2],[51762,0,2],[51763,0,2],[51764,0,2],[51765,0,2],[51766,0,2],[51767,0,2],[51768,0,2],[51769,0,2],[51770,0,2],[51771,0,2],[51772,0,2],[51773,0,2],[51774,0,2],[51775,0,2],[51776,0,2],[51777,0,2],[51778,0,2],[51779,0,2],[51780,0,2],[51781,0,2],[51782,0,2],[51783,0,2],[51784,0,2],[51785,0,2],[51786,0,2],[51787,0,2],[51788,0,1],[51789,0,2],[51790,0,2],[51791,0,2],[51792,0,2],[51793,0,2],[51794,0,2],[51795,0,2],[51796,0,2],[51797,0,2],[51798,0,2],[51799,0,2],[51800,0,2],[51801,0,2],[51802,0,2],[51803,0,2],[51804,0,2],[51805,0,2],[51806,0,2],[51807,0,2],[51808,0,2],[51809,0,2],[51810,0,2],[51811,0,2],[51812,0,2],[51813,0,2],[51814,0,2],[51815,0,2],[51816,0,1],[51817,0,2],[51818,0,2],[51819,0,2],[51820,0,2],[51821,0,2],[51822,0,2],[51823,0,2],[51824,0,2],[51825,0,2],[51826,0,2],[51827,0,2],[51828,0,2],[51829,0,2],[51830,0,2],[51831,0,2],[51832,0,2],[51833,0,2],[51834,0,2],[51835,0,2],[51836,0,2],[51837,0,2],[51838,0,2],[51839,0,2],[51840,0,2],[51841,0,2],[51842,0,2],[51843,0,2],[51844,0,1],[51845,0,2],[51846,0,2],[51847,0,2],[51848,0,2],[51849,0,2],[51850,0,2],[51851,0,2],[51852,0,2],[51853,0,2],[51854,0,2],[51855,0,2],[51856,0,2],[51857,0,2],[51858,0,2],[51859,0,2],[51860,0,2],[51861,0,2],[51862,0,2],[51863,0,2],[51864,0,2],[51865,0,2],[51866,0,2],[51867,0,2],[51868,0,2],[51869,0,2],[51870,0,2],[51871,0,2],[51872,0,1],[51873,0,2],[51874,0,2],[51875,0,2],[51876,0,2],[51877,0,2],[51878,0,2],[51879,0,2],[51880,0,2],[51881,0,2],[51882,0,2],[51883,0,2],[51884,0,2],[51885,0,2],[51886,0,2],[51887,0,2],[51888,0,2],[51889,0,2],[51890,0,2],[51891,0,2],[51892,0,2],[51893,0,2],[51894,0,2],[51895,0,2],[51896,0,2],[51897,0,2],[51898,0,2],[51899,0,2],[51900,0,1],[51901,0,2],[51902,0,2],[51903,0,2],[51904,0,2],[51905,0,2],[51906,0,2],[51907,0,2],[51908,0,2],[51909,0,2],[51910,0,2],[51911,0,2],[51912,0,2],[51913,0,2],[51914,0,2],[51915,0,2],[51916,0,2],[51917,0,2],[51918,0,2],[51919,0,2],[51920,0,2],[51921,0,2],[51922,0,2],[51923,0,2],[51924,0,2],[51925,0,2],[51926,0,2],[51927,0,2],[51928,0,1],[51929,0,2],[51930,0,2],[51931,0,2],[51932,0,2],[51933,0,2],[51934,0,2],[51935,0,2],[51936,0,2],[51937,0,2],[51938,0,2],[51939,0,2],[51940,0,2],[51941,0,2],[51942,0,2],[51943,0,2],[51944,0,2],[51945,0,2],[51946,0,2],[51947,0,2],[51948,0,2],[51949,0,2],[51950,0,2],[51951,0,2],[51952,0,2],[51953,0,2],[51954,0,2],[51955,0,2],[51956,0,1],[51957,0,2],[51958,0,2],[51959,0,2],[51960,0,2],[51961,0,2],[51962,0,2],[51963,0,2],[51964,0,2],[51965,0,2],[51966,0,2],[51967,0,2],[51968,0,2],[51969,0,2],[51970,0,2],[51971,0,2],[51972,0,2],[51973,0,2],[51974,0,2],[51975,0,2],[51976,0,2],[51977,0,2],[51978,0,2],[51979,0,2],[51980,0,2],[51981,0,2],[51982,0,2],[51983,0,2],[51984,0,1],[51985,0,2],[51986,0,2],[51987,0,2],[51988,0,2],[51989,0,2],[51990,0,2],[51991,0,2],[51992,0,2],[51993,0,2],[51994,0,2],[51995,0,2],[51996,0,2],[51997,0,2],[51998,0,2],[51999,0,2],[52000,0,2],[52001,0,2],[52002,0,2],[52003,0,2],[52004,0,2],[52005,0,2],[52006,0,2],[52007,0,2],[52008,0,2],[52009,0,2],[52010,0,2],[52011,0,2],[52012,0,1],[52013,0,2],[52014,0,2],[52015,0,2],[52016,0,2],[52017,0,2],[52018,0,2],[52019,0,2],[52020,0,2],[52021,0,2],[52022,0,2],[52023,0,2],[52024,0,2],[52025,0,2],[52026,0,2],[52027,0,2],[52028,0,2],[52029,0,2],[52030,0,2],[52031,0,2],[52032,0,2],[52033,0,2],[52034,0,2],[52035,0,2],[52036,0,2],[52037,0,2],[52038,0,2],[52039,0,2],[52040,0,1],[52041,0,2],[52042,0,2],[52043,0,2],[52044,0,2],[52045,0,2],[52046,0,2],[52047,0,2],[52048,0,2],[52049,0,2],[52050,0,2],[52051,0,2],[52052,0,2],[52053,0,2],[52054,0,2],[52055,0,2],[52056,0,2],[52057,0,2],[52058,0,2],[52059,0,2],[52060,0,2],[52061,0,2],[52062,0,2],[52063,0,2],[52064,0,2],[52065,0,2],[52066,0,2],[52067,0,2],[52068,0,1],[52069,0,2],[52070,0,2],[52071,0,2],[52072,0,2],[52073,0,2],[52074,0,2],[52075,0,2],[52076,0,2],[52077,0,2],[52078,0,2],[52079,0,2],[52080,0,2],[52081,0,2],[52082,0,2],[52083,0,2],[52084,0,2],[52085,0,2],[52086,0,2],[52087,0,2],[52088,0,2],[52089,0,2],[52090,0,2],[52091,0,2],[52092,0,2],[52093,0,2],[52094,0,2],[52095,0,2],[52096,0,1],[52097,0,2],[52098,0,2],[52099,0,2],[52100,0,2],[52101,0,2],[52102,0,2],[52103,0,2],[52104,0,2],[52105,0,2],[52106,0,2],[52107,0,2],[52108,0,2],[52109,0,2],[52110,0,2],[52111,0,2],[52112,0,2],[52113,0,2],[52114,0,2],[52115,0,2],[52116,0,2],[52117,0,2],[52118,0,2],[52119,0,2],[52120,0,2],[52121,0,2],[52122,0,2],[52123,0,2],[52124,0,1],[52125,0,2],[52126,0,2],[52127,0,2],[52128,0,2],[52129,0,2],[52130,0,2],[52131,0,2],[52132,0,2],[52133,0,2],[52134,0,2],[52135,0,2],[52136,0,2],[52137,0,2],[52138,0,2],[52139,0,2],[52140,0,2],[52141,0,2],[52142,0,2],[52143,0,2],[52144,0,2],[52145,0,2],[52146,0,2],[52147,0,2],[52148,0,2],[52149,0,2],[52150,0,2],[52151,0,2],[52152,0,1],[52153,0,2],[52154,0,2],[52155,0,2],[52156,0,2],[52157,0,2],[52158,0,2],[52159,0,2],[52160,0,2],[52161,0,2],[52162,0,2],[52163,0,2],[52164,0,2],[52165,0,2],[52166,0,2],[52167,0,2],[52168,0,2],[52169,0,2],[52170,0,2],[52171,0,2],[52172,0,2],[52173,0,2],[52174,0,2],[52175,0,2],[52176,0,2],[52177,0,2],[52178,0,2],[52179,0,2],[52180,0,1],[52181,0,2],[52182,0,2],[52183,0,2],[52184,0,2],[52185,0,2],[52186,0,2],[52187,0,2],[52188,0,2],[52189,0,2],[52190,0,2],[52191,0,2],[52192,0,2],[52193,0,2],[52194,0,2],[52195,0,2],[52196,0,2],[52197,0,2],[52198,0,2],[52199,0,2],[52200,0,2],[52201,0,2],[52202,0,2],[52203,0,2],[52204,0,2],[52205,0,2],[52206,0,2],[52207,0,2],[52208,0,1],[52209,0,2],[52210,0,2],[52211,0,2],[52212,0,2],[52213,0,2],[52214,0,2],[52215,0,2],[52216,0,2],[52217,0,2],[52218,0,2],[52219,0,2],[52220,0,2],[52221,0,2],[52222,0,2],[52223,0,2],[52224,0,2],[52225,0,2],[52226,0,2],[52227,0,2],[52228,0,2],[52229,0,2],[52230,0,2],[52231,0,2],[52232,0,2],[52233,0,2],[52234,0,2],[52235,0,2],[52236,0,1],[52237,0,2],[52238,0,2],[52239,0,2],[52240,0,2],[52241,0,2],[52242,0,2],[52243,0,2],[52244,0,2],[52245,0,2],[52246,0,2],[52247,0,2],[52248,0,2],[52249,0,2],[52250,0,2],[52251,0,2],[52252,0,2],[52253,0,2],[52254,0,2],[52255,0,2],[52256,0,2],[52257,0,2],[52258,0,2],[52259,0,2],[52260,0,2],[52261,0,2],[52262,0,2],[52263,0,2],[52264,0,1],[52265,0,2],[52266,0,2],[52267,0,2],[52268,0,2],[52269,0,2],[52270,0,2],[52271,0,2],[52272,0,2],[52273,0,2],[52274,0,2],[52275,0,2],[52276,0,2],[52277,0,2],[52278,0,2],[52279,0,2],[52280,0,2],[52281,0,2],[52282,0,2],[52283,0,2],[52284,0,2],[52285,0,2],[52286,0,2],[52287,0,2],[52288,0,2],[52289,0,2],[52290,0,2],[52291,0,2],[52292,0,1],[52293,0,2],[52294,0,2],[52295,0,2],[52296,0,2],[52297,0,2],[52298,0,2],[52299,0,2],[52300,0,2],[52301,0,2],[52302,0,2],[52303,0,2],[52304,0,2],[52305,0,2],[52306,0,2],[52307,0,2],[52308,0,2],[52309,0,2],[52310,0,2],[52311,0,2],[52312,0,2],[52313,0,2],[52314,0,2],[52315,0,2],[52316,0,2],[52317,0,2],[52318,0,2],[52319,0,2],[52320,0,1],[52321,0,2],[52322,0,2],[52323,0,2],[52324,0,2],[52325,0,2],[52326,0,2],[52327,0,2],[52328,0,2],[52329,0,2],[52330,0,2],[52331,0,2],[52332,0,2],[52333,0,2],[52334,0,2],[52335,0,2],[52336,0,2],[52337,0,2],[52338,0,2],[52339,0,2],[52340,0,2],[52341,0,2],[52342,0,2],[52343,0,2],[52344,0,2],[52345,0,2],[52346,0,2],[52347,0,2],[52348,0,1],[52349,0,2],[52350,0,2],[52351,0,2],[52352,0,2],[52353,0,2],[52354,0,2],[52355,0,2],[52356,0,2],[52357,0,2],[52358,0,2],[52359,0,2],[52360,0,2],[52361,0,2],[52362,0,2],[52363,0,2],[52364,0,2],[52365,0,2],[52366,0,2],[52367,0,2],[52368,0,2],[52369,0,2],[52370,0,2],[52371,0,2],[52372,0,2],[52373,0,2],[52374,0,2],[52375,0,2],[52376,0,1],[52377,0,2],[52378,0,2],[52379,0,2],[52380,0,2],[52381,0,2],[52382,0,2],[52383,0,2],[52384,0,2],[52385,0,2],[52386,0,2],[52387,0,2],[52388,0,2],[52389,0,2],[52390,0,2],[52391,0,2],[52392,0,2],[52393,0,2],[52394,0,2],[52395,0,2],[52396,0,2],[52397,0,2],[52398,0,2],[52399,0,2],[52400,0,2],[52401,0,2],[52402,0,2],[52403,0,2],[52404,0,1],[52405,0,2],[52406,0,2],[52407,0,2],[52408,0,2],[52409,0,2],[52410,0,2],[52411,0,2],[52412,0,2],[52413,0,2],[52414,0,2],[52415,0,2],[52416,0,2],[52417,0,2],[52418,0,2],[52419,0,2],[52420,0,2],[52421,0,2],[52422,0,2],[52423,0,2],[52424,0,2],[52425,0,2],[52426,0,2],[52427,0,2],[52428,0,2],[52429,0,2],[52430,0,2],[52431,0,2],[52432,0,1],[52433,0,2],[52434,0,2],[52435,0,2],[52436,0,2],[52437,0,2],[52438,0,2],[52439,0,2],[52440,0,2],[52441,0,2],[52442,0,2],[52443,0,2],[52444,0,2],[52445,0,2],[52446,0,2],[52447,0,2],[52448,0,2],[52449,0,2],[52450,0,2],[52451,0,2],[52452,0,2],[52453,0,2],[52454,0,2],[52455,0,2],[52456,0,2],[52457,0,2],[52458,0,2],[52459,0,2],[52460,0,1],[52461,0,2],[52462,0,2],[52463,0,2],[52464,0,2],[52465,0,2],[52466,0,2],[52467,0,2],[52468,0,2],[52469,0,2],[52470,0,2],[52471,0,2],[52472,0,2],[52473,0,2],[52474,0,2],[52475,0,2],[52476,0,2],[52477,0,2],[52478,0,2],[52479,0,2],[52480,0,2],[52481,0,2],[52482,0,2],[52483,0,2],[52484,0,2],[52485,0,2],[52486,0,2],[52487,0,2],[52488,0,1],[52489,0,2],[52490,0,2],[52491,0,2],[52492,0,2],[52493,0,2],[52494,0,2],[52495,0,2],[52496,0,2],[52497,0,2],[52498,0,2],[52499,0,2],[52500,0,2],[52501,0,2],[52502,0,2],[52503,0,2],[52504,0,2],[52505,0,2],[52506,0,2],[52507,0,2],[52508,0,2],[52509,0,2],[52510,0,2],[52511,0,2],[52512,0,2],[52513,0,2],[52514,0,2],[52515,0,2],[52516,0,1],[52517,0,2],[52518,0,2],[52519,0,2],[52520,0,2],[52521,0,2],[52522,0,2],[52523,0,2],[52524,0,2],[52525,0,2],[52526,0,2],[52527,0,2],[52528,0,2],[52529,0,2],[52530,0,2],[52531,0,2],[52532,0,2],[52533,0,2],[52534,0,2],[52535,0,2],[52536,0,2],[52537,0,2],[52538,0,2],[52539,0,2],[52540,0,2],[52541,0,2],[52542,0,2],[52543,0,2],[52544,0,1],[52545,0,2],[52546,0,2],[52547,0,2],[52548,0,2],[52549,0,2],[52550,0,2],[52551,0,2],[52552,0,2],[52553,0,2],[52554,0,2],[52555,0,2],[52556,0,2],[52557,0,2],[52558,0,2],[52559,0,2],[52560,0,2],[52561,0,2],[52562,0,2],[52563,0,2],[52564,0,2],[52565,0,2],[52566,0,2],[52567,0,2],[52568,0,2],[52569,0,2],[52570,0,2],[52571,0,2],[52572,0,1],[52573,0,2],[52574,0,2],[52575,0,2],[52576,0,2],[52577,0,2],[52578,0,2],[52579,0,2],[52580,0,2],[52581,0,2],[52582,0,2],[52583,0,2],[52584,0,2],[52585,0,2],[52586,0,2],[52587,0,2],[52588,0,2],[52589,0,2],[52590,0,2],[52591,0,2],[52592,0,2],[52593,0,2],[52594,0,2],[52595,0,2],[52596,0,2],[52597,0,2],[52598,0,2],[52599,0,2],[52600,0,1],[52601,0,2],[52602,0,2],[52603,0,2],[52604,0,2],[52605,0,2],[52606,0,2],[52607,0,2],[52608,0,2],[52609,0,2],[52610,0,2],[52611,0,2],[52612,0,2],[52613,0,2],[52614,0,2],[52615,0,2],[52616,0,2],[52617,0,2],[52618,0,2],[52619,0,2],[52620,0,2],[52621,0,2],[52622,0,2],[52623,0,2],[52624,0,2],[52625,0,2],[52626,0,2],[52627,0,2],[52628,0,1],[52629,0,2],[52630,0,2],[52631,0,2],[52632,0,2],[52633,0,2],[52634,0,2],[52635,0,2],[52636,0,2],[52637,0,2],[52638,0,2],[52639,0,2],[52640,0,2],[52641,0,2],[52642,0,2],[52643,0,2],[52644,0,2],[52645,0,2],[52646,0,2],[52647,0,2],[52648,0,2],[52649,0,2],[52650,0,2],[52651,0,2],[52652,0,2],[52653,0,2],[52654,0,2],[52655,0,2],[52656,0,1],[52657,0,2],[52658,0,2],[52659,0,2],[52660,0,2],[52661,0,2],[52662,0,2],[52663,0,2],[52664,0,2],[52665,0,2],[52666,0,2],[52667,0,2],[52668,0,2],[52669,0,2],[52670,0,2],[52671,0,2],[52672,0,2],[52673,0,2],[52674,0,2],[52675,0,2],[52676,0,2],[52677,0,2],[52678,0,2],[52679,0,2],[52680,0,2],[52681,0,2],[52682,0,2],[52683,0,2],[52684,0,1],[52685,0,2],[52686,0,2],[52687,0,2],[52688,0,2],[52689,0,2],[52690,0,2],[52691,0,2],[52692,0,2],[52693,0,2],[52694,0,2],[52695,0,2],[52696,0,2],[52697,0,2],[52698,0,2],[52699,0,2],[52700,0,2],[52701,0,2],[52702,0,2],[52703,0,2],[52704,0,2],[52705,0,2],[52706,0,2],[52707,0,2],[52708,0,2],[52709,0,2],[52710,0,2],[52711,0,2],[52712,0,1],[52713,0,2],[52714,0,2],[52715,0,2],[52716,0,2],[52717,0,2],[52718,0,2],[52719,0,2],[52720,0,2],[52721,0,2],[52722,0,2],[52723,0,2],[52724,0,2],[52725,0,2],[52726,0,2],[52727,0,2],[52728,0,2],[52729,0,2],[52730,0,2],[52731,0,2],[52732,0,2],[52733,0,2],[52734,0,2],[52735,0,2],[52736,0,2],[52737,0,2],[52738,0,2],[52739,0,2],[52740,0,1],[52741,0,2],[52742,0,2],[52743,0,2],[52744,0,2],[52745,0,2],[52746,0,2],[52747,0,2],[52748,0,2],[52749,0,2],[52750,0,2],[52751,0,2],[52752,0,2],[52753,0,2],[52754,0,2],[52755,0,2],[52756,0,2],[52757,0,2],[52758,0,2],[52759,0,2],[52760,0,2],[52761,0,2],[52762,0,2],[52763,0,2],[52764,0,2],[52765,0,2],[52766,0,2],[52767,0,2],[52768,0,1],[52769,0,2],[52770,0,2],[52771,0,2],[52772,0,2],[52773,0,2],[52774,0,2],[52775,0,2],[52776,0,2],[52777,0,2],[52778,0,2],[52779,0,2],[52780,0,2],[52781,0,2],[52782,0,2],[52783,0,2],[52784,0,2],[52785,0,2],[52786,0,2],[52787,0,2],[52788,0,2],[52789,0,2],[52790,0,2],[52791,0,2],[52792,0,2],[52793,0,2],[52794,0,2],[52795,0,2],[52796,0,1],[52797,0,2],[52798,0,2],[52799,0,2],[52800,0,2],[52801,0,2],[52802,0,2],[52803,0,2],[52804,0,2],[52805,0,2],[52806,0,2],[52807,0,2],[52808,0,2],[52809,0,2],[52810,0,2],[52811,0,2],[52812,0,2],[52813,0,2],[52814,0,2],[52815,0,2],[52816,0,2],[52817,0,2],[52818,0,2],[52819,0,2],[52820,0,2],[52821,0,2],[52822,0,2],[52823,0,2],[52824,0,1],[52825,0,2],[52826,0,2],[52827,0,2],[52828,0,2],[52829,0,2],[52830,0,2],[52831,0,2],[52832,0,2],[52833,0,2],[52834,0,2],[52835,0,2],[52836,0,2],[52837,0,2],[52838,0,2],[52839,0,2],[52840,0,2],[52841,0,2],[52842,0,2],[52843,0,2],[52844,0,2],[52845,0,2],[52846,0,2],[52847,0,2],[52848,0,2],[52849,0,2],[52850,0,2],[52851,0,2],[52852,0,1],[52853,0,2],[52854,0,2],[52855,0,2],[52856,0,2],[52857,0,2],[52858,0,2],[52859,0,2],[52860,0,2],[52861,0,2],[52862,0,2],[52863,0,2],[52864,0,2],[52865,0,2],[52866,0,2],[52867,0,2],[52868,0,2],[52869,0,2],[52870,0,2],[52871,0,2],[52872,0,2],[52873,0,2],[52874,0,2],[52875,0,2],[52876,0,2],[52877,0,2],[52878,0,2],[52879,0,2],[52880,0,1],[52881,0,2],[52882,0,2],[52883,0,2],[52884,0,2],[52885,0,2],[52886,0,2],[52887,0,2],[52888,0,2],[52889,0,2],[52890,0,2],[52891,0,2],[52892,0,2],[52893,0,2],[52894,0,2],[52895,0,2],[52896,0,2],[52897,0,2],[52898,0,2],[52899,0,2],[52900,0,2],[52901,0,2],[52902,0,2],[52903,0,2],[52904,0,2],[52905,0,2],[52906,0,2],[52907,0,2],[52908,0,1],[52909,0,2],[52910,0,2],[52911,0,2],[52912,0,2],[52913,0,2],[52914,0,2],[52915,0,2],[52916,0,2],[52917,0,2],[52918,0,2],[52919,0,2],[52920,0,2],[52921,0,2],[52922,0,2],[52923,0,2],[52924,0,2],[52925,0,2],[52926,0,2],[52927,0,2],[52928,0,2],[52929,0,2],[52930,0,2],[52931,0,2],[52932,0,2],[52933,0,2],[52934,0,2],[52935,0,2],[52936,0,1],[52937,0,2],[52938,0,2],[52939,0,2],[52940,0,2],[52941,0,2],[52942,0,2],[52943,0,2],[52944,0,2],[52945,0,2],[52946,0,2],[52947,0,2],[52948,0,2],[52949,0,2],[52950,0,2],[52951,0,2],[52952,0,2],[52953,0,2],[52954,0,2],[52955,0,2],[52956,0,2],[52957,0,2],[52958,0,2],[52959,0,2],[52960,0,2],[52961,0,2],[52962,0,2],[52963,0,2],[52964,0,1],[52965,0,2],[52966,0,2],[52967,0,2],[52968,0,2],[52969,0,2],[52970,0,2],[52971,0,2],[52972,0,2],[52973,0,2],[52974,0,2],[52975,0,2],[52976,0,2],[52977,0,2],[52978,0,2],[52979,0,2],[52980,0,2],[52981,0,2],[52982,0,2],[52983,0,2],[52984,0,2],[52985,0,2],[52986,0,2],[52987,0,2],[52988,0,2],[52989,0,2],[52990,0,2],[52991,0,2],[52992,0,1],[52993,0,2],[52994,0,2],[52995,0,2],[52996,0,2],[52997,0,2],[52998,0,2],[52999,0,2],[53000,0,2],[53001,0,2],[53002,0,2],[53003,0,2],[53004,0,2],[53005,0,2],[53006,0,2],[53007,0,2],[53008,0,2],[53009,0,2],[53010,0,2],[53011,0,2],[53012,0,2],[53013,0,2],[53014,0,2],[53015,0,2],[53016,0,2],[53017,0,2],[53018,0,2],[53019,0,2],[53020,0,1],[53021,0,2],[53022,0,2],[53023,0,2],[53024,0,2],[53025,0,2],[53026,0,2],[53027,0,2],[53028,0,2],[53029,0,2],[53030,0,2],[53031,0,2],[53032,0,2],[53033,0,2],[53034,0,2],[53035,0,2],[53036,0,2],[53037,0,2],[53038,0,2],[53039,0,2],[53040,0,2],[53041,0,2],[53042,0,2],[53043,0,2],[53044,0,2],[53045,0,2],[53046,0,2],[53047,0,2],[53048,0,1],[53049,0,2],[53050,0,2],[53051,0,2],[53052,0,2],[53053,0,2],[53054,0,2],[53055,0,2],[53056,0,2],[53057,0,2],[53058,0,2],[53059,0,2],[53060,0,2],[53061,0,2],[53062,0,2],[53063,0,2],[53064,0,2],[53065,0,2],[53066,0,2],[53067,0,2],[53068,0,2],[53069,0,2],[53070,0,2],[53071,0,2],[53072,0,2],[53073,0,2],[53074,0,2],[53075,0,2],[53076,0,1],[53077,0,2],[53078,0,2],[53079,0,2],[53080,0,2],[53081,0,2],[53082,0,2],[53083,0,2],[53084,0,2],[53085,0,2],[53086,0,2],[53087,0,2],[53088,0,2],[53089,0,2],[53090,0,2],[53091,0,2],[53092,0,2],[53093,0,2],[53094,0,2],[53095,0,2],[53096,0,2],[53097,0,2],[53098,0,2],[53099,0,2],[53100,0,2],[53101,0,2],[53102,0,2],[53103,0,2],[53104,0,1],[53105,0,2],[53106,0,2],[53107,0,2],[53108,0,2],[53109,0,2],[53110,0,2],[53111,0,2],[53112,0,2],[53113,0,2],[53114,0,2],[53115,0,2],[53116,0,2],[53117,0,2],[53118,0,2],[53119,0,2],[53120,0,2],[53121,0,2],[53122,0,2],[53123,0,2],[53124,0,2],[53125,0,2],[53126,0,2],[53127,0,2],[53128,0,2],[53129,0,2],[53130,0,2],[53131,0,2],[53132,0,1],[53133,0,2],[53134,0,2],[53135,0,2],[53136,0,2],[53137,0,2],[53138,0,2],[53139,0,2],[53140,0,2],[53141,0,2],[53142,0,2],[53143,0,2],[53144,0,2],[53145,0,2],[53146,0,2],[53147,0,2],[53148,0,2],[53149,0,2],[53150,0,2],[53151,0,2],[53152,0,2],[53153,0,2],[53154,0,2],[53155,0,2],[53156,0,2],[53157,0,2],[53158,0,2],[53159,0,2],[53160,0,1],[53161,0,2],[53162,0,2],[53163,0,2],[53164,0,2],[53165,0,2],[53166,0,2],[53167,0,2],[53168,0,2],[53169,0,2],[53170,0,2],[53171,0,2],[53172,0,2],[53173,0,2],[53174,0,2],[53175,0,2],[53176,0,2],[53177,0,2],[53178,0,2],[53179,0,2],[53180,0,2],[53181,0,2],[53182,0,2],[53183,0,2],[53184,0,2],[53185,0,2],[53186,0,2],[53187,0,2],[53188,0,1],[53189,0,2],[53190,0,2],[53191,0,2],[53192,0,2],[53193,0,2],[53194,0,2],[53195,0,2],[53196,0,2],[53197,0,2],[53198,0,2],[53199,0,2],[53200,0,2],[53201,0,2],[53202,0,2],[53203,0,2],[53204,0,2],[53205,0,2],[53206,0,2],[53207,0,2],[53208,0,2],[53209,0,2],[53210,0,2],[53211,0,2],[53212,0,2],[53213,0,2],[53214,0,2],[53215,0,2],[53216,0,1],[53217,0,2],[53218,0,2],[53219,0,2],[53220,0,2],[53221,0,2],[53222,0,2],[53223,0,2],[53224,0,2],[53225,0,2],[53226,0,2],[53227,0,2],[53228,0,2],[53229,0,2],[53230,0,2],[53231,0,2],[53232,0,2],[53233,0,2],[53234,0,2],[53235,0,2],[53236,0,2],[53237,0,2],[53238,0,2],[53239,0,2],[53240,0,2],[53241,0,2],[53242,0,2],[53243,0,2],[53244,0,1],[53245,0,2],[53246,0,2],[53247,0,2],[53248,0,2],[53249,0,2],[53250,0,2],[53251,0,2],[53252,0,2],[53253,0,2],[53254,0,2],[53255,0,2],[53256,0,2],[53257,0,2],[53258,0,2],[53259,0,2],[53260,0,2],[53261,0,2],[53262,0,2],[53263,0,2],[53264,0,2],[53265,0,2],[53266,0,2],[53267,0,2],[53268,0,2],[53269,0,2],[53270,0,2],[53271,0,2],[53272,0,1],[53273,0,2],[53274,0,2],[53275,0,2],[53276,0,2],[53277,0,2],[53278,0,2],[53279,0,2],[53280,0,2],[53281,0,2],[53282,0,2],[53283,0,2],[53284,0,2],[53285,0,2],[53286,0,2],[53287,0,2],[53288,0,2],[53289,0,2],[53290,0,2],[53291,0,2],[53292,0,2],[53293,0,2],[53294,0,2],[53295,0,2],[53296,0,2],[53297,0,2],[53298,0,2],[53299,0,2],[53300,0,1],[53301,0,2],[53302,0,2],[53303,0,2],[53304,0,2],[53305,0,2],[53306,0,2],[53307,0,2],[53308,0,2],[53309,0,2],[53310,0,2],[53311,0,2],[53312,0,2],[53313,0,2],[53314,0,2],[53315,0,2],[53316,0,2],[53317,0,2],[53318,0,2],[53319,0,2],[53320,0,2],[53321,0,2],[53322,0,2],[53323,0,2],[53324,0,2],[53325,0,2],[53326,0,2],[53327,0,2],[53328,0,1],[53329,0,2],[53330,0,2],[53331,0,2],[53332,0,2],[53333,0,2],[53334,0,2],[53335,0,2],[53336,0,2],[53337,0,2],[53338,0,2],[53339,0,2],[53340,0,2],[53341,0,2],[53342,0,2],[53343,0,2],[53344,0,2],[53345,0,2],[53346,0,2],[53347,0,2],[53348,0,2],[53349,0,2],[53350,0,2],[53351,0,2],[53352,0,2],[53353,0,2],[53354,0,2],[53355,0,2],[53356,0,1],[53357,0,2],[53358,0,2],[53359,0,2],[53360,0,2],[53361,0,2],[53362,0,2],[53363,0,2],[53364,0,2],[53365,0,2],[53366,0,2],[53367,0,2],[53368,0,2],[53369,0,2],[53370,0,2],[53371,0,2],[53372,0,2],[53373,0,2],[53374,0,2],[53375,0,2],[53376,0,2],[53377,0,2],[53378,0,2],[53379,0,2],[53380,0,2],[53381,0,2],[53382,0,2],[53383,0,2],[53384,0,1],[53385,0,2],[53386,0,2],[53387,0,2],[53388,0,2],[53389,0,2],[53390,0,2],[53391,0,2],[53392,0,2],[53393,0,2],[53394,0,2],[53395,0,2],[53396,0,2],[53397,0,2],[53398,0,2],[53399,0,2],[53400,0,2],[53401,0,2],[53402,0,2],[53403,0,2],[53404,0,2],[53405,0,2],[53406,0,2],[53407,0,2],[53408,0,2],[53409,0,2],[53410,0,2],[53411,0,2],[53412,0,1],[53413,0,2],[53414,0,2],[53415,0,2],[53416,0,2],[53417,0,2],[53418,0,2],[53419,0,2],[53420,0,2],[53421,0,2],[53422,0,2],[53423,0,2],[53424,0,2],[53425,0,2],[53426,0,2],[53427,0,2],[53428,0,2],[53429,0,2],[53430,0,2],[53431,0,2],[53432,0,2],[53433,0,2],[53434,0,2],[53435,0,2],[53436,0,2],[53437,0,2],[53438,0,2],[53439,0,2],[53440,0,1],[53441,0,2],[53442,0,2],[53443,0,2],[53444,0,2],[53445,0,2],[53446,0,2],[53447,0,2],[53448,0,2],[53449,0,2],[53450,0,2],[53451,0,2],[53452,0,2],[53453,0,2],[53454,0,2],[53455,0,2],[53456,0,2],[53457,0,2],[53458,0,2],[53459,0,2],[53460,0,2],[53461,0,2],[53462,0,2],[53463,0,2],[53464,0,2],[53465,0,2],[53466,0,2],[53467,0,2],[53468,0,1],[53469,0,2],[53470,0,2],[53471,0,2],[53472,0,2],[53473,0,2],[53474,0,2],[53475,0,2],[53476,0,2],[53477,0,2],[53478,0,2],[53479,0,2],[53480,0,2],[53481,0,2],[53482,0,2],[53483,0,2],[53484,0,2],[53485,0,2],[53486,0,2],[53487,0,2],[53488,0,2],[53489,0,2],[53490,0,2],[53491,0,2],[53492,0,2],[53493,0,2],[53494,0,2],[53495,0,2],[53496,0,1],[53497,0,2],[53498,0,2],[53499,0,2],[53500,0,2],[53501,0,2],[53502,0,2],[53503,0,2],[53504,0,2],[53505,0,2],[53506,0,2],[53507,0,2],[53508,0,2],[53509,0,2],[53510,0,2],[53511,0,2],[53512,0,2],[53513,0,2],[53514,0,2],[53515,0,2],[53516,0,2],[53517,0,2],[53518,0,2],[53519,0,2],[53520,0,2],[53521,0,2],[53522,0,2],[53523,0,2],[53524,0,1],[53525,0,2],[53526,0,2],[53527,0,2],[53528,0,2],[53529,0,2],[53530,0,2],[53531,0,2],[53532,0,2],[53533,0,2],[53534,0,2],[53535,0,2],[53536,0,2],[53537,0,2],[53538,0,2],[53539,0,2],[53540,0,2],[53541,0,2],[53542,0,2],[53543,0,2],[53544,0,2],[53545,0,2],[53546,0,2],[53547,0,2],[53548,0,2],[53549,0,2],[53550,0,2],[53551,0,2],[53552,0,1],[53553,0,2],[53554,0,2],[53555,0,2],[53556,0,2],[53557,0,2],[53558,0,2],[53559,0,2],[53560,0,2],[53561,0,2],[53562,0,2],[53563,0,2],[53564,0,2],[53565,0,2],[53566,0,2],[53567,0,2],[53568,0,2],[53569,0,2],[53570,0,2],[53571,0,2],[53572,0,2],[53573,0,2],[53574,0,2],[53575,0,2],[53576,0,2],[53577,0,2],[53578,0,2],[53579,0,2],[53580,0,1],[53581,0,2],[53582,0,2],[53583,0,2],[53584,0,2],[53585,0,2],[53586,0,2],[53587,0,2],[53588,0,2],[53589,0,2],[53590,0,2],[53591,0,2],[53592,0,2],[53593,0,2],[53594,0,2],[53595,0,2],[53596,0,2],[53597,0,2],[53598,0,2],[53599,0,2],[53600,0,2],[53601,0,2],[53602,0,2],[53603,0,2],[53604,0,2],[53605,0,2],[53606,0,2],[53607,0,2],[53608,0,1],[53609,0,2],[53610,0,2],[53611,0,2],[53612,0,2],[53613,0,2],[53614,0,2],[53615,0,2],[53616,0,2],[53617,0,2],[53618,0,2],[53619,0,2],[53620,0,2],[53621,0,2],[53622,0,2],[53623,0,2],[53624,0,2],[53625,0,2],[53626,0,2],[53627,0,2],[53628,0,2],[53629,0,2],[53630,0,2],[53631,0,2],[53632,0,2],[53633,0,2],[53634,0,2],[53635,0,2],[53636,0,1],[53637,0,2],[53638,0,2],[53639,0,2],[53640,0,2],[53641,0,2],[53642,0,2],[53643,0,2],[53644,0,2],[53645,0,2],[53646,0,2],[53647,0,2],[53648,0,2],[53649,0,2],[53650,0,2],[53651,0,2],[53652,0,2],[53653,0,2],[53654,0,2],[53655,0,2],[53656,0,2],[53657,0,2],[53658,0,2],[53659,0,2],[53660,0,2],[53661,0,2],[53662,0,2],[53663,0,2],[53664,0,1],[53665,0,2],[53666,0,2],[53667,0,2],[53668,0,2],[53669,0,2],[53670,0,2],[53671,0,2],[53672,0,2],[53673,0,2],[53674,0,2],[53675,0,2],[53676,0,2],[53677,0,2],[53678,0,2],[53679,0,2],[53680,0,2],[53681,0,2],[53682,0,2],[53683,0,2],[53684,0,2],[53685,0,2],[53686,0,2],[53687,0,2],[53688,0,2],[53689,0,2],[53690,0,2],[53691,0,2],[53692,0,1],[53693,0,2],[53694,0,2],[53695,0,2],[53696,0,2],[53697,0,2],[53698,0,2],[53699,0,2],[53700,0,2],[53701,0,2],[53702,0,2],[53703,0,2],[53704,0,2],[53705,0,2],[53706,0,2],[53707,0,2],[53708,0,2],[53709,0,2],[53710,0,2],[53711,0,2],[53712,0,2],[53713,0,2],[53714,0,2],[53715,0,2],[53716,0,2],[53717,0,2],[53718,0,2],[53719,0,2],[53720,0,1],[53721,0,2],[53722,0,2],[53723,0,2],[53724,0,2],[53725,0,2],[53726,0,2],[53727,0,2],[53728,0,2],[53729,0,2],[53730,0,2],[53731,0,2],[53732,0,2],[53733,0,2],[53734,0,2],[53735,0,2],[53736,0,2],[53737,0,2],[53738,0,2],[53739,0,2],[53740,0,2],[53741,0,2],[53742,0,2],[53743,0,2],[53744,0,2],[53745,0,2],[53746,0,2],[53747,0,2],[53748,0,1],[53749,0,2],[53750,0,2],[53751,0,2],[53752,0,2],[53753,0,2],[53754,0,2],[53755,0,2],[53756,0,2],[53757,0,2],[53758,0,2],[53759,0,2],[53760,0,2],[53761,0,2],[53762,0,2],[53763,0,2],[53764,0,2],[53765,0,2],[53766,0,2],[53767,0,2],[53768,0,2],[53769,0,2],[53770,0,2],[53771,0,2],[53772,0,2],[53773,0,2],[53774,0,2],[53775,0,2],[53776,0,1],[53777,0,2],[53778,0,2],[53779,0,2],[53780,0,2],[53781,0,2],[53782,0,2],[53783,0,2],[53784,0,2],[53785,0,2],[53786,0,2],[53787,0,2],[53788,0,2],[53789,0,2],[53790,0,2],[53791,0,2],[53792,0,2],[53793,0,2],[53794,0,2],[53795,0,2],[53796,0,2],[53797,0,2],[53798,0,2],[53799,0,2],[53800,0,2],[53801,0,2],[53802,0,2],[53803,0,2],[53804,0,1],[53805,0,2],[53806,0,2],[53807,0,2],[53808,0,2],[53809,0,2],[53810,0,2],[53811,0,2],[53812,0,2],[53813,0,2],[53814,0,2],[53815,0,2],[53816,0,2],[53817,0,2],[53818,0,2],[53819,0,2],[53820,0,2],[53821,0,2],[53822,0,2],[53823,0,2],[53824,0,2],[53825,0,2],[53826,0,2],[53827,0,2],[53828,0,2],[53829,0,2],[53830,0,2],[53831,0,2],[53832,0,1],[53833,0,2],[53834,0,2],[53835,0,2],[53836,0,2],[53837,0,2],[53838,0,2],[53839,0,2],[53840,0,2],[53841,0,2],[53842,0,2],[53843,0,2],[53844,0,2],[53845,0,2],[53846,0,2],[53847,0,2],[53848,0,2],[53849,0,2],[53850,0,2],[53851,0,2],[53852,0,2],[53853,0,2],[53854,0,2],[53855,0,2],[53856,0,2],[53857,0,2],[53858,0,2],[53859,0,2],[53860,0,1],[53861,0,2],[53862,0,2],[53863,0,2],[53864,0,2],[53865,0,2],[53866,0,2],[53867,0,2],[53868,0,2],[53869,0,2],[53870,0,2],[53871,0,2],[53872,0,2],[53873,0,2],[53874,0,2],[53875,0,2],[53876,0,2],[53877,0,2],[53878,0,2],[53879,0,2],[53880,0,2],[53881,0,2],[53882,0,2],[53883,0,2],[53884,0,2],[53885,0,2],[53886,0,2],[53887,0,2],[53888,0,1],[53889,0,2],[53890,0,2],[53891,0,2],[53892,0,2],[53893,0,2],[53894,0,2],[53895,0,2],[53896,0,2],[53897,0,2],[53898,0,2],[53899,0,2],[53900,0,2],[53901,0,2],[53902,0,2],[53903,0,2],[53904,0,2],[53905,0,2],[53906,0,2],[53907,0,2],[53908,0,2],[53909,0,2],[53910,0,2],[53911,0,2],[53912,0,2],[53913,0,2],[53914,0,2],[53915,0,2],[53916,0,1],[53917,0,2],[53918,0,2],[53919,0,2],[53920,0,2],[53921,0,2],[53922,0,2],[53923,0,2],[53924,0,2],[53925,0,2],[53926,0,2],[53927,0,2],[53928,0,2],[53929,0,2],[53930,0,2],[53931,0,2],[53932,0,2],[53933,0,2],[53934,0,2],[53935,0,2],[53936,0,2],[53937,0,2],[53938,0,2],[53939,0,2],[53940,0,2],[53941,0,2],[53942,0,2],[53943,0,2],[53944,0,1],[53945,0,2],[53946,0,2],[53947,0,2],[53948,0,2],[53949,0,2],[53950,0,2],[53951,0,2],[53952,0,2],[53953,0,2],[53954,0,2],[53955,0,2],[53956,0,2],[53957,0,2],[53958,0,2],[53959,0,2],[53960,0,2],[53961,0,2],[53962,0,2],[53963,0,2],[53964,0,2],[53965,0,2],[53966,0,2],[53967,0,2],[53968,0,2],[53969,0,2],[53970,0,2],[53971,0,2],[53972,0,1],[53973,0,2],[53974,0,2],[53975,0,2],[53976,0,2],[53977,0,2],[53978,0,2],[53979,0,2],[53980,0,2],[53981,0,2],[53982,0,2],[53983,0,2],[53984,0,2],[53985,0,2],[53986,0,2],[53987,0,2],[53988,0,2],[53989,0,2],[53990,0,2],[53991,0,2],[53992,0,2],[53993,0,2],[53994,0,2],[53995,0,2],[53996,0,2],[53997,0,2],[53998,0,2],[53999,0,2],[54000,0,1],[54001,0,2],[54002,0,2],[54003,0,2],[54004,0,2],[54005,0,2],[54006,0,2],[54007,0,2],[54008,0,2],[54009,0,2],[54010,0,2],[54011,0,2],[54012,0,2],[54013,0,2],[54014,0,2],[54015,0,2],[54016,0,2],[54017,0,2],[54018,0,2],[54019,0,2],[54020,0,2],[54021,0,2],[54022,0,2],[54023,0,2],[54024,0,2],[54025,0,2],[54026,0,2],[54027,0,2],[54028,0,1],[54029,0,2],[54030,0,2],[54031,0,2],[54032,0,2],[54033,0,2],[54034,0,2],[54035,0,2],[54036,0,2],[54037,0,2],[54038,0,2],[54039,0,2],[54040,0,2],[54041,0,2],[54042,0,2],[54043,0,2],[54044,0,2],[54045,0,2],[54046,0,2],[54047,0,2],[54048,0,2],[54049,0,2],[54050,0,2],[54051,0,2],[54052,0,2],[54053,0,2],[54054,0,2],[54055,0,2],[54056,0,1],[54057,0,2],[54058,0,2],[54059,0,2],[54060,0,2],[54061,0,2],[54062,0,2],[54063,0,2],[54064,0,2],[54065,0,2],[54066,0,2],[54067,0,2],[54068,0,2],[54069,0,2],[54070,0,2],[54071,0,2],[54072,0,2],[54073,0,2],[54074,0,2],[54075,0,2],[54076,0,2],[54077,0,2],[54078,0,2],[54079,0,2],[54080,0,2],[54081,0,2],[54082,0,2],[54083,0,2],[54084,0,1],[54085,0,2],[54086,0,2],[54087,0,2],[54088,0,2],[54089,0,2],[54090,0,2],[54091,0,2],[54092,0,2],[54093,0,2],[54094,0,2],[54095,0,2],[54096,0,2],[54097,0,2],[54098,0,2],[54099,0,2],[54100,0,2],[54101,0,2],[54102,0,2],[54103,0,2],[54104,0,2],[54105,0,2],[54106,0,2],[54107,0,2],[54108,0,2],[54109,0,2],[54110,0,2],[54111,0,2],[54112,0,1],[54113,0,2],[54114,0,2],[54115,0,2],[54116,0,2],[54117,0,2],[54118,0,2],[54119,0,2],[54120,0,2],[54121,0,2],[54122,0,2],[54123,0,2],[54124,0,2],[54125,0,2],[54126,0,2],[54127,0,2],[54128,0,2],[54129,0,2],[54130,0,2],[54131,0,2],[54132,0,2],[54133,0,2],[54134,0,2],[54135,0,2],[54136,0,2],[54137,0,2],[54138,0,2],[54139,0,2],[54140,0,1],[54141,0,2],[54142,0,2],[54143,0,2],[54144,0,2],[54145,0,2],[54146,0,2],[54147,0,2],[54148,0,2],[54149,0,2],[54150,0,2],[54151,0,2],[54152,0,2],[54153,0,2],[54154,0,2],[54155,0,2],[54156,0,2],[54157,0,2],[54158,0,2],[54159,0,2],[54160,0,2],[54161,0,2],[54162,0,2],[54163,0,2],[54164,0,2],[54165,0,2],[54166,0,2],[54167,0,2],[54168,0,1],[54169,0,2],[54170,0,2],[54171,0,2],[54172,0,2],[54173,0,2],[54174,0,2],[54175,0,2],[54176,0,2],[54177,0,2],[54178,0,2],[54179,0,2],[54180,0,2],[54181,0,2],[54182,0,2],[54183,0,2],[54184,0,2],[54185,0,2],[54186,0,2],[54187,0,2],[54188,0,2],[54189,0,2],[54190,0,2],[54191,0,2],[54192,0,2],[54193,0,2],[54194,0,2],[54195,0,2],[54196,0,1],[54197,0,2],[54198,0,2],[54199,0,2],[54200,0,2],[54201,0,2],[54202,0,2],[54203,0,2],[54204,0,2],[54205,0,2],[54206,0,2],[54207,0,2],[54208,0,2],[54209,0,2],[54210,0,2],[54211,0,2],[54212,0,2],[54213,0,2],[54214,0,2],[54215,0,2],[54216,0,2],[54217,0,2],[54218,0,2],[54219,0,2],[54220,0,2],[54221,0,2],[54222,0,2],[54223,0,2],[54224,0,1],[54225,0,2],[54226,0,2],[54227,0,2],[54228,0,2],[54229,0,2],[54230,0,2],[54231,0,2],[54232,0,2],[54233,0,2],[54234,0,2],[54235,0,2],[54236,0,2],[54237,0,2],[54238,0,2],[54239,0,2],[54240,0,2],[54241,0,2],[54242,0,2],[54243,0,2],[54244,0,2],[54245,0,2],[54246,0,2],[54247,0,2],[54248,0,2],[54249,0,2],[54250,0,2],[54251,0,2],[54252,0,1],[54253,0,2],[54254,0,2],[54255,0,2],[54256,0,2],[54257,0,2],[54258,0,2],[54259,0,2],[54260,0,2],[54261,0,2],[54262,0,2],[54263,0,2],[54264,0,2],[54265,0,2],[54266,0,2],[54267,0,2],[54268,0,2],[54269,0,2],[54270,0,2],[54271,0,2],[54272,0,2],[54273,0,2],[54274,0,2],[54275,0,2],[54276,0,2],[54277,0,2],[54278,0,2],[54279,0,2],[54280,0,1],[54281,0,2],[54282,0,2],[54283,0,2],[54284,0,2],[54285,0,2],[54286,0,2],[54287,0,2],[54288,0,2],[54289,0,2],[54290,0,2],[54291,0,2],[54292,0,2],[54293,0,2],[54294,0,2],[54295,0,2],[54296,0,2],[54297,0,2],[54298,0,2],[54299,0,2],[54300,0,2],[54301,0,2],[54302,0,2],[54303,0,2],[54304,0,2],[54305,0,2],[54306,0,2],[54307,0,2],[54308,0,1],[54309,0,2],[54310,0,2],[54311,0,2],[54312,0,2],[54313,0,2],[54314,0,2],[54315,0,2],[54316,0,2],[54317,0,2],[54318,0,2],[54319,0,2],[54320,0,2],[54321,0,2],[54322,0,2],[54323,0,2],[54324,0,2],[54325,0,2],[54326,0,2],[54327,0,2],[54328,0,2],[54329,0,2],[54330,0,2],[54331,0,2],[54332,0,2],[54333,0,2],[54334,0,2],[54335,0,2],[54336,0,1],[54337,0,2],[54338,0,2],[54339,0,2],[54340,0,2],[54341,0,2],[54342,0,2],[54343,0,2],[54344,0,2],[54345,0,2],[54346,0,2],[54347,0,2],[54348,0,2],[54349,0,2],[54350,0,2],[54351,0,2],[54352,0,2],[54353,0,2],[54354,0,2],[54355,0,2],[54356,0,2],[54357,0,2],[54358,0,2],[54359,0,2],[54360,0,2],[54361,0,2],[54362,0,2],[54363,0,2],[54364,0,1],[54365,0,2],[54366,0,2],[54367,0,2],[54368,0,2],[54369,0,2],[54370,0,2],[54371,0,2],[54372,0,2],[54373,0,2],[54374,0,2],[54375,0,2],[54376,0,2],[54377,0,2],[54378,0,2],[54379,0,2],[54380,0,2],[54381,0,2],[54382,0,2],[54383,0,2],[54384,0,2],[54385,0,2],[54386,0,2],[54387,0,2],[54388,0,2],[54389,0,2],[54390,0,2],[54391,0,2],[54392,0,1],[54393,0,2],[54394,0,2],[54395,0,2],[54396,0,2],[54397,0,2],[54398,0,2],[54399,0,2],[54400,0,2],[54401,0,2],[54402,0,2],[54403,0,2],[54404,0,2],[54405,0,2],[54406,0,2],[54407,0,2],[54408,0,2],[54409,0,2],[54410,0,2],[54411,0,2],[54412,0,2],[54413,0,2],[54414,0,2],[54415,0,2],[54416,0,2],[54417,0,2],[54418,0,2],[54419,0,2],[54420,0,1],[54421,0,2],[54422,0,2],[54423,0,2],[54424,0,2],[54425,0,2],[54426,0,2],[54427,0,2],[54428,0,2],[54429,0,2],[54430,0,2],[54431,0,2],[54432,0,2],[54433,0,2],[54434,0,2],[54435,0,2],[54436,0,2],[54437,0,2],[54438,0,2],[54439,0,2],[54440,0,2],[54441,0,2],[54442,0,2],[54443,0,2],[54444,0,2],[54445,0,2],[54446,0,2],[54447,0,2],[54448,0,1],[54449,0,2],[54450,0,2],[54451,0,2],[54452,0,2],[54453,0,2],[54454,0,2],[54455,0,2],[54456,0,2],[54457,0,2],[54458,0,2],[54459,0,2],[54460,0,2],[54461,0,2],[54462,0,2],[54463,0,2],[54464,0,2],[54465,0,2],[54466,0,2],[54467,0,2],[54468,0,2],[54469,0,2],[54470,0,2],[54471,0,2],[54472,0,2],[54473,0,2],[54474,0,2],[54475,0,2],[54476,0,1],[54477,0,2],[54478,0,2],[54479,0,2],[54480,0,2],[54481,0,2],[54482,0,2],[54483,0,2],[54484,0,2],[54485,0,2],[54486,0,2],[54487,0,2],[54488,0,2],[54489,0,2],[54490,0,2],[54491,0,2],[54492,0,2],[54493,0,2],[54494,0,2],[54495,0,2],[54496,0,2],[54497,0,2],[54498,0,2],[54499,0,2],[54500,0,2],[54501,0,2],[54502,0,2],[54503,0,2],[54504,0,1],[54505,0,2],[54506,0,2],[54507,0,2],[54508,0,2],[54509,0,2],[54510,0,2],[54511,0,2],[54512,0,2],[54513,0,2],[54514,0,2],[54515,0,2],[54516,0,2],[54517,0,2],[54518,0,2],[54519,0,2],[54520,0,2],[54521,0,2],[54522,0,2],[54523,0,2],[54524,0,2],[54525,0,2],[54526,0,2],[54527,0,2],[54528,0,2],[54529,0,2],[54530,0,2],[54531,0,2],[54532,0,1],[54533,0,2],[54534,0,2],[54535,0,2],[54536,0,2],[54537,0,2],[54538,0,2],[54539,0,2],[54540,0,2],[54541,0,2],[54542,0,2],[54543,0,2],[54544,0,2],[54545,0,2],[54546,0,2],[54547,0,2],[54548,0,2],[54549,0,2],[54550,0,2],[54551,0,2],[54552,0,2],[54553,0,2],[54554,0,2],[54555,0,2],[54556,0,2],[54557,0,2],[54558,0,2],[54559,0,2],[54560,0,1],[54561,0,2],[54562,0,2],[54563,0,2],[54564,0,2],[54565,0,2],[54566,0,2],[54567,0,2],[54568,0,2],[54569,0,2],[54570,0,2],[54571,0,2],[54572,0,2],[54573,0,2],[54574,0,2],[54575,0,2],[54576,0,2],[54577,0,2],[54578,0,2],[54579,0,2],[54580,0,2],[54581,0,2],[54582,0,2],[54583,0,2],[54584,0,2],[54585,0,2],[54586,0,2],[54587,0,2],[54588,0,1],[54589,0,2],[54590,0,2],[54591,0,2],[54592,0,2],[54593,0,2],[54594,0,2],[54595,0,2],[54596,0,2],[54597,0,2],[54598,0,2],[54599,0,2],[54600,0,2],[54601,0,2],[54602,0,2],[54603,0,2],[54604,0,2],[54605,0,2],[54606,0,2],[54607,0,2],[54608,0,2],[54609,0,2],[54610,0,2],[54611,0,2],[54612,0,2],[54613,0,2],[54614,0,2],[54615,0,2],[54616,0,1],[54617,0,2],[54618,0,2],[54619,0,2],[54620,0,2],[54621,0,2],[54622,0,2],[54623,0,2],[54624,0,2],[54625,0,2],[54626,0,2],[54627,0,2],[54628,0,2],[54629,0,2],[54630,0,2],[54631,0,2],[54632,0,2],[54633,0,2],[54634,0,2],[54635,0,2],[54636,0,2],[54637,0,2],[54638,0,2],[54639,0,2],[54640,0,2],[54641,0,2],[54642,0,2],[54643,0,2],[54644,0,1],[54645,0,2],[54646,0,2],[54647,0,2],[54648,0,2],[54649,0,2],[54650,0,2],[54651,0,2],[54652,0,2],[54653,0,2],[54654,0,2],[54655,0,2],[54656,0,2],[54657,0,2],[54658,0,2],[54659,0,2],[54660,0,2],[54661,0,2],[54662,0,2],[54663,0,2],[54664,0,2],[54665,0,2],[54666,0,2],[54667,0,2],[54668,0,2],[54669,0,2],[54670,0,2],[54671,0,2],[54672,0,1],[54673,0,2],[54674,0,2],[54675,0,2],[54676,0,2],[54677,0,2],[54678,0,2],[54679,0,2],[54680,0,2],[54681,0,2],[54682,0,2],[54683,0,2],[54684,0,2],[54685,0,2],[54686,0,2],[54687,0,2],[54688,0,2],[54689,0,2],[54690,0,2],[54691,0,2],[54692,0,2],[54693,0,2],[54694,0,2],[54695,0,2],[54696,0,2],[54697,0,2],[54698,0,2],[54699,0,2],[54700,0,1],[54701,0,2],[54702,0,2],[54703,0,2],[54704,0,2],[54705,0,2],[54706,0,2],[54707,0,2],[54708,0,2],[54709,0,2],[54710,0,2],[54711,0,2],[54712,0,2],[54713,0,2],[54714,0,2],[54715,0,2],[54716,0,2],[54717,0,2],[54718,0,2],[54719,0,2],[54720,0,2],[54721,0,2],[54722,0,2],[54723,0,2],[54724,0,2],[54725,0,2],[54726,0,2],[54727,0,2],[54728,0,1],[54729,0,2],[54730,0,2],[54731,0,2],[54732,0,2],[54733,0,2],[54734,0,2],[54735,0,2],[54736,0,2],[54737,0,2],[54738,0,2],[54739,0,2],[54740,0,2],[54741,0,2],[54742,0,2],[54743,0,2],[54744,0,2],[54745,0,2],[54746,0,2],[54747,0,2],[54748,0,2],[54749,0,2],[54750,0,2],[54751,0,2],[54752,0,2],[54753,0,2],[54754,0,2],[54755,0,2],[54756,0,1],[54757,0,2],[54758,0,2],[54759,0,2],[54760,0,2],[54761,0,2],[54762,0,2],[54763,0,2],[54764,0,2],[54765,0,2],[54766,0,2],[54767,0,2],[54768,0,2],[54769,0,2],[54770,0,2],[54771,0,2],[54772,0,2],[54773,0,2],[54774,0,2],[54775,0,2],[54776,0,2],[54777,0,2],[54778,0,2],[54779,0,2],[54780,0,2],[54781,0,2],[54782,0,2],[54783,0,2],[54784,0,1],[54785,0,2],[54786,0,2],[54787,0,2],[54788,0,2],[54789,0,2],[54790,0,2],[54791,0,2],[54792,0,2],[54793,0,2],[54794,0,2],[54795,0,2],[54796,0,2],[54797,0,2],[54798,0,2],[54799,0,2],[54800,0,2],[54801,0,2],[54802,0,2],[54803,0,2],[54804,0,2],[54805,0,2],[54806,0,2],[54807,0,2],[54808,0,2],[54809,0,2],[54810,0,2],[54811,0,2],[54812,0,1],[54813,0,2],[54814,0,2],[54815,0,2],[54816,0,2],[54817,0,2],[54818,0,2],[54819,0,2],[54820,0,2],[54821,0,2],[54822,0,2],[54823,0,2],[54824,0,2],[54825,0,2],[54826,0,2],[54827,0,2],[54828,0,2],[54829,0,2],[54830,0,2],[54831,0,2],[54832,0,2],[54833,0,2],[54834,0,2],[54835,0,2],[54836,0,2],[54837,0,2],[54838,0,2],[54839,0,2],[54840,0,1],[54841,0,2],[54842,0,2],[54843,0,2],[54844,0,2],[54845,0,2],[54846,0,2],[54847,0,2],[54848,0,2],[54849,0,2],[54850,0,2],[54851,0,2],[54852,0,2],[54853,0,2],[54854,0,2],[54855,0,2],[54856,0,2],[54857,0,2],[54858,0,2],[54859,0,2],[54860,0,2],[54861,0,2],[54862,0,2],[54863,0,2],[54864,0,2],[54865,0,2],[54866,0,2],[54867,0,2],[54868,0,1],[54869,0,2],[54870,0,2],[54871,0,2],[54872,0,2],[54873,0,2],[54874,0,2],[54875,0,2],[54876,0,2],[54877,0,2],[54878,0,2],[54879,0,2],[54880,0,2],[54881,0,2],[54882,0,2],[54883,0,2],[54884,0,2],[54885,0,2],[54886,0,2],[54887,0,2],[54888,0,2],[54889,0,2],[54890,0,2],[54891,0,2],[54892,0,2],[54893,0,2],[54894,0,2],[54895,0,2],[54896,0,1],[54897,0,2],[54898,0,2],[54899,0,2],[54900,0,2],[54901,0,2],[54902,0,2],[54903,0,2],[54904,0,2],[54905,0,2],[54906,0,2],[54907,0,2],[54908,0,2],[54909,0,2],[54910,0,2],[54911,0,2],[54912,0,2],[54913,0,2],[54914,0,2],[54915,0,2],[54916,0,2],[54917,0,2],[54918,0,2],[54919,0,2],[54920,0,2],[54921,0,2],[54922,0,2],[54923,0,2],[54924,0,1],[54925,0,2],[54926,0,2],[54927,0,2],[54928,0,2],[54929,0,2],[54930,0,2],[54931,0,2],[54932,0,2],[54933,0,2],[54934,0,2],[54935,0,2],[54936,0,2],[54937,0,2],[54938,0,2],[54939,0,2],[54940,0,2],[54941,0,2],[54942,0,2],[54943,0,2],[54944,0,2],[54945,0,2],[54946,0,2],[54947,0,2],[54948,0,2],[54949,0,2],[54950,0,2],[54951,0,2],[54952,0,1],[54953,0,2],[54954,0,2],[54955,0,2],[54956,0,2],[54957,0,2],[54958,0,2],[54959,0,2],[54960,0,2],[54961,0,2],[54962,0,2],[54963,0,2],[54964,0,2],[54965,0,2],[54966,0,2],[54967,0,2],[54968,0,2],[54969,0,2],[54970,0,2],[54971,0,2],[54972,0,2],[54973,0,2],[54974,0,2],[54975,0,2],[54976,0,2],[54977,0,2],[54978,0,2],[54979,0,2],[54980,0,1],[54981,0,2],[54982,0,2],[54983,0,2],[54984,0,2],[54985,0,2],[54986,0,2],[54987,0,2],[54988,0,2],[54989,0,2],[54990,0,2],[54991,0,2],[54992,0,2],[54993,0,2],[54994,0,2],[54995,0,2],[54996,0,2],[54997,0,2],[54998,0,2],[54999,0,2],[55000,0,2],[55001,0,2],[55002,0,2],[55003,0,2],[55004,0,2],[55005,0,2],[55006,0,2],[55007,0,2],[55008,0,1],[55009,0,2],[55010,0,2],[55011,0,2],[55012,0,2],[55013,0,2],[55014,0,2],[55015,0,2],[55016,0,2],[55017,0,2],[55018,0,2],[55019,0,2],[55020,0,2],[55021,0,2],[55022,0,2],[55023,0,2],[55024,0,2],[55025,0,2],[55026,0,2],[55027,0,2],[55028,0,2],[55029,0,2],[55030,0,2],[55031,0,2],[55032,0,2],[55033,0,2],[55034,0,2],[55035,0,2],[55036,0,1],[55037,0,2],[55038,0,2],[55039,0,2],[55040,0,2],[55041,0,2],[55042,0,2],[55043,0,2],[55044,0,2],[55045,0,2],[55046,0,2],[55047,0,2],[55048,0,2],[55049,0,2],[55050,0,2],[55051,0,2],[55052,0,2],[55053,0,2],[55054,0,2],[55055,0,2],[55056,0,2],[55057,0,2],[55058,0,2],[55059,0,2],[55060,0,2],[55061,0,2],[55062,0,2],[55063,0,2],[55064,0,1],[55065,0,2],[55066,0,2],[55067,0,2],[55068,0,2],[55069,0,2],[55070,0,2],[55071,0,2],[55072,0,2],[55073,0,2],[55074,0,2],[55075,0,2],[55076,0,2],[55077,0,2],[55078,0,2],[55079,0,2],[55080,0,2],[55081,0,2],[55082,0,2],[55083,0,2],[55084,0,2],[55085,0,2],[55086,0,2],[55087,0,2],[55088,0,2],[55089,0,2],[55090,0,2],[55091,0,2],[55092,0,1],[55093,0,2],[55094,0,2],[55095,0,2],[55096,0,2],[55097,0,2],[55098,0,2],[55099,0,2],[55100,0,2],[55101,0,2],[55102,0,2],[55103,0,2],[55104,0,2],[55105,0,2],[55106,0,2],[55107,0,2],[55108,0,2],[55109,0,2],[55110,0,2],[55111,0,2],[55112,0,2],[55113,0,2],[55114,0,2],[55115,0,2],[55116,0,2],[55117,0,2],[55118,0,2],[55119,0,2],[55120,0,1],[55121,0,2],[55122,0,2],[55123,0,2],[55124,0,2],[55125,0,2],[55126,0,2],[55127,0,2],[55128,0,2],[55129,0,2],[55130,0,2],[55131,0,2],[55132,0,2],[55133,0,2],[55134,0,2],[55135,0,2],[55136,0,2],[55137,0,2],[55138,0,2],[55139,0,2],[55140,0,2],[55141,0,2],[55142,0,2],[55143,0,2],[55144,0,2],[55145,0,2],[55146,0,2],[55147,0,2],[55148,0,1],[55149,0,2],[55150,0,2],[55151,0,2],[55152,0,2],[55153,0,2],[55154,0,2],[55155,0,2],[55156,0,2],[55157,0,2],[55158,0,2],[55159,0,2],[55160,0,2],[55161,0,2],[55162,0,2],[55163,0,2],[55164,0,2],[55165,0,2],[55166,0,2],[55167,0,2],[55168,0,2],[55169,0,2],[55170,0,2],[55171,0,2],[55172,0,2],[55173,0,2],[55174,0,2],[55175,0,2],[55176,0,1],[55177,0,2],[55178,0,2],[55179,0,2],[55180,0,2],[55181,0,2],[55182,0,2],[55183,0,2],[55184,0,2],[55185,0,2],[55186,0,2],[55187,0,2],[55188,0,2],[55189,0,2],[55190,0,2],[55191,0,2],[55192,0,2],[55193,0,2],[55194,0,2],[55195,0,2],[55196,0,2],[55197,0,2],[55198,0,2],[55199,0,2],[55200,0,2],[55201,0,2],[55202,0,2],[55203,0,2],[64285,0,1],[64286,1,1],[64287,0,1],[64298,0,1],[64299,0,1],[64300,0,2],[64301,0,2],[64302,0,1],[64303,0,1],[64304,0,1],[64305,0,1],[64306,0,1],[64307,0,1],[64308,0,1],[64309,0,1],[64310,0,1],[64312,0,1],[64313,0,1],[64314,0,1],[64315,0,1],[64316,0,1],[64318,0,1],[64320,0,1],[64321,0,1],[64323,0,1],[64324,0,1],[64326,0,1],[64327,0,1],[64328,0,1],[64329,0,1],[64330,0,1],[64331,0,1],[64332,0,1],[64333,0,1],[64334,0,1],[64420,0,1],[64421,0,1],[64432,0,1],[64433,0,1],[64603,0,1],[64604,0,1],[64605,0,1],[64606,0,2],[64607,0,2],[64608,0,2],[64609,0,2],[64610,0,2],[64611,0,2],[64656,0,1],[64729,0,1],[64754,0,2],[64755,0,2],[64756,0,2],[64828,0,1],[64829,0,1],[65056,1,1],[65057,1,1],[65058,1,1],[65059,1,1],[65060,1,1],[65061,1,1],[65062,1,1],[65063,1,1],[65064,1,1],[65065,1,1],[65066,1,1],[65067,1,1],[65068,1,1],[65069,1,1],[65070,1,1],[65071,1,1],[65097,0,1],[65098,0,1],[65099,0,1],[65100,0,1],[65136,0,1],[65137,0,1],[65138,0,1],[65140,0,1],[65142,0,1],[65143,0,1],[65144,0,1],[65145,0,1],[65146,0,1],[65147,0,1],[65148,0,1],[65149,0,1],[65150,0,1],[65151,0,1],[65153,0,1],[65154,0,1],[65155,0,1],[65156,0,1],[65157,0,1],[65158,0,1],[65159,0,1],[65160,0,1],[65161,0,1],[65162,0,1],[65163,0,1],[65164,0,1],[65269,0,1],[65270,0,1],[65271,0,1],[65272,0,1],[65273,0,1],[65274,0,1],[65438,1,1],[65439,1,1],[65443,1,1],[65445,1,1],[65446,1,1],[65450,1,1],[65451,1,1],[65452,1,1],[65453,1,1],[65454,1,1],[65455,1,1],[65474,1,1],[65475,1,1],[65476,1,1],[65477,1,1],[65478,1,1],[65479,1,1],[65482,1,1],[65483,1,1],[65484,1,1],[65485,1,1],[65486,1,1],[65487,1,1],[65490,1,1],[65491,1,1],[65492,1,1],[65493,1,1],[65494,1,1],[65495,1,1],[65498,1,1],[65499,1,1],[65500,1,1],[65507,0,1],[66045,1,1],[66272,1,1],[66422,1,1],[66423,1,1],[66424,1,1],[66425,1,1],[66426,1,1],[68109,1,1],[68111,1,1],[68152,1,1],[68153,1,1],[68154,1,1],[68159,1,1],[68325,1,1],[68326,1,1],[68900,1,1],[68901,1,1],[68902,1,1],[68903,1,1],[69291,1,1],[69292,1,1],[69373,1,1],[69374,1,1],[69375,1,1],[69446,1,1],[69447,1,1],[69448,1,1],[69449,1,1],[69450,1,1],[69451,1,1],[69452,1,1],[69453,1,1],[69454,1,1],[69455,1,1],[69456,1,1],[69506,1,1],[69507,1,1],[69508,1,1],[69509,1,1],[69702,1,1],[69744,1,1],[69759,1,1],[69786,0,1],[69788,0,1],[69803,0,1],[69817,1,1],[69818,1,1],[69888,1,1],[69889,1,1],[69890,1,1],[69927,1,1],[69934,0,1],[69935,0,1],[69939,1,1],[69940,1,1],[70003,1,1],[70080,1,1],[70090,1,1],[70197,1,1],[70198,1,1],[70377,1,1],[70378,1,1],[70459,1,1],[70460,1,1],[70462,1,1],[70475,0,1],[70476,0,1],[70477,1,1],[70487,1,1],[70502,1,1],[70503,1,1],[70504,1,1],[70505,1,1],[70506,1,1],[70507,1,1],[70508,1,1],[70512,1,1],[70513,1,1],[70514,1,1],[70515,1,1],[70516,1,1],[70722,1,1],[70726,1,1],[70750,1,1],[70832,1,1],[70842,1,1],[70843,0,1],[70844,0,1],[70845,1,1],[70846,0,1],[70850,1,1],[70851,1,1],[71087,1,1],[71098,0,1],[71099,0,1],[71103,1,1],[71104,1,1],[71231,1,1],[71350,1,1],[71351,1,1],[71467,1,1],[71737,1,1],[71738,1,1],[71984,1,1],[71992,0,1],[71997,1,1],[71998,1,1],[72003,1,1],[72160,1,1],[72244,1,1],[72263,1,1],[72345,1,1],[72767,1,1],[73026,1,1],[73028,1,1],[73029,1,1],[73111,1,1],[73537,1,1],[73538,1,1],[92912,1,1],[92913,1,1],[92914,1,1],[92915,1,1],[92916,1,1],[92976,1,1],[92977,1,1],[92978,1,1],[92979,1,1],[92980,1,1],[92981,1,1],[92982,1,1],[94192,1,1],[94193,1,1],[113822,1,1],[119134,0,1],[119135,0,1],[119136,0,2],[119137,0,2],[119138,0,2],[119139,0,2],[119140,0,2],[119141,1,1],[119142,1,1],[119143,1,1],[119144,1,1],[119145,1,1],[119149,1,1],[119150,1,1],[119151,1,1],[119152,1,1],[119153,1,1],[119154,1,1],[119163,1,1],[119164,1,1],[119165,1,1],[119166,1,1],[119167,1,1],[119168,1,1],[119169,1,1],[119170,1,1],[119173,1,1],[119174,1,1],[119175,1,1],[119176,1,1],[119177,1,1],[119178,1,1],[119179,1,1],[119210,1,1],[119211,1,1],[119212,1,1],[119213,1,1],[119227,0,1],[119228,0,1],[119229,0,2],[119230,0,2],[119231,0,2],[119232,0,2],[119362,1,1],[119363,1,1],[119364,1,1],[122880,1,1],[122881,1,1],[122882,1,1],[122883,1,1],[122884,1,1],[122885,1,1],[122886,1,1],[122888,1,1],[122889,1,1],[122890,1,1],[122891,1,1],[122892,1,1],[122893,1,1],[122894,1,1],[122895,1,1],[122896,1,1],[122897,1,1],[122898,1,1],[122899,1,1],[122900,1,1],[122901,1,1],[122902,1,1],[122903,1,1],[122904,1,1],[122907,1,1],[122908,1,1],[122909,1,1],[122910,1,1],[122911,1,1],[122912,1,1],[122913,1,1],[122915,1,1],[122916,1,1],[122918,1,1],[122919,1,1],[122920,1,1],[122921,1,1],[122922,1,1],[123023,1,1],[123184,1,1],[123185,1,1],[123186,1,1],[123187,1,1],[123188,1,1],[123189,1,1],[123190,1,1],[123566,1,1],[123628,1,1],[123629,1,1],[123630,1,1],[123631,1,1],[124140,1,1],[124141,1,1],[124142,1,1],[124143,1,1],[125136,1,1],[125137,1,1],[125138,1,1],[125139,1,1],[125140,1,1],[125141,1,1],[125142,1,1],[125252,1,1],[125253,1,1],[125254,1,1],[125255,1,1],[125256,1,1],[125257,1,1],[125258,1,1],[127507,0,1]]} diff --git a/packages/skill-tree/src/byte-source.ts b/packages/skill-tree/src/byte-source.ts index 008192b..893444a 100644 --- a/packages/skill-tree/src/byte-source.ts +++ b/packages/skill-tree/src/byte-source.ts @@ -98,11 +98,20 @@ export class StreamReader { private chunk: Uint8Array = new Uint8Array(0); private offset = 0; private ended = false; + private consumed = 0; - constructor(source: AsyncIterable) { + /** `budget` caps the total bytes taken from the stream: headers, skipped data and file content alike. */ + constructor(source: AsyncIterable, private readonly budget = Infinity) { this.it = source[Symbol.asyncIterator](); } + private spend(n: number): void { + this.consumed += n; + if (this.consumed > this.budget) { + throw new SkillTreeError(ERROR_CODES.limitExceeded, "", `archive data exceeds ${this.budget} bytes`); + } + } + private async nextChunk(): Promise { while (!this.ended) { const next = await this.it.next(); @@ -132,6 +141,7 @@ export class StreamReader { throw readFailed(`stream ends after ${filled} of ${n} bytes`); } const take = Math.min(n - filled, this.chunk.length - this.offset); + this.spend(take); out.set(this.chunk.subarray(this.offset, this.offset + take), filled); this.offset += take; filled += take; @@ -147,6 +157,7 @@ export class StreamReader { throw readFailed(`stream ends ${left} bytes before the end of an entry`); } const take = Math.min(left, this.chunk.length - this.offset); + this.spend(take); const piece = this.chunk.subarray(this.offset, this.offset + take); this.offset += take; left -= take; diff --git a/packages/skill-tree/src/collision.ts b/packages/skill-tree/src/collision.ts index 395edd4..37a097e 100644 --- a/packages/skill-tree/src/collision.ts +++ b/packages/skill-tree/src/collision.ts @@ -45,9 +45,10 @@ export function checkFileDirs(files: readonly string[], dirEntries: readonly str * so a given entry list always reports the same path. */ export function checkCollisions(files: readonly string[], dirEntries: readonly string[]): SkillTreeError | null { + const keys = files.map(foldKey); const byKey = new Map(); - for (const file of files) { - const key = foldKey(file); + for (const [i, file] of files.entries()) { + const key = keys[i]!; const prior = byKey.get(key); if (prior !== undefined) { return treeError(ERROR_CODES.caseCollision, file, `collides with ${JSON.stringify(prior)} under case folding`); @@ -56,9 +57,12 @@ export function checkCollisions(files: readonly string[], dirEntries: readonly s } const foldedDirs = new Map(); let dirConflict: SkillTreeError | null = null; - for (const file of files) { - for (const dir of dirPrefixes(file)) { - const key = foldKey(dir); + for (const [i, file] of files.entries()) { + // "/" is a starter that neither folds, decomposes nor reorders, and nothing + // folds or decomposes to it, so the key's prefixes are the prefixes' keys. + const dirKeys = dirPrefixes(keys[i]!); + for (const [j, dir] of dirPrefixes(file).entries()) { + const key = dirKeys[j]!; const prior = foldedDirs.get(key); if (prior === undefined) foldedDirs.set(key, { dir, file }); else if (prior.dir !== dir && dirConflict === null) { @@ -70,8 +74,8 @@ export function checkCollisions(files: readonly string[], dirEntries: readonly s } } } - for (const file of files) { - const owner = foldedDirs.get(foldKey(file)); + for (const [i, file] of files.entries()) { + const owner = foldedDirs.get(keys[i]!); if (owner !== undefined) { return treeError(ERROR_CODES.caseCollision, file, `collides under case folding with the directory of ${JSON.stringify(owner.file)}`); } diff --git a/packages/skill-tree/src/entry-collector.ts b/packages/skill-tree/src/entry-collector.ts index 0951970..90ac8ba 100644 --- a/packages/skill-tree/src/entry-collector.ts +++ b/packages/skill-tree/src/entry-collector.ts @@ -24,27 +24,44 @@ export class EntryCollector { } } - /** Hashes one regular file's content as it streams, counting it toward the file and byte limits. */ - async hashFile(path: string, content: AsyncIterable): Promise<{ size: number; sha256: string }> { + private countBytes(path: string, size: number, added: number): void { + this.total += added; + if (!(size <= this.limits.maxFileSize)) { + throw treeError(ERROR_CODES.limitExceeded, path, `file exceeds ${this.limits.maxFileSize} bytes`); + } + if (this.total > this.limits.maxTreeSize) { + throw treeError(ERROR_CODES.limitExceeded, path, `tree exceeds ${this.limits.maxTreeSize} bytes`); + } + } + + private countFileEntry(path: string): void { if (++this.files > this.limits.maxFiles) { throw treeError(ERROR_CODES.limitExceeded, path, `tree has more than ${this.limits.maxFiles} files`); } + } + + /** Hashes one regular file's content as it streams, counting it toward the file and byte limits. */ + async hashFile(path: string, content: AsyncIterable): Promise<{ size: number; sha256: string }> { + this.countFileEntry(path); const hash = createSha256(); let size = 0; for await (const chunk of content) { size += chunk.length; - this.total += chunk.length; - if (size > this.limits.maxFileSize) { - throw treeError(ERROR_CODES.limitExceeded, path, `file exceeds ${this.limits.maxFileSize} bytes`); - } - if (this.total > this.limits.maxTreeSize) { - throw treeError(ERROR_CODES.limitExceeded, path, `tree exceeds ${this.limits.maxTreeSize} bytes`); - } + this.countBytes(path, size, chunk.length); hash.update(chunk); } return { size, sha256: hash.hex() }; } + /** + * Counts a regular file whose content is not hashed (a sparse file, which + * is rejected later) at its logical size, as the limit step sees it. + */ + countFile(path: string, size: number): void { + this.countFileEntry(path); + this.countBytes(path, size, Math.max(size, 0)); + } + add(entry: TreeEntry): void { this.entries.push(entry); } diff --git a/packages/skill-tree/src/tar-header.ts b/packages/skill-tree/src/tar-header.ts index 86ce14b..1902771 100644 --- a/packages/skill-tree/src/tar-header.ts +++ b/packages/skill-tree/src/tar-header.ts @@ -9,53 +9,77 @@ export const BLOCK = 512; /** Go archive/tar caps PAX and GNU long-name payloads at 1 MiB. */ export const MAX_SPECIAL_FILE_SIZE = 1 << 20; +const INT64_MIN = -(1n << 63n); +const INT64_MAX = (1n << 63n) - 1n; + +export type TarFormat = "v7" | "ustar" | "star" | "gnu"; + export interface RawHeader { - /** Raw name bytes (ustar prefix joined), before any PAX or GNU override. */ + /** Raw name bytes (prefix joined), before any PAX or GNU override. */ name: Uint8Array; linkname: Uint8Array; + /** Header mode; may be negative or beyond 2^53 (then imprecise), which `headerMode` rejects. */ mode: number; + /** Header size; negative when a base-256 field says so. */ size: number; typeflag: string; - /** Old GNU sparse ('S') extension flag at offset 482. */ - gnuExtended: boolean; + format: TarFormat; + /** The raw header block, kept for the old GNU sparse map. */ + block: Uint8Array; } -const latin = new TextDecoder("latin1"); +/** Bytes as a string of char codes 0-255; only ever matched against ASCII patterns. */ +export function byteString(bytes: Uint8Array): string { + let out = ""; + for (const b of bytes) out += String.fromCharCode(b); + return out; +} -function cString(block: Uint8Array, start: number, length: number): Uint8Array { - const field = block.subarray(start, start + length); +/** Go parser.parseString: the bytes before the first NUL. */ +function cString(field: Uint8Array): Uint8Array { const nul = field.indexOf(0); return nul < 0 ? field : field.subarray(0, nul); } -function trimField(field: Uint8Array): string { - return latin.decode(field).replace(/^[ \0]+|[ \0]+$/g, ""); +const isPad = (b: number) => b === 0x20 || b === 0; + +/** Go parseOctal: trim spaces and NULs, cut at a NUL, then an unsigned 64-bit octal number. */ +function parseOctal(field: Uint8Array, what: string): bigint { + let start = 0; + let end = field.length; + while (start < end && isPad(field[start]!)) start++; + while (end > start && isPad(field[end - 1]!)) end--; + if (start === end) return 0n; + const text = byteString(cString(field.subarray(start, end))); + if (!/^[0-7]+$/.test(text)) throw readFailed(`invalid octal ${what} ${JSON.stringify(text)}`); + const value = BigInt(`0o${text}`); + if (value >> 64n > 0n) throw readFailed(`${what} overflows`); + return BigInt.asIntN(64, value); } -/** Octal or GNU base-256 numeric field, like Go's parseNumeric. */ -export function parseNumeric(field: Uint8Array, what: string): number { +/** Go parseNumeric: octal, or GNU base-256 two's complement (negative values included) within int64. */ +export function parseNumeric(field: Uint8Array, what: string): bigint { const first = field[0] ?? 0; - if (first & 0x80) { - if (first & 0x40) throw readFailed(`negative base-256 ${what}`); - let value = first & 0x3f; - for (const byte of field.subarray(1)) { - value = value * 256 + byte; - if (!Number.isSafeInteger(value)) throw readFailed(`${what} overflows`); - } - return value; + if ((first & 0x80) === 0) return parseOctal(field, what); + const inv = first & 0x40 ? 0xff : 0; + let x = 0n; + for (let i = 0; i < field.length; i++) { + let c = field[i]! ^ inv; + if (i === 0) c &= 0x7f; + if (x >> 56n > 0n) throw readFailed(`${what} overflows`); + x = (x << 8n) | BigInt(c); } - const text = trimField(field); - if (text === "") return 0; - if (!/^[0-7]+$/.test(text)) throw readFailed(`invalid octal ${what} ${JSON.stringify(text)}`); - const value = parseInt(text, 8); - if (!Number.isSafeInteger(value)) throw readFailed(`${what} overflows`); - return value; + if (x >> 63n > 0n) throw readFailed(`${what} overflows`); + return inv ? -x - 1n : x; } function checksumMatches(block: Uint8Array): boolean { - const stored = trimField(block.subarray(148, 156)); - if (!/^[0-7]+$/.test(stored)) return false; - const want = parseInt(stored, 8); + let want: bigint; + try { + want = parseOctal(block.subarray(148, 156), "checksum"); + } catch { + return false; + } let unsigned = 0; let signed = 0; for (let i = 0; i < BLOCK; i++) { @@ -63,7 +87,7 @@ function checksumMatches(block: Uint8Array): boolean { unsigned += byte; signed += byte > 127 ? byte - 256 : byte; } - return want === unsigned || want === signed; + return want === BigInt(unsigned) || want === BigInt(signed); } function startsWith(block: Uint8Array, offset: number, text: string): boolean { @@ -71,82 +95,166 @@ function startsWith(block: Uint8Array, offset: number, text: string): boolean { return true; } +/** Go block.getFormat after the checksum: the 6-byte magic decides, the USTAR version is not checked. */ +function formatOf(block: Uint8Array): TarFormat { + if (startsWith(block, 257, "ustar\u0000")) return startsWith(block, 508, "tar\u0000") ? "star" : "ustar"; + if (startsWith(block, 257, "ustar ") && startsWith(block, 263, " \u0000")) return "gnu"; + return "v7"; +} + export function isZeroBlock(block: Uint8Array): boolean { return block.every((b) => b === 0); } +function joinPrefix(prefix: Uint8Array, name: Uint8Array): Uint8Array { + if (prefix.length === 0) return name; + const joined = new Uint8Array(prefix.length + 1 + name.length); + joined.set(prefix); + joined[prefix.length] = 0x2f; + joined.set(name, prefix.length + 1); + return joined; +} + +/** + * Go Reader.readHeader: every numeric field of the format must parse, even + * those the tree does not use, or the header is malformed. + */ export function parseHeader(block: Uint8Array): RawHeader { if (!checksumMatches(block)) throw readFailed("tar header checksum mismatch"); - let name = cString(block, 0, 100); - const ustar = startsWith(block, 257, "ustar\u000000"); - const gnu = startsWith(block, 257, "ustar \u0000"); - if (ustar) { - // star archives end the header with "tar\0" and keep a shorter prefix. - const star = startsWith(block, 508, "tar\u0000"); - const prefix = cString(block, 345, star ? 131 : 155); - if (prefix.length > 0) { - const joined = new Uint8Array(prefix.length + 1 + name.length); - joined.set(prefix); - joined[prefix.length] = 0x2f; - joined.set(name, prefix.length + 1); - name = joined; + const format = formatOf(block); + const field = (start: number, length: number) => block.subarray(start, start + length); + const size = parseNumeric(field(124, 12), "size"); + const mode = parseNumeric(field(100, 8), "mode"); + parseNumeric(field(108, 8), "uid"); + parseNumeric(field(116, 8), "gid"); + parseNumeric(field(136, 12), "mtime"); + let prefix: Uint8Array = new Uint8Array(0); + if (format !== "v7") { + parseNumeric(field(329, 8), "devmajor"); + parseNumeric(field(337, 8), "devminor"); + } + if (format === "ustar") prefix = cString(field(345, 155)); + if (format === "star") { + prefix = cString(field(345, 131)); + parseNumeric(field(476, 12), "atime"); + parseNumeric(field(488, 12), "ctime"); + } + if (format === "gnu") { + // Pre-Go 1.8 writers put a USTAR prefix where GNU keeps atime and ctime; + // Go falls back to it when those fields do not parse and it is ASCII. + try { + if (block[345] !== 0) parseNumeric(field(345, 12), "atime"); + if (block[357] !== 0) parseNumeric(field(357, 12), "ctime"); + } catch { + const legacy = cString(field(345, 155)); + if (legacy.every((b) => b < 0x80)) prefix = legacy; } } - const typeflag = String.fromCharCode(block[156]!); return { - name, - linkname: cString(block, 157, 100), - mode: parseNumeric(block.subarray(100, 108), "mode"), - size: parseNumeric(block.subarray(124, 136), "size"), - typeflag, - gnuExtended: gnu && typeflag === "S" && block[482] !== 0, + name: joinPrefix(prefix, cString(field(0, 100))), + linkname: cString(field(157, 100)), + mode: Number(mode), + size: Number(size), + typeflag: String.fromCharCode(block[156]!), + format, + block, }; } const utf8 = new TextDecoder("utf-8"); +export const SPARSE_MAP = "GNU.sparse.map"; +const SPARSE_OFFSET = "GNU.sparse.offset"; +const SPARSE_NUMBYTES = "GNU.sparse.numbytes"; +/** Records whose raw value bytes are kept, since they become entry names. */ +const RAW_RECORDS = new Set(["path", "GNU.sparse.name"]); + export interface PaxRecords { + /** Records by key, in a prototype-free object so no key can reach Object.prototype. */ records: Record; - /** Raw bytes of the `path` record, which may not be valid UTF-8. */ - rawPath?: Uint8Array; + /** Raw value bytes of `path` and `GNU.sparse.name`, which may not be valid UTF-8. */ + raw: Map; +} + +/** Go parsePAXRecord's length: ParseInt base 10, so a sign and leading zeros are allowed. */ +function recordLength(text: string): number { + return /^[+-]?[0-9]+$/.test(text) ? Number(text) : NaN; } -/** Parses PAX records " =\n" like Go's parsePAX; later records win. */ +/** + * Parses PAX records " =\n" like Go's parsePAX; later + * records win, and GNU 0.0 sparse offset/numbytes pairs become `GNU.sparse.map`. + */ export function parsePax(data: Uint8Array): PaxRecords { - const records: Record = {}; - let rawPath: Uint8Array | undefined; + const records: Record = Object.create(null) as Record; + const raw = new Map(); + const sparseMap: string[] = []; let pos = 0; while (pos < data.length) { const space = data.indexOf(0x20, pos); - const lenText = space < 0 ? "" : latin.decode(data.subarray(pos, space)); - if (!/^[1-9][0-9]*$/.test(lenText)) throw readFailed("invalid PAX record length"); - const end = pos + Number(lenText); - if (end > data.length || end <= space + 1 || data[end - 1] !== 0x0a) throw readFailed("invalid PAX record"); + if (space < 0) throw readFailed("invalid PAX record length"); + const lenText = byteString(data.subarray(pos, space)); + const n = recordLength(lenText); + if (!(n >= 5 && n <= data.length - pos) || n - (lenText.length + 1) <= 0) throw readFailed("invalid PAX record length"); + const end = pos + n; + if (data[end - 1] !== 0x0a) throw readFailed("invalid PAX record"); const body = data.subarray(space + 1, end - 1); const eq = body.indexOf(0x3d); if (eq <= 0) throw readFailed("invalid PAX record key"); - const key = utf8.decode(body.subarray(0, eq)); - const value = utf8.decode(body.subarray(eq + 1)); - const nulInValue = ["path", "linkpath", "uname", "gname"].includes(key) && value.includes("\0"); - if (key.includes("\0") || nulInValue) throw readFailed(`invalid PAX record ${JSON.stringify(key)}`); - records[key] = value; - if (key === "path") rawPath = body.subarray(eq + 1); + const keyBytes = body.subarray(0, eq); + const valueBytes = body.subarray(eq + 1); + const key = utf8.decode(keyBytes); + const value = utf8.decode(valueBytes); + const nulInValue = ["path", "linkpath", "uname", "gname"].includes(key) ? valueBytes.includes(0) : keyBytes.includes(0); + if (nulInValue) throw readFailed(`invalid PAX record ${JSON.stringify(key)}`); pos = end; + if (key === SPARSE_OFFSET || key === SPARSE_NUMBYTES) { + const want = sparseMap.length % 2 === 0 ? SPARSE_OFFSET : SPARSE_NUMBYTES; + if (key !== want || value.includes(",")) throw readFailed("invalid GNU sparse PAX records"); + sparseMap.push(value); + continue; + } + records[key] = value; + if (RAW_RECORDS.has(key)) raw.set(key, valueBytes); } - return rawPath === undefined ? { records } : { records, rawPath }; + if (sparseMap.length > 0) records[SPARSE_MAP] = sparseMap.join(","); + return { records, raw }; +} + +/** Go strconv.ParseInt(value, 10, 64), or undefined when it fails. */ +export function parseInt64(value: string): bigint | undefined { + if (!/^[+-]?[0-9]+$/.test(value)) return undefined; + const n = BigInt(value); + return n < INT64_MIN || n > INT64_MAX ? undefined : n; } -const DECIMAL_RECORDS = ["size", "uid", "gid"]; -const TIME_RECORDS = ["atime", "mtime", "ctime"]; +/** Go parsePAXTime: int64 seconds, then optional "." and sub-second digits ("1." is valid). */ +function validPaxTime(value: string): boolean { + const dot = value.indexOf("."); + const secs = dot < 0 ? value : value.slice(0, dot); + return parseInt64(secs) !== undefined && /^[0-9]*$/.test(dot < 0 ? "" : value.slice(dot + 1)); +} -/** Rejects records Go's mergePAX cannot parse. */ -export function checkPaxValues(records: Readonly>): void { - for (const [key, value] of Object.entries(records)) { - if (DECIMAL_RECORDS.includes(key) && !(/^[0-9]+$/.test(value) && Number.isSafeInteger(Number(value)))) { - throw readFailed(`invalid PAX ${key}`); +const INT_RECORDS = new Set(["size", "uid", "gid"]); +const TIME_RECORDS = new Set(["atime", "mtime", "ctime"]); + +/** + * Go mergePAX: rejects a non-empty value it cannot parse, and returns the + * `size` record when it overrides the header (empty values keep the header's). + */ +export function mergePaxValues(records: Readonly>): number | undefined { + let size: number | undefined; + for (const key of Object.keys(records)) { + const value = records[key]!; + if (value === "") continue; + if (INT_RECORDS.has(key)) { + const n = parseInt64(value); + if (n === undefined) throw readFailed(`invalid PAX ${key}`); + if (key === "size") size = Number(n); } - if (TIME_RECORDS.includes(key) && !/^-?[0-9]+(\.[0-9]+)?$/.test(value)) throw readFailed(`invalid PAX ${key}`); + if (TIME_RECORDS.has(key) && !validPaxTime(value)) throw readFailed(`invalid PAX ${key}`); } + return size; } /** Header-only types carry no data regardless of their size field (Go isHeaderOnlyType). */ diff --git a/packages/skill-tree/src/tar-reader.ts b/packages/skill-tree/src/tar-reader.ts index eca49f6..551ee72 100644 --- a/packages/skill-tree/src/tar-reader.ts +++ b/packages/skill-tree/src/tar-reader.ts @@ -12,13 +12,14 @@ import { BLOCK, MAX_SPECIAL_FILE_SIZE, blockPadding, - checkPaxValues, isHeaderOnly, isZeroBlock, + mergePaxValues, parseHeader, parsePax, } from "./tar-header"; import type { PaxRecords } from "./tar-header"; +import { readOldGnuSparse, readPaxSparse } from "./tar-sparse"; import { LIMITS, headerMode } from "./tree"; import type { EntryKind, TreeLimits } from "./tree"; @@ -83,6 +84,25 @@ async function readSpecial(reader: StreamReader, size: number): Promise= 0)) throw readFailed(`tar entry has a negative size ${size}`); + return n; +} + +/** Bytes an archive may take beyond its file content: headers, extension records and skipped data. */ +const ENTRY_OVERHEAD = 16 * 1024; + +/** + * The total byte budget of one archive. Go archive/tar has no such limit; + * it bounds data that no file limit counts (non-regular entry data, PAX and + * GNU extension chains), so a stream cannot be read without end. + */ +export function tarByteBudget(limits: TreeLimits): number { + return limits.maxTreeSize + limits.maxEntries * ENTRY_OVERHEAD; +} + async function readEntries(reader: StreamReader, collector: EntryCollector): Promise { let pax: PaxRecords | undefined; let longName: Uint8Array | undefined; @@ -96,44 +116,62 @@ async function readEntries(reader: StreamReader, collector: EntryCollector): Pro } const h = parseHeader(block); if (h.typeflag === "x") { - pax = parsePax(await readSpecial(reader, h.size)); + pax = parsePax(await readSpecial(reader, dataLength(h.typeflag, h.size))); continue; } if (h.typeflag === "L" || h.typeflag === "K") { - const value = nulTerminated(await readSpecial(reader, h.size)); - if (h.typeflag === "L" && value.length > 0) longName = value; + const value = nulTerminated(await readSpecial(reader, dataLength(h.typeflag, h.size))); + // An empty long name clears an earlier one, as Go's parseString result does. + if (h.typeflag === "L") longName = value.length > 0 ? value : undefined; continue; } collector.present(); if (h.typeflag === "g") { // Global records describe the archive; pending x and L headers are dropped, as in Go. - const global = parsePax(await readSpecial(reader, h.size)); - checkPaxValues(global.records); - const name = decodeName(global.rawPath ?? h.name); - collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: "", size: 0, sha256: "", kind: "metadata", paxRecords: global.records }); + // Go ignores a global header's merge failure and then reports no records. + const global = parsePax(await readSpecial(reader, dataLength(h.typeflag, h.size))); + let records = global.records; + try { + mergePaxValues(records); + } catch { + records = Object.create(null) as Record; + } + const name = decodeName(records.path ? global.raw.get("path")! : h.name); + collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: "", size: 0, sha256: "", kind: "metadata", paxRecords: records }); pax = undefined; longName = undefined; continue; } - const records = pax?.records ?? {}; - checkPaxValues(records); - const name = decodeName(longName ?? pax?.rawPath ?? h.name); - const declared = records.size !== undefined ? Number(records.size) : h.size; - const dataSize = isHeaderOnly(h.typeflag) ? 0 : declared; + const records = pax?.records ?? (Object.create(null) as Record); + const size = mergePaxValues(records) ?? h.size; + let rawName = longName ?? (records.path ? pax!.raw.get("path")! : h.name); + const physical = dataLength(h.typeflag, size); + let logical = size; + let consumed = 0; + if (h.typeflag === "S") await readOldGnuSparse(reader, h); + else { + const sparse = await readPaxSparse(reader, h, pax, size, physical); + if (sparse !== undefined) { + rawName = sparse.name ?? rawName; + logical = sparse.size; + consumed = sparse.consumed; + } + } + const name = decodeName(rawName); const kind = tarEntryKind(h.typeflag, name.path); - if (h.gnuExtended) { - // Old GNU sparse headers chain extension blocks before the data. - for (let ext = await reader.readExact(BLOCK); ; ext = await reader.readExact(BLOCK)) { - if (ext === null) throw readFailed("truncated GNU sparse header"); - if (ext[504] === 0) break; + const sparse = logical !== size || consumed > 0 || Object.keys(records).some((k) => k.startsWith("GNU.sparse.")); + let hashed = { size: 0, sha256: "" }; + if (kind === "regular" && !sparse) hashed = await collector.hashFile(name.path, reader.chunks(physical)); + else { + // Sparse files are rejected later, but their logical size counts toward the limits first. + if (kind === "regular") { + collector.countFile(name.path, logical); + hashed = { size: logical, sha256: "" }; } + await reader.skip(physical - consumed); } - let size = 0; - let sha256 = ""; - if (kind === "regular") ({ size, sha256 } = await collector.hashFile(name.path, reader.chunks(dataSize))); - else await reader.skip(dataSize); - await reader.skip(blockPadding(dataSize)); - collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: headerMode(h.mode), size, sha256, kind, paxRecords: records }); + await reader.skip(blockPadding(physical)); + collector.add({ path: name.path, utf8Valid: name.utf8Valid, mode: headerMode(h.mode), ...hashed, kind, paxRecords: records }); pax = undefined; longName = undefined; } @@ -145,10 +183,11 @@ async function readEntries(reader: StreamReader, collector: EntryCollector): Pro * limits stop reading as soon as they are exceeded. */ export async function readTarTree(source: ByteSource, options: TarReadOptions = {}): Promise { - const collector = new EntryCollector(options.limits ?? LIMITS); + const limits = options.limits ?? LIMITS; + const collector = new EntryCollector(limits); let reader: StreamReader | undefined; try { - reader = new StreamReader(await gunzipIfNeeded(toAsyncIterable(source), options.compression ?? "auto")); + reader = new StreamReader(await gunzipIfNeeded(toAsyncIterable(source), options.compression ?? "auto"), tarByteBudget(limits)); await readEntries(reader, collector); } catch (err) { throw asTreeError(err); diff --git a/packages/skill-tree/src/tar-sparse.ts b/packages/skill-tree/src/tar-sparse.ts new file mode 100644 index 0000000..24ad96f --- /dev/null +++ b/packages/skill-tree/src/tar-sparse.ts @@ -0,0 +1,167 @@ +/** + * GNU sparse maps as Go archive/tar Reader.Next reads them. The tree never + * accepts a sparse file (contract 4.4), but the map decides the entry's name, + * logical size and how much of its data section is the map itself, and a + * malformed map is a malformed archive (`tree.read_failed`), as in Go. + */ +import { readFailed } from "./byte-source"; +import type { StreamReader } from "./byte-source"; +import { BLOCK, MAX_SPECIAL_FILE_SIZE, SPARSE_MAP, byteString, isHeaderOnly, parseInt64, parseNumeric } from "./tar-header"; +import type { PaxRecords, RawHeader } from "./tar-header"; + +interface SparseEntry { + offset: bigint; + length: bigint; +} + +const INT64_MAX = (1n << 63n) - 1n; +/** Go parses the entry count as a native int and rejects counts whose double overflows. */ +const MAX_SPARSE_COUNT = INT64_MAX / 2n; + +/** Go validateSparseEntries: in order, non-overlapping, non-negative and within `size`. */ +function validSparseEntries(entries: readonly SparseEntry[], size: bigint): boolean { + if (size < 0n) return false; + let preEnd = 0n; + for (const { offset, length } of entries) { + if (offset < 0n || length < 0n || offset > INT64_MAX - length) return false; + if (offset + length > size || preEnd > offset) return false; + preEnd = offset + length; + } + return true; +} + +function sparseCount(text: string | undefined): bigint { + const n = parseInt64(text ?? ""); + if (n === undefined || n < 0n || n > MAX_SPARSE_COUNT) throw readFailed("invalid GNU sparse entry count"); + return n; +} + +function sparsePair(offset: string, length: string): SparseEntry { + const o = parseInt64(offset); + const l = parseInt64(length); + if (o === undefined || l === undefined) throw readFailed("invalid GNU sparse map entry"); + return { offset: o, length: l }; +} + +/** Go readGNUSparseMap0x1: the map from the GNU.sparse.numblocks and GNU.sparse.map records. */ +function map0x1(records: Readonly>): SparseEntry[] { + const n = sparseCount(records["GNU.sparse.numblocks"]); + const map = records[SPARSE_MAP] ?? ""; + const fields = map === "" ? [] : map.split(","); + if (BigInt(fields.length) !== 2n * n) throw readFailed("GNU sparse map does not match its entry count"); + const out: SparseEntry[] = []; + for (let i = 0; i + 1 < fields.length; i += 2) out.push(sparsePair(fields[i]!, fields[i + 1]!)); + return out; +} + +/** + * Go readGNUSparseMap1x0: newline-separated decimal fields at the start of + * the data section, read in whole blocks up to 1 MiB. Returns the map and + * the data bytes it took. + */ +async function map1x0(reader: StreamReader, available: number): Promise<{ entries: SparseEntry[]; consumed: number }> { + let text = ""; + let newlines = 0; + let consumed = 0; + let at = 0; + const feed = async (want: bigint) => { + while (BigInt(newlines) < want) { + consumed += BLOCK; + if (consumed > MAX_SPECIAL_FILE_SIZE) throw readFailed("GNU sparse map is too long"); + const block = consumed <= available ? await reader.readExact(BLOCK) : null; + if (block === null) throw readFailed("truncated GNU sparse map"); + const chunk = byteString(block); + text += chunk; + for (let i = 0; i < chunk.length; i++) if (chunk.charCodeAt(i) === 0x0a) newlines++; + } + }; + const token = () => { + const nl = text.indexOf("\n", at); + const out = text.slice(at, nl); + at = nl + 1; + newlines--; + return out; + }; + await feed(1n); + const n = sparseCount(token()); + await feed(2n * n); + const entries: SparseEntry[] = []; + for (let i = 0n; i < n; i++) entries.push(sparsePair(token(), token())); + return { entries, consumed }; +} + +/** Go readGNUSparsePAXHeaders version detection: "0.x", "1.0", or undefined when not sparse. */ +function paxSparseVersion(records: Readonly>): "0.x" | "1.0" | undefined { + const major = records["GNU.sparse.major"] ?? ""; + const minor = records["GNU.sparse.minor"] ?? ""; + if (major === "0" && (minor === "0" || minor === "1")) return "0.x"; + if (major === "1" && minor === "0") return "1.0"; + if (major !== "" || minor !== "") return undefined; // an unknown version is not sparse + return (records[SPARSE_MAP] ?? "") !== "" ? "0.x" : undefined; +} + +export interface PaxSparse { + /** `GNU.sparse.name`, which replaces the entry name. */ + name?: Uint8Array; + /** Logical file size. */ + size: number; + /** Data section bytes the 1.0 map occupied. */ + consumed: number; +} + +/** + * Applies GNU sparse PAX records like Go: the name and size overrides, then + * the map, validated against the logical size. Returns undefined when the + * records do not describe a sparse file. + */ +export async function readPaxSparse( + reader: StreamReader, + h: RawHeader, + pax: PaxRecords | undefined, + size: number, + physical: number, +): Promise { + const records = pax?.records ?? {}; + const version = paxSparseVersion(records); + if (version === undefined) return undefined; + const nameText = records["GNU.sparse.name"] ?? ""; + const sizeText = records["GNU.sparse.size"] || records["GNU.sparse.realsize"] || ""; + let logical = BigInt(size); + if (sizeText !== "") { + const n = parseInt64(sizeText); + if (n === undefined) throw readFailed("invalid GNU sparse size"); + logical = n; + } + const { entries, consumed } = version === "1.0" ? await map1x0(reader, physical) : { entries: map0x1(records), consumed: 0 }; + if (isHeaderOnly(h.typeflag) || !validSparseEntries(entries, logical)) throw readFailed("invalid GNU sparse map"); + return { ...(nameText === "" ? {} : { name: pax?.raw.get("GNU.sparse.name") }), size: Number(logical), consumed }; +} + +/** + * Go readOldGNUSparseMap for type 'S': GNU format only, map entries in the + * header and in extension blocks that precede the data. + */ +export async function readOldGnuSparse(reader: StreamReader, h: RawHeader): Promise { + if (h.format !== "gnu") throw readFailed("old GNU sparse header outside the GNU format"); + let block = h.block; + const size = parseNumeric(block.subarray(483, 495), "sparse real size"); + const entries: SparseEntry[] = []; + let base = 386; + let count = 4; + let extended = 482; + for (;;) { + for (let i = 0; i < count; i++) { + const at = base + i * 24; + if (block[at] === 0) break; + entries.push({ offset: parseNumeric(block.subarray(at, at + 12), "sparse offset"), length: parseNumeric(block.subarray(at + 12, at + 24), "sparse length") }); + } + if (block[extended]! === 0) break; + const next = await reader.readExact(BLOCK); + if (next === null) throw readFailed("truncated GNU sparse header"); + block = next; + base = 0; + count = 21; + extended = 504; + } + if (!validSparseEntries(entries, size)) throw readFailed("invalid GNU sparse map"); +} diff --git a/packages/skill-tree/src/tree.ts b/packages/skill-tree/src/tree.ts index 961e171..f8fd0b6 100644 --- a/packages/skill-tree/src/tree.ts +++ b/packages/skill-tree/src/tree.ts @@ -69,12 +69,24 @@ function isNoiseEntry(e: TreeEntry): boolean { } } -/** Maps a tar or zip header mode to its class; any other mode keeps its octal form and is rejected. */ +/** The largest mode a tar header's 8-byte octal field can hold. */ +const MAX_HEADER_MODE = 0o7777777; +const TYPE_BITS = 0o170000; + +/** + * Maps a tar or zip header mode to its class; any other mode keeps its + * octal form and is rejected, like Go's HeaderMode over int64. A mode that is + * not a safe integer, negative or wider than the octal field is rejected + * before the type bits are cleared, so no bit above them is ever dropped + * (JavaScript bitwise operators truncate to 32 bits). + */ export function headerMode(mode: number): string { - const perm = mode & ~0o170000; - if (perm === 0o644) return MODE_REGULAR; - if (perm === 0o755) return MODE_EXECUTABLE; - return `0${mode.toString(8)}`; + if (Number.isSafeInteger(mode) && mode >= 0 && mode <= MAX_HEADER_MODE) { + const perm = mode & ~TYPE_BITS; + if (perm === 0o644) return MODE_REGULAR; + if (perm === 0o755) return MODE_EXECUTABLE; + } + return Number.isFinite(mode) ? `0${mode.toString(8)}` : `0${mode}`; } function isSparseRecord(key: string): boolean { @@ -112,7 +124,11 @@ export function checkLimits(entries: readonly TreeEntry[], listed: number, limit for (const e of entries) { if (kindOf(e) !== "regular") continue; if (++count > limits.maxFiles) return treeError(ERROR_CODES.limitExceeded, e.path, `tree has more than ${limits.maxFiles} files`); - const size = Math.max(e.size, 0); + // A negative size counts as none (validation rejects it later); any other + // size that is not a safe integer (NaN, fractional, infinite, beyond 2^53) + // cannot be summed exactly and fails here. + const size = e.size < 0 ? 0 : e.size; + if (!Number.isSafeInteger(size)) return treeError(ERROR_CODES.limitExceeded, e.path, `file size ${e.size} is not a safe integer`); if (size > limits.maxFileSize) return treeError(ERROR_CODES.limitExceeded, e.path, `file exceeds ${limits.maxFileSize} bytes`); if ((total += size) > limits.maxTreeSize) return treeError(ERROR_CODES.limitExceeded, e.path, `tree exceeds ${limits.maxTreeSize} bytes`); } diff --git a/packages/skill-tree/src/unicode-15-tables.ts b/packages/skill-tree/src/unicode-15-tables.ts index 7936df5..9e2940e 100644 --- a/packages/skill-tree/src/unicode-15-tables.ts +++ b/packages/skill-tree/src/unicode-15-tables.ts @@ -1,7 +1,7 @@ // Code generated by scripts/gen-unicode-tables.mjs. DO NOT EDIT. // Unicode 15.0.0. Inputs: // fixtures/ucd/CaseFolding-15.0.0.txt sha256 cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7 -// scripts/unicode-15.0.0-go.json sha256 baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5 (go1.25.3, x/text norm 15.0.0) +// scripts/unicode-15.0.0-go.json sha256 0d0155948ceea434fa241b59937db1a41689fa2ccb8231d35d96a2c56f57b52b (go1.25.3, x/text norm 15.0.0) // Encodings: ranges are "delta.length" base-36 items (delta from the previous // range end); maps are "keyDelta:value.value"; lists are base-36 deltas. @@ -12,3 +12,4 @@ export const COMBINING_CLASSES = "lc.k.6e,1.0.6g,1.3.64,1.0.6g,1.0.60,1.4.64,1.1 export const CANONICAL_DECOMPOSITIONS = "5c:1t.lc,1:1t.ld,1:1t.le,1:1t.lf,1:1t.lk,1:1t.lm,2:1v.mf,1:1x.lc,1:1x.ld,1:1x.le,1:1x.lk,1:21.lc,1:21.ld,1:21.le,1:21.lk,2:26.lf,1:27.lc,1:27.ld,1:27.le,1:27.lf,1:27.lk,3:2d.lc,1:2d.ld,1:2d.le,1:2d.lk,1:2h.ld,3:2p.lc,1:2p.ld,1:2p.le,1:2p.lf,1:2p.lk,1:2p.lm,2:2r.mf,1:2t.lc,1:2t.ld,1:2t.le,1:2t.lk,1:2x.lc,1:2x.ld,1:2x.le,1:2x.lk,2:32.lf,1:33.lc,1:33.ld,1:33.le,1:33.lf,1:33.lk,3:39.lc,1:39.ld,1:39.le,1:39.lk,1:3d.ld,2:3d.lk,1:1t.lg,1:2p.lg,1:1t.li,1:2p.li,1:1t.mg,1:2p.mg,1:1v.ld,1:2r.ld,1:1v.le,1:2r.le,1:1v.lj,1:2r.lj,1:1v.lo,1:2r.lo,1:1w.lo,1:2s.lo,3:1x.lg,1:2t.lg,1:1x.li,1:2t.li,1:1x.lj,1:2t.lj,1:1x.mg,1:2t.mg,1:1x.lo,1:2t.lo,1:1z.le,1:2v.le,1:1z.li,1:2v.li,1:1z.lj,1:2v.lj,1:1z.mf,1:2v.mf,1:20.le,1:2w.le,3:21.lf,1:2x.lf,1:21.lg,1:2x.lg,1:21.li,1:2x.li,1:21.mg,1:2x.mg,1:21.lj,4:22.le,1:2y.le,1:23.mf,1:2z.mf,2:24.ld,1:30.ld,1:24.mf,1:30.mf,1:24.lo,1:30.lo,5:26.ld,1:32.ld,1:26.mf,1:32.mf,1:26.lo,1:32.lo,4:27.lg,1:33.lg,1:27.li,1:33.li,1:27.ln,1:33.ln,3:2a.ld,1:36.ld,1:2a.mf,1:36.mf,1:2a.lo,1:36.lo,1:2b.ld,1:37.ld,1:2b.le,1:37.le,1:2b.mf,1:37.mf,1:2b.lo,1:37.lo,1:2c.mf,1:38.mf,1:2c.lo,1:38.lo,3:2d.lf,1:39.lf,1:2d.lg,1:39.lg,1:2d.li,1:39.li,1:2d.lm,1:39.lm,1:2d.ln,1:39.ln,1:2d.mg,1:39.mg,1:2f.le,1:3b.le,1:2h.le,1:3d.le,1:2h.lk,1:2i.ld,1:3e.ld,1:2i.lj,1:3e.lj,1:2i.lo,1:3e.lo,y:27.m3,1:33.m3,e:2d.m3,1:39.m3,t:1t.lo,1:2p.lo,1:21.lo,1:2x.lo,1:27.lo,1:33.lo,1:2d.lo,1:39.lo,1:64.lg,1:70.lg,1:64.ld,1:70.ld,1:64.lo,1:70.lo,1:64.lc,1:70.lc,2:5g.lg,1:6c.lg,1:fa.lg,1:fb.lg,1:5i.lg,1:6e.lg,3:1z.lo,1:2v.lo,1:23.lo,1:2z.lo,1:27.mg,1:33.mg,1:dm.lg,1:dn.lg,1:c7.lo,1:ia.lo,1:2y.lo,4:1z.ld,1:2v.ld,3:26.lc,1:32.lc,1:5h.ld,1:6d.ld,1:5i.ld,1:6e.ld,1:60.ld,1:6w.ld,1:1t.lr,1:2p.lr,1:1t.lt,1:2p.lt,1:1x.lr,1:2t.lr,1:1x.lt,1:2t.lt,1:21.lr,1:2x.lr,1:21.lt,1:2x.lt,1:27.lr,1:33.lr,1:27.lt,1:33.lt,1:2a.lr,1:36.lr,1:2a.lt,1:36.lt,1:2d.lr,1:39.lr,1:2d.lt,1:39.lt,1:2b.me,1:37.me,1:2c.me,1:38.me,3:20.lo,1:2w.lo,7:1t.lj,1:2p.lj,1:1x.mf,1:2t.mf,1:5y.lg,1:6u.lg,1:5x.lg,1:6t.lg,1:27.lj,1:33.lj,1:fi.lg,1:fj.lg,1:2h.lg,1:3d.lg,7h:lc,1:ld,2:lv,1:lk.ld,1c:jd,a:1n,7:4o.ld,1:pd.ld,1:53,1:ph.ld,1:pj.ld,1:pl.ld,2:pr.ld,2:px.ld,1:q1.ld,1:qy.ld,q:pl.lk,1:px.lk,1:q9.ld,1:qd.ld,1:qf.ld,1:qh.ld,1:qz.ld,q:qh.lk,1:qt.lk,1:qn.ld,1:qt.ld,1:qx.ld,5:r6.ld,1:r6.lk,18:t1.lc,1:t1.lk,2:sz.ld,4:sm.lk,5:t6.ld,1:t4.lc,1:tf.li,b:t4.li,w:u0.li,n:tx.lc,1:tx.lk,2:tv.ld,4:uu.lk,5:u2.ld,1:u0.lc,1:ub.li,o:vo.lr,1:vp.lr,22:t2.li,1:ty.li,e:sw.li,1:ts.li,1:sw.lk,1:ts.lk,3:t1.li,1:tx.li,3:yg.lk,1:yh.lk,1:t2.lk,1:ty.lk,1:t3.lk,1:tz.lk,3:t4.lg,1:u0.lg,1:t4.lk,1:u0.lk,1:ta.lk,1:u6.lk,3:yw.lk,1:yx.lk,1:tp.lk,1:ul.lk,1:tf.lg,1:ub.lg,1:tf.lk,1:ub.lk,1:tf.ln,1:ub.ln,1:tj.lk,1:uf.lk,3:tn.lk,1:uj.lk,89:17r.18z,1:17r.190,1:18o.190,1:17r.191,1:18q.190,4a:1cl.190,2:1c1.190,h:1ci.190,gm:1t4.1to,8:1tc.1to,3:1tf.1to,10:1sl.1to,1:1sm.1to,1:1sn.1to,1:1ss.1to,1:1sx.1to,1:1sy.1to,1:1t7.1to,1:1tb.1to,30:1xj.1xa,1:1xj.1xz,g:1wh.1x8,1:1wi.1x8,2:1wv.1x8,2c:20i.20s,3:20o.20s,z:1zq.20s,1:1zr.20s,1:1zw.20s,3:20b.20s,6i:287.28m,3:287.27y,1:287.28n,g:275.27w,1:276.27w,1j:2aa.2c7,1i:2bq.2bi,1:2br.2bi,1:2bq.2c7,3g:2fa.2fq,3c:2in.2j9,7:2iu.2j9,1:2iu.2ja,2:2iu.2iq,1:2iy.2j9,3j:2me.2m6,1:2mf.2m6,1:2me.2mv,3y:2qh.2q2,2:2qh.2q7,1:2qk.2q2,1:2qh.2qn,9x:30i.33r,a:30s.33r,5:30x.33r,5:312.33r,5:317.33r,d:30g.33p,a:31t.31u,2:31t.31w,1:33m.328,2:33n.328,9:31t.328,i:32q.33r,a:330.33r,5:335.33r,5:33a.33r,5:33f.33r,d:32o.33p,31:36t.372,25c:5c5.5dh,2:5c7.5dh,2:5c9.5dh,2:5cb.5dh,2:5cd.5dh,4:5ch.5dh,15:5dm.5dh,2:5do.5dh,3:5dq.5dh,1:5dr.5dh,2:5du.5dh,jh:1t.md,1:2p.md,1:1u.lj,1:2q.lj,1:1u.mb,1:2q.mb,1:1u.mp,1:2q.mp,1:5j.ld,1:6f.ld,1:1w.lj,1:2s.lj,1:1w.mb,1:2s.mb,1:1w.mp,1:2s.mp,1:1w.mf,1:2s.mf,1:1w.ml,1:2s.ml,1:7m.lc,1:7n.lc,1:7m.ld,1:7n.ld,1:1x.ml,1:2t.ml,1:1x.mo,1:2t.mo,1:fc.li,1:fd.li,1:1y.lj,1:2u.lj,1:1z.lg,1:2v.lg,1:20.lj,1:2w.lj,1:20.mb,1:2w.mb,1:20.lk,1:2w.lk,1:20.mf,1:2w.mf,1:20.mm,1:2w.mm,1:21.mo,1:2x.mo,1:5r.ld,1:6n.ld,1:23.ld,1:2z.ld,1:23.mb,1:2z.mb,1:23.mp,1:2z.mp,1:24.mb,1:30.mb,1:5yu.lg,1:5yv.lg,1:24.mp,1:30.mp,1:24.ml,1:30.ml,1:25.ld,1:31.ld,1:25.lj,1:31.lj,1:25.mb,1:31.mb,1:26.lj,1:32.lj,1:26.mb,1:32.mb,1:26.mp,1:32.mp,1:26.ml,1:32.ml,1:5x.ld,1:6t.ld,1:5x.lk,1:6t.lk,1:98.lc,1:99.lc,1:98.ld,1:99.ld,1:28.ld,1:34.ld,1:28.lj,1:34.lj,1:2a.lj,1:36.lj,1:2a.mb,1:36.mb,1:5zu.lg,1:5zv.lg,1:2a.mp,1:36.mp,1:2b.lj,1:37.lj,1:2b.mb,1:37.mb,1:9m.lj,1:9n.lj,1:9s.lj,1:9t.lj,1:602.lj,1:603.lj,1:2c.lj,1:38.lj,1:2c.mb,1:38.mb,1:2c.mp,1:38.mp,1:2c.ml,1:38.ml,1:2d.mc,1:39.mc,1:2d.mo,1:39.mo,1:2d.ml,1:39.ml,1:a0.ld,1:a1.ld,1:a2.lk,1:a3.lk,1:2e.lf,1:3a.lf,1:2e.mb,1:3a.mb,1:2f.lc,1:3b.lc,1:2f.ld,1:3b.ld,1:2f.lk,1:3b.lk,1:2f.lj,1:3b.lj,1:2f.mb,1:3b.mb,1:2g.lj,1:3c.lj,1:2g.lk,1:3c.lk,1:2h.lj,1:3d.lj,1:2i.le,1:3e.le,1:2i.mb,1:3e.mb,1:2i.mp,1:3e.mp,1:2w.mp,1:38.lk,1:3b.lm,1:3d.lm,2:an.lj,5:1t.mb,1:2p.mb,1:1t.ll,1:2p.ll,1:5e.ld,1:6a.ld,1:5e.lc,1:6a.lc,1:5e.ll,1:6a.ll,1:5e.lf,1:6a.lf,1:61s.le,1:61t.le,1:76.ld,1:77.ld,1:76.lc,1:77.lc,1:76.ll,1:77.ll,1:76.lf,1:77.lf,1:61s.li,1:61t.li,1:1x.mb,1:2t.mb,1:1x.ll,1:2t.ll,1:1x.lf,1:2t.lf,1:5m.ld,1:6i.ld,1:5m.lc,1:6i.lc,1:5m.ll,1:6i.ll,1:5m.lf,1:6i.lf,1:62g.le,1:62h.le,1:21.ll,1:2x.ll,1:21.mb,1:2x.mb,1:27.mb,1:33.mb,1:27.ll,1:33.ll,1:5w.ld,1:6s.ld,1:5w.lc,1:6s.lc,1:5w.ll,1:6s.ll,1:5w.lf,1:6s.lf,1:630.le,1:631.le,1:bk.ld,1:bl.ld,1:bk.lc,1:bl.lc,1:bk.ll,1:bl.ll,1:bk.lf,1:bl.lf,1:bk.mb,1:bl.mb,1:2d.mb,1:39.mb,1:2d.ll,1:39.ll,1:bz.ld,1:c0.ld,1:bz.lc,1:c0.lc,1:bz.ll,1:c0.ll,1:bz.lf,1:c0.lf,1:bz.mb,1:c0.mb,1:2h.lc,1:3d.lc,1:2h.mb,1:3d.mb,1:2h.ll,1:3d.ll,1:2h.lf,1:3d.lf,7:q9.lv,1:q9.lw,1:64g.lc,1:64h.lc,1:64g.ld,1:64h.ld,1:64g.n6,1:64h.n6,1:pd.lv,1:pd.lw,1:64o.lc,1:64p.lc,1:64o.ld,1:64p.ld,1:64o.n6,1:64p.n6,1:qd.lv,1:qd.lw,1:64w.lc,1:64x.lc,1:64w.ld,1:64x.ld,3:ph.lv,1:ph.lw,1:654.lc,1:655.lc,1:654.ld,1:655.ld,3:qf.lv,1:qf.lw,1:65c.lc,1:65d.lc,1:65c.ld,1:65d.ld,1:65c.n6,1:65d.n6,1:pj.lv,1:pj.lw,1:65k.lc,1:65l.lc,1:65k.ld,1:65l.ld,1:65k.n6,1:65l.n6,1:qh.lv,1:qh.lw,1:65s.lc,1:65t.lc,1:65s.ld,1:65t.ld,1:65s.n6,1:65t.n6,1:pl.lv,1:pl.lw,1:660.lc,1:661.lc,1:660.ld,1:661.ld,1:660.n6,1:661.n6,1:qn.lv,1:qn.lw,1:668.lc,1:669.lc,1:668.ld,1:669.ld,3:pr.lv,1:pr.lw,1:66g.lc,1:66h.lc,1:66g.ld,1:66h.ld,3:qt.lv,1:qt.lw,1:66o.lc,1:66p.lc,1:66o.ld,1:66p.ld,1:66o.n6,1:66p.n6,2:px.lw,2:66x.lc,2:66x.ld,2:66x.n6,1:qx.lv,1:qx.lw,1:674.lc,1:675.lc,1:674.ld,1:675.ld,1:674.n6,1:675.n6,1:q1.lv,1:q1.lw,1:67c.lc,1:67d.lc,1:67c.ld,1:67d.ld,1:67c.n6,1:67d.n6,1:q9.lc,1:q9.ld,1:qd.lc,1:qd.ld,1:qf.lc,1:qf.ld,1:qh.lc,1:qh.ld,1:qn.lc,1:qn.ld,1:qt.lc,1:qt.ld,1:qx.lc,1:qx.ld,3:64g.n9,1:64h.n9,1:64i.n9,1:64j.n9,1:64k.n9,1:64l.n9,1:64m.n9,1:64n.n9,1:64o.n9,1:64p.n9,1:64q.n9,1:64r.n9,1:64s.n9,1:64t.n9,1:64u.n9,1:64v.n9,1:65c.n9,1:65d.n9,1:65e.n9,1:65f.n9,1:65g.n9,1:65h.n9,1:65i.n9,1:65j.n9,1:65k.n9,1:65l.n9,1:65m.n9,1:65n.n9,1:65o.n9,1:65p.n9,1:65q.n9,1:65r.n9,1:674.n9,1:675.n9,1:676.n9,1:677.n9,1:678.n9,1:679.n9,1:67a.n9,1:67b.n9,1:67c.n9,1:67d.n9,1:67e.n9,1:67f.n9,1:67g.n9,1:67h.n9,1:67i.n9,1:67j.n9,1:q9.li,1:q9.lg,1:67k.n9,1:q9.n9,1:q4.n9,2:q9.n6,1:69i.n9,1:pd.li,1:pd.lg,1:pd.lc,1:pd.ld,1:pd.n9,2:qh,3:4o.n6,1:67o.n9,1:qf.n9,1:q6.n9,2:qf.n6,1:69y.n9,1:ph.lc,1:ph.ld,1:pj.lc,1:pj.ld,1:pj.n9,1:69r.lc,1:69r.ld,1:69r.n6,1:qh.li,1:qh.lg,1:qy.lc,1:qh.lk.ld,3:qh.n6,1:qy.n6,1:pl.li,1:pl.lg,1:pl.lc,1:pl.ld,2:6bi.lc,1:6bi.ld,1:6bi.n6,1:qt.li,1:qt.lg,1:qz.lc,1:qt.lk.ld,1:qp.lv,1:qp.lw,1:qt.n6,1:qz.n6,1:px.li,1:px.lg,1:px.lc,1:px.ld,1:pt.lw,1:4o.lc,1:4o.ld,1:2o,3:67w.n9,1:qx.n9,1:r2.n9,2:qx.n6,1:6ba.n9,1:pr.lc,1:pr.ld,1:q1.lc,1:q1.ld,1:q1.n9,1:50,3:6bm,1:6bn,85:q1,4:23,1:1t.lm,33:6mo.mw,1:6mq.mw,j:6ms.mw,v:6og.mw,1:6ok.mw,1:6oi.mw,1h:6pv.mw,5:6q0.mw,3:6q3.mw,o:6qr.mw,2:6qt.mw,r:6rg.mw,3:6rn.mw,3:6rp.mw,2:6rs.mw,n:1p.mw,2:6sh.mw,b:6rx.mw,1:1o.mw,1:1q.mw,1:6sk.mw,1:6sl.mw,3:6sy.mw,1:6sz.mw,3:6t2.mw,1:6t3.mw,7:6t6.mw,1:6t7.mw,3:6te.mw,1:6tf.mw,3:6ti.mw,1:6tj.mw,z:6ua.mw,1:6ug.mw,1:6uh.mw,1:6uj.mw,1d:6t8.mw,1:6t9.mw,1:6tt.mw,1:6tu.mw,7:6uq.mw,1:6ur.mw,1:6us.mw,1:6ut.mw,1o:9hk,1:9hl,1iq:8gt.mw,12o:9jf.9ll,2:9jh.9ll,2:9jj.9ll,2:9jl.9ll,2:9jn.9ll,2:9jp.9ll,2:9jr.9ll,2:9jt.9ll,2:9jv.9ll,2:9jx.9ll,2:9jz.9ll,2:9k1.9ll,3:9k4.9ll,2:9k6.9ll,2:9k8.9ll,7:9kf.9ll,1:9kf.9lm,2:9ki.9ll,1:9ki.9lm,2:9kl.9ll,1:9kl.9lm,2:9ko.9ll,1:9ko.9lm,2:9kr.9ll,1:9kr.9lm,n:9ja.9ll,a:9lp.9ll,e:9m3.9ll,2:9m5.9ll,2:9m7.9ll,2:9m9.9ll,2:9mb.9ll,2:9md.9ll,2:9mf.9ll,2:9mh.9ll,2:9mj.9ll,2:9ml.9ll,2:9mn.9ll,2:9mp.9ll,3:9ms.9ll,2:9mu.9ll,2:9mw.9ll,7:9n3.9ll,1:9n3.9lm,2:9n6.9ll,1:9n6.9lm,2:9n9.9ll,1:9n9.9lm,2:9nc.9ll,1:9nc.9lm,2:9nf.9ll,1:9nf.9lm,n:9ly.9ll,3:9nz.9ll,1:9o0.9ll,1:9o1.9ll,1:9o2.9ll,4:9od.9ll,13ia:rpk,1:kc4,1:s7e,1:rt4,1:lw1,1:fg2,1:gkl,1:vj0,1:vj0,1:hn5,1:ssx,1:gw7,1:hmw,1:jcm,1:ne1,1:p6t,1:qin,1:qt6,1:r20,1:sjz,1:kxu,1:ljv,1:mah,1:mvy,1:q4d,1:sq2,1:uep,1:fia,1:ghh,1:l50,1:mjf,1:qi5,1:v8e,1:ifk,1:m3v,1:qfh,1:r50,1:jih,1:pnc,1:qvz,1:iq2,1:kd3,1:lm2,1:mpo,1:slq,1:fpi,1:g53,1:gda,1:jwk,1:l3n,1:mj4,1:nhj,1:pa9,1:qh2,1:qjg,1:s1b,1:tv6,1:upb,1:v7e,1:nt8,1:nzz,1:otc,1:q15,1:t1g,1:vb3,1:rfa,1:hjz,1:iro,1:okg,1:pdq,1:mle,1:nuy,1:rsy,1:ttj,1:hjs,1:i8y,1:kyb,1:lp6,1:lxr,1:oq7,1:oxj,1:tor,1:gcy,1:pe3,1:g64,1:g5o,1:o4c,1:ou6,1:q29,1:tpx,1:rk0,1:jin,1:kxu,1:rge,1:fg9,1:i5j,1:iz6,1:mtj,1:n74,1:gev,1:nwb,1:fr3,1:iw9,1:ff1,1:lho,1:k1k,1:opu,1:gjn,1:hge,1:ni9,1:q4p,1:re2,1:la2,1:sds,1:lfs,1:jjy,1:put,1:jog,1:n6t,1:fji,1:g2x,1:g5l,1:kn5,1:oo7,1:prj,1:rf6,1:ssv,1:gdx,1:gn6,1:ho3,1:ir0,1:k3p,1:m4e,1:nxm,1:tkd,1:ui2,1:vbr,1:vda,1:gbf,1:kau,1:l87,1:sbm,1:ino,1:j9s,1:jcw,1:jve,1:lyb,1:mdl,1:n0p,1:o22,1:ovo,1:pdb,1:s9y,1:q9a,1:sgz,1:t3e,1:g7r,1:gbn,1:gql,1:ma0,1:r0i,1:re2,1:iq1,1:iyd,1:jnf,1:l9q,1:oji,1:mt1,1:fl0,1:h6h,1:i5j,1:iii,1:izg,1:muq,1:mzt,1:p7e,1:pc6,1:svo,1:tti,1:tvs,1:u1k,1:fpn,1:o1a,1:ss4,1:trs,1:j4x,1:fie,1:fyy,1:i5q,1:i7z,1:k2h,1:kxu,1:mha,1:ncy,1:q9o,1:sjg,1:vil,1:k94,1:tny,1:gax,1:kfv,1:kj7,1:lkx,1:luk,1:mx5,1:n6h,1:nsb,1:opc,1:u3i,1:g31,1:je6,1:tq0,1:fu3,1:ie1,1:lpm,1:sa2,1:ivf,1:j7o,1:kk7,1:mtj,1:tqe,1:g89,1:glr,1:i91,1:k5v,1:kem,1:ko8,1:lid,1:mx2,1:naa,1:p6h,1:r0v,1:r1d,1:sss,1:tsy,1:gfz,1:lve,1:gm5,1:mhc,1:n14,1:qgq,1:tr7,1:uvr,1:vbz,1:kgn,1:lor,1:pns,1:o97,1:obk,1:olu,1:mo0,1:m8p,1:riw,1:fk0,1:px2,1:g8q,1:g7b,1:ip2,1:jir,1:onq,1:i2t,1:ljy,1:kac,1:saj,1:qx8,1:tot,1:r63,1:iqb,1:g1s,1:gxs,3:hga,2:k8k,3:g66,1:mqy,1:ngq,1:ny4,1:nz2,1:nz9,1:o0f,1:tw6,1:on2,1:p8d,2:qhe,2:rg8,3:shk,1:sn1,4:u7j,1:u7w,1:u94,1:v5g,1:sm6,1:trr,1:fqm,1:fzb,1:g25,1:gcp,1:gdg,1:ggh,1:gwt,1:gzq,1:h2g,1:hfk,1:hig,1:i90,1:i9a,1:j2s,1:j8o,1:j9q,1:jci,1:k0f,1:k4i,1:k9d,1:kn9,1:lmf,1:lqy,1:lya,1:mem,1:mjv,1:mxu,1:ntd,1:ny6,1:nyh,1:nyg,1:nyo,1:nyu,1:nz1,1:o0d,1:o0e,1:o5c,1:o75,1:og0,1:ovo,1:ow9,1:oxt,1:p6a,1:pad,1:pnx,1:prt,1:prt,1:q53,1:r2o,1:r6e,1:rgh,1:ri1,1:rtf,1:ruw,1:sdy,1:shk,1:tsz,1:u0v,1:u2j,1:j1x,1:36cu,1:pp4,3:ffq,1:g51,1:g2w,1:fpc,1:g1x,1:g3k,1:gcn,1:ge2,1:gwt,1:gut,1:gwp,1:gyq,1:hga,1:hir,1:hms,1:hn8,1:huq,1:i08,1:iqa,1:iqh,1:iuh,1:iwd,1:j4o,1:j7y,1:j60,1:j9q,1:j8g,1:jci,1:jec,1:jpg,1:jrw,1:jte,1:k0m,1:k8k,1:kd3,1:kd7,1:keu,1:l89,1:la2,1:lkx,1:lwb,1:lvv,1:lya,1:m5a,1:mem,1:nmv,1:mk5,1:mnj,1:mqy,1:n01,1:n46,1:n5n,1:nbx,1:nbz,1:ngq,1:nh7,1:nhw,1:nka,1:nk0,1:nv0,1:o8h,1:og0,1:ol7,1:orf,1:ovo,1:p4u,1:pad,1:pxu,1:q27,1:qrd,1:r41,1:r5y,1:r6e,1:ren,1:rg8,1:rez,1:rgh,1:rge,1:rfx,1:ri1,1:rka,1:ruw,1:sag,1:sj6,1:srd,1:sxi,1:tq4,1:tsz,1:tw6,1:tzv,1:u0v,1:u17,1:u2j,1:umq,1:vj0,1:313e,1:3138,1:33dh,1:brx,1:cns,1:cop,1:39e1,1:3bgw,1:3i6r,1:vgj,1:vim,1w:15l.14k,2:16a.14n,b:161.14x,1:161.14y,1:161.14s.14x,1:161.14s.14y,1:15c.14n,1:15c.14o,1:15c.14s,1:15d.14s,1:15e.14s,1:15f.14s,1:15g.14s,1:15h.14s,1:15i.14s,2:15k.14s,1:15l.14s,1:15m.14s,1:15n.14s,1:15o.14s,2:15q.14s,2:15s.14s,1:15t.14s,2:15v.14s,1:15w.14s,2:15y.14s,1:15z.14s,1:160.14s,1:161.14s,1:162.14s,1:15h.14p,1:15d.14v,1:15n.14v,1:15w.14v,47g:1huh.1hve,2:1huj.1hve,f:1hut.1hve,3n:1hyp.1hyf,1:1hyq.1hyf,f0:1idj.1ida,1:1idj.1idz,a7:1int.1inu,1:1int.1ink,2:1int.1inx,70:1iuw.1iun,1:1iux.1iun,ot:1jjp.1jjk,10di:2jx3.2jxh,1:2jx4.2jxh,1:2jx4.2jxh.2jxq,1:2jx4.2jxh.2jxr,1:2jx4.2jxh.2jxs,1:2jx4.2jxh.2jxt,1:2jx4.2jxh.2jxu,2f:2jzt.2jxh,1:2jzu.2jxh,1:2jzt.2jxh.2jxq,1:2jzu.2jxh.2jxq,1:2jzt.2jxh.2jxr,1:2jzu.2jxh.2jxr,1m4g:fgd,1:fg8,1:fgh,1:2tcy,1:fog,1:fqm,1:fqz,1:fsy,1:fwa,1:fx5,1:fzb,1:fyn,1:ae6,1:2ud6,1:g25,1:g2c,1:g2s,1:g3b,1:2u58,1:aex,1:g2v,1:g3x,1:2u6j,1:g47,1:g4k,1:fkc,1:g4s,1:g51,1:3ly7,1:g6t,1:g77,1:afz,1:g8r,1:g92,1:gaa,1:gaf,1:ahh,1:gcn,1:gcp,1:gdg,1:ge2,1:ged,1:gee,1:gev,1:gg9,1:ggh,1:ggq,1:ghf,1:ghp,1:ghr,1:ghr,1:ghr,1:2v58,1:m7k,1:gju,1:gkf,1:2vdv,1:gkr,1:gkx,1:gli,1:gpq,1:gmw,1:gnc,1:go8,1:gpu,1:gs6,1:gsw,1:gur,1:gv7,1:gw4,1:gw4,1:gwp,1:gx7,1:gxf,1:gxu,1:h7a,1:gzq,1:h7b,1:h1t,1:h2s,1:g7b,1:hke,1:hce,1:hdg,1:he5,1:haj,1:hf6,1:hf5,1:hik,1:2x9g,1:hki,1:hkn,1:hl2,1:hlm,1:hlu,1:hnm,1:2xm0,1:2xnu,1:hrg,1:hsr,1:ht3,1:hqw,1:huu,1:aum,1:av0,1:hzc,1:i0u,1:i0u,1:2y88,1:i4j,1:i54,1:i5j,1:i5v,1:2yhk,1:i67,1:i6e,1:itv,1:i76,1:ayp,1:i8w,1:i9a,1:ibk,1:ia5,1:2z1g,1:if7,1:2z1i,1:ige,1:igb,1:igs,1:ijl,1:ijm,1:b3j,1:ikd,1:ilk,1:im5,1:ind,1:b4y,1:2zr7,1:b5o,1:ipc,1:ipf,1:ipi,1:iq2,1:3pg2,1:iri,1:3035,1:3035,1:poh,1:isi,1:isi,1:b7r,1:335k,1:3cgq,1:iua,1:iuj,1:b8j,1:ivu,1:ix9,1:ixj,1:iyh,1:j29,1:bay,1:ba4,1:j2s,1:30t0,1:j47,1:j7s,1:j7w,1:j7y,1:j7w,1:j96,1:j9q,1:jaq,1:jac,1:jan,1:jby,1:jci,1:jcm,1:jdc,1:jdn,1:jfh,1:jht,1:jis,1:jm8,1:31n0,1:jlp,1:jjw,1:jmw,1:jnn,1:jqc,1:31td,1:js2,1:jph,1:jop,1:bhq,1:ju1,1:jum,1:jvh,1:juf,1:bjg,1:k0f,1:k18,1:32mi,1:k4j,1:kc8,1:k7d,1:bo9,1:k9d,1:bns,1:bms,1:g42,1:g45,1:kcg,1:k9o,1:pf1,1:deh,1:kd3,1:kd7,1:kdd,1:kf2,1:ker,1:33cz,1:bpl,1:kje,1:kg5,1:klu,1:kn9,1:33hp,1:kni,1:kkf,1:kr8,1:brx,1:ksi,1:kv7,1:kx6,1:l2g,1:33xf,1:l3v,1:bvc,1:l5t,1:34br,1:l78,1:bwu,1:l82,1:l9b,1:la2,1:la3,1:34p9,1:2yvf,1:34sa,1:le6,1:354s,1:lhb,1:lhp,1:lev,1:ljq,1:lku,1:lmf,1:lkx,1:lm1,1:lmg,1:lmt,1:357i,1:lkk,1:lrj,1:lta,1:c37,1:lvv,1:lvr,1:35jl,1:lq1,1:m0e,1:35ni,1:35ou,1:m2u,1:m61,1:m5a,1:m57,1:c5y,1:m6i,1:m7x,1:m7r,1:m99,1:2u5h,1:mdh,1:368z,1:mfw,1:36i3,1:mjs,1:mk5,1:mkw,1:36yw,1:mm8,1:mmt,1:3779,1:37dg,1:mt6,1:mtn,1:cdo,1:mud,1:ce0,1:ce0,1:myv,1:mzg,1:n01,1:n0l,1:n2i,1:cgr,1:n50,1:386u,1:n5q,1:389e,1:n74,1:2zrz,1:nbk,1:38v5,1:38vs,1:38zo,1:cn0,1:cnc,1:nhw,1:394j,1:394i,1:395l,1:396b,1:nj2,1:nj3,1:nj3,1:nka,1:cop,1:nm3,1:cp2,1:cra,1:39r1,1:nri,1:nt8,1:nv0,1:ctf,1:3a5i,1:nyu,1:3a8q,1:3a9x,1:o0f,1:o2z,1:cvj,1:o5c,1:o5m,1:o5r,1:3at8,1:3b1j,1:3b1j,1:oa6,1:d1e,1:3b8r,1:og6,1:og9,1:d2f,1:3beo,1:onm,1:d5s,1:oo8,1:oo3,1:oow,1:3c06,1:orn,1:d8h,1:ouf,1:ow2,1:oxx,1:d9w,1:3ciw,1:3cjr,1:dax,1:3cnt,1:p6i,1:3cqm,1:p79,1:pa2,1:pad,1:3d22,1:3d43,1:pcw,1:3d7s,1:pdc,1:33a7,1:ded,1:pf6,1:phf,1:dfv,1:pj2,1:hx1,1:3dlz,1:3dmd,1:33bn,1:33bw,1:poh,1:pok,1:sda,1:dij,1:psh,1:psb,1:pst,1:gc3,1:ptd,1:ptf,1:ptp,1:puu,1:3ebg,1:put,1:pwd,1:pyb,1:q0d,1:pwj,1:q0t,1:q1z,1:q53,1:pxv,1:q16,1:q18,1:q1o,1:3eie,1:3eqz,1:3emt,1:dnv,1:q9d,1:q9f,1:qae,1:3g0a,1:qck,1:3f3g,1:dp9,1:dpd,1:3f75,1:3ff6,1:dpn,1:qj4,1:qjg,1:qjr,1:qjt,1:qll,1:qko,1:qoe,1:qn6,1:qrd,1:qp4,1:qqz,1:qrq,1:dsn,1:qu9,1:qv5,1:dtl,1:qxs,1:qxv,1:3giv,1:r13,1:r1a,1:dv9,1:r22,1:aez,1:3gz2,1:3h46,1:dz2,1:dzb,1:rds,1:rfx,1:rka,1:rpx,1:3hrc,1:rsb,1:rsx,1:rvf,1:rxz,1:3i9b,1:2upw,1:s0b,1:rzw,1:s1c,1:2uvy,1:s7o,1:sag,1:3jki,1:3jl9,1:sk4,1:smp,1:snl,1:3ju6,1:snv,1:svs,1:t07,1:t08,1:sxo,1:t89,1:t91,1:3ksa,1:tjf,1:ej9,1:tkn,1:3l2v,1:eli,1:ts3,1:iia,1:tur,1:3ltx,1:3lzu,1:epa,1:epi,1:u00,1:3mdm,1:er6,1:3mhi,1:u17,1:u17,1:u21,1:3mpi,1:u76,1:eur,1:u95,1:ucn,1:ude,1:uf2,1:ez2,1:3nsg,1:umq,1:uv4,1:v0d,1:f66,1:f71,1:v3b,1:3owe,1:f7c,1:3oxx,1:3p5a,1:3p8x,1:vcr,1:f9y,1:veh,1:vem,1:vet,1:vf3,1:vfa,1:vgb,1:3pxc"; export const PRIMARY_COMPOSITES = "5c,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,4,1,1,1,2,1,1,1,1,1,5,1,1,1,1,1,4,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,y,1,e,1,t,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,4,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,7,1,1,1,1,1,1,1,1,1,1,1,1,1,9e,1,2,1,1,2,2,1,1,q,1,1,1,1,1,1,q,1,1,1,1,5,1,18,1,2,4,5,1,1,b,w,n,1,2,4,5,1,1,o,1,22,1,e,1,1,1,3,1,3,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,3,1,89,1,1,1,1,4a,2,h,gm,8,3,47,1,ak,3,1,20,1i,1,1,3g,3c,7,1,2,1,3j,1,1,3y,2,1,1,g8,25c,2,2,2,2,4,15,2,3,1,2,jh,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,5,1,1,1,2,1,1,2,2,1,1,1,1,1,1,4,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,2,1,5,1,1,2,1,1,2,2,bi,1,j,v,1,1,1h,5,3,o,2,r,3,3,2,n,2,b,1,1,1,1,3,1,3,1,7,1,3,1,3,1,z,1,1,1,1d,1,1,1,7,1,1,1,2n3,2,2,2,2,2,2,2,2,2,2,2,3,2,2,7,1,2,1,2,1,2,1,2,1,n,a,e,2,2,2,2,2,2,2,2,2,2,2,3,2,2,7,1,2,1,2,1,2,1,2,1,n,3,1,1,1,4,1864,2,f,3n,1,f0,1,a7,1,2,70,1,ot"; export const CASE_FOLDING = "1t:2p,1:2q,1:2r,1:2s,1:2t,1:2u,1:2v,1:2w,1:2x,1:2y,1:2z,1:30,1:31,1:32,1:33,1:34,1:35,1:36,1:37,1:38,1:39,1:3a,1:3b,1:3c,1:3d,1:3e,2j:qk,b:68,1:69,1:6a,1:6b,1:6c,1:6d,1:6e,1:6f,1:6g,1:6h,1:6i,1:6j,1:6k,1:6l,1:6m,1:6n,1:6o,1:6p,1:6q,1:6r,1:6s,1:6t,1:6u,2:6w,1:6x,1:6y,1:6z,1:70,1:71,1:72,1:37.37,x:75,2:77,2:79,2:7b,2:7d,2:7f,2:7h,2:7j,2:7l,2:7n,2:7p,2:7r,2:7t,2:7v,2:7x,2:7z,2:81,2:83,2:85,2:87,2:89,2:8b,2:8d,2:8f,2:2x.lj,2:8j,2:8l,2:8n,3:8q,2:8s,2:8u,2:8w,2:8y,2:90,2:92,2:94,2:jg.32,1:97,2:99,2:9b,2:9d,2:9f,2:9h,2:9j,2:9l,2:9n,2:9p,2:9r,2:9t,2:9v,2:9x,2:9z,2:a1,2:a3,2:a5,2:a7,2:a9,2:ab,2:ad,2:af,2:73,1:ai,2:ak,2:am,2:37,2:gj,1:ar,2:at,2:gk,1:aw,2:gm,1:gn,1:b0,3:d9,1:gp,1:gr,1:b6,2:gw,1:gz,2:h5,1:h4,1:bd,4:hb,1:he,2:hh,1:bl,2:bn,2:bp,2:hs,1:bs,2:hv,3:bx,2:i0,1:c0,2:i2,1:i3,1:c4,2:c6,2:ia,1:c9,4:cd,8:cm,1:cm,2:cp,1:cp,2:cs,1:cs,2:cu,2:cw,2:cy,2:d0,2:d2,2:d4,2:d6,2:d8,3:db,2:dd,2:df,2:dh,2:dj,2:dl,2:dn,2:dp,2:dr,2:2y.lo,1:dv,1:dv,2:dx,2:b9,1:cf,1:e1,2:e3,2:e5,2:e7,2:e9,2:eb,2:ed,2:ef,2:eh,2:ej,2:el,2:en,2:ep,2:er,2:et,2:ev,2:ex,2:ez,2:f1,2:f3,2:bi,2:f7,2:f9,2:fb,2:fd,2:ff,2:fh,2:fj,2:fl,2:fn,8:8rp,1:fw,2:be,1:8rq,3:g2,2:ao,1:i1,1:i4,1:g7,2:g9,2:gb,2:gd,2:gf,6v:qh,17:oh,2:oj,4:on,9:s3,7:q4,2:q5,1:q6,1:q7,2:r0,2:r1,1:r2,1:qh.lk.ld,1:q9,1:qa,1:qb,1:qc,1:qd,1:qe,1:qf,1:qg,1:qh,1:qi,1:qj,1:qk,1:ql,1:qm,1:qn,1:qo,1:qp,2:qr,1:qs,1:qt,1:qu,1:qv,1:qw,1:qx,1:qy,1:qz,5:qt.lk.ld,i:qr,d:rb,1:qa,1:qg,4:qu,1:qo,2:rd,2:rf,2:rh,2:rj,2:rl,2:rn,2:rp,2:rr,2:rt,2:rv,2:rx,2:rz,2:qi,1:qp,3:qg,1:qd,2:s8,2:s2,1:sb,3:or,1:os,1:ot,1:uo,1:up,1:uq,1:ur,1:us,1:ut,1:uu,1:uv,1:uw,1:ux,1:uy,1:uz,1:v0,1:v1,1:v2,1:v3,1:ts,1:tt,1:tu,1:tv,1:tw,1:tx,1:ty,1:tz,1:u0,1:u1,1:u2,1:u3,1:u4,1:u5,1:u6,1:u7,1:u8,1:u9,1:ua,1:ub,1:uc,1:ud,1:ue,1:uf,1:ug,1:uh,1:ui,1:uj,1:uk,1:ul,1:um,1:un,1d:v5,2:v7,2:v9,2:vb,2:vd,2:vf,2:vh,2:vj,2:vl,2:vn,2:vp,2:vr,2:vt,2:vv,2:vx,2:vz,2:w1,a:wb,2:wd,2:wf,2:wh,2:wj,2:wl,2:wn,2:wp,2:wr,2:wt,2:wv,2:wx,2:wz,2:x1,2:x3,2:x5,2:x7,2:x9,2:xb,2:xd,2:xf,2:xh,2:xj,2:xl,2:xn,2:xp,2:xr,2:y7,1:xu,2:xw,2:xy,2:y0,2:y2,2:y4,2:y6,3:y9,2:yb,2:yd,2:yf,2:yh,2:yj,2:yl,2:yn,2:yp,2:yr,2:yt,2:yv,2:yx,2:yz,2:z1,2:z3,2:z5,2:z7,2:z9,2:zb,2:zd,2:zf,2:zh,2:zj,2:zl,2:zn,2:zp,2:zr,2:zt,2:zv,2:zx,2:zz,2:101,2:103,2:105,2:107,2:109,2:10b,2:10d,2:10f,2:10h,2:10j,2:10l,2:10n,2:10p,2:10r,2:10t,2:10v,3:129,1:12a,1:12b,1:12c,1:12d,1:12e,1:12f,1:12g,1:12h,1:12i,1:12j,1:12k,1:12l,1:12m,1:12n,1:12o,1:12p,1:12q,1:12r,1:12s,1:12t,1:12u,1:12v,1:12w,1:12x,1:12y,1:12z,1:130,1:131,1:132,1:133,1:134,1:135,1:136,1:137,1:138,1:139,1:13a,1d:12d.136,26x:8w0,1:8w1,1:8w2,1:8w3,1:8w4,1:8w5,1:8w6,1:8w7,1:8w8,1:8w9,1:8wa,1:8wb,1:8wc,1:8wd,1:8we,1:8wf,1:8wg,1:8wh,1:8wi,1:8wj,1:8wk,1:8wl,1:8wm,1:8wn,1:8wo,1:8wp,1:8wq,1:8wr,1:8ws,1:8wt,1:8wu,1:8wv,1:8ww,1:8wx,1:8wy,1:8wz,1:8x0,1:8x1,2:8x3,6:8x9,mj:3xs,1:3xt,1:3xu,1:3xv,1:3xw,1:3xx,1oj:tu,1:tw,1:u6,1:u9,1:ua,1:ua,1:ui,1:v7,1:wuj,8:3bk,1:3bl,1:3bm,1:3bn,1:3bo,1:3bp,1:3bq,1:3br,1:3bs,1:3bt,1:3bu,1:3bv,1:3bw,1:3bx,1:3by,1:3bz,1:3c0,1:3c1,1:3c2,1:3c3,1:3c4,1:3c5,1:3c6,1:3c7,1:3c8,1:3c9,1:3ca,1:3cb,1:3cc,1:3cd,1:3ce,1:3cf,1:3cg,1:3ch,1:3ci,1:3cj,1:3ck,1:3cl,1:3cm,1:3cn,1:3co,1:3cp,1:3cq,3:3ct,1:3cu,1:3cv,8x:5xd,2:5xf,2:5xh,2:5xj,2:5xl,2:5xn,2:5xp,2:5xr,2:5xt,2:5xv,2:5xx,2:5xz,2:5y1,2:5y3,2:5y5,2:5y7,2:5y9,2:5yb,2:5yd,2:5yf,2:5yh,2:5yj,2:5yl,2:5yn,2:5yp,2:5yr,2:5yt,2:5yv,2:5yx,2:5yz,2:5z1,2:5z3,2:5z5,2:5z7,2:5z9,2:5zb,2:5zd,2:5zf,2:5zh,2:5zj,2:5zl,2:5zn,2:5zp,2:5zr,2:5zt,2:5zv,2:5zx,2:5zz,2:601,2:603,2:605,2:607,2:609,2:60b,2:60d,2:60f,2:60h,2:60j,2:60l,2:60n,2:60p,2:60r,2:60t,2:60v,2:60x,2:60z,2:611,2:613,2:615,2:617,2:619,2:61b,2:61d,2:61f,2:61h,2:2w.mp,1:38.lk,1:3b.lm,1:3d.lm,1:2p.ji,1:601,3:37.37,2:61t,2:61v,2:61x,2:61z,2:621,2:623,2:625,2:627,2:629,2:62b,2:62d,2:62f,2:62h,2:62j,2:62l,2:62n,2:62p,2:62r,2:62t,2:62v,2:62x,2:62z,2:631,2:633,2:635,2:637,2:639,2:63b,2:63d,2:63f,2:63h,2:63j,2:63l,2:63n,2:63p,2:63r,2:63t,2:63v,2:63x,2:63z,2:641,2:643,2:645,2:647,2:649,2:64b,2:64d,2:64f,a:64g,1:64h,1:64i,1:64j,1:64k,1:64l,1:64m,1:64n,9:64w,1:64x,1:64y,1:64z,1:650,1:651,b:65c,1:65d,1:65e,1:65f,1:65g,1:65h,1:65i,1:65j,9:65s,1:65t,1:65u,1:65v,1:65w,1:65x,1:65y,1:65z,9:668,1:669,1:66a,1:66b,1:66c,1:66d,3:qt.lv,2:qt.lv.lc,2:qt.lv.ld,2:qt.lv.n6,3:66p,2:66r,2:66t,2:66v,9:674,1:675,1:676,1:677,1:678,1:679,1:67a,1:67b,h:64g.qh,1:64h.qh,1:64i.qh,1:64j.qh,1:64k.qh,1:64l.qh,1:64m.qh,1:64n.qh,1:64g.qh,1:64h.qh,1:64i.qh,1:64j.qh,1:64k.qh,1:64l.qh,1:64m.qh,1:64n.qh,1:65c.qh,1:65d.qh,1:65e.qh,1:65f.qh,1:65g.qh,1:65h.qh,1:65i.qh,1:65j.qh,1:65c.qh,1:65d.qh,1:65e.qh,1:65f.qh,1:65g.qh,1:65h.qh,1:65i.qh,1:65j.qh,1:674.qh,1:675.qh,1:676.qh,1:677.qh,1:678.qh,1:679.qh,1:67a.qh,1:67b.qh,1:674.qh,1:675.qh,1:676.qh,1:677.qh,1:678.qh,1:679.qh,1:67a.qh,1:67b.qh,3:67k.qh,1:q9.qh,1:q4.qh,2:q9.n6,1:q9.n6.qh,1:69c,1:69d,1:67k,1:67l,1:q9.qh,2:qh,4:67o.qh,1:qf.qh,1:q6.qh,2:qf.n6,1:qf.n6.qh,1:67m,1:67n,1:67o,1:67p,1:qf.qh,6:qh.lk.lc,1:qh.lk.ld,3:qh.n6,1:qh.lk.n6,1:6a8,1:6a9,1:67q,1:67r,7:qt.lk.lc,1:qt.lk.ld,1:qp.lv,2:qt.n6,1:qt.lk.n6,1:6ao,1:6ap,1:67u,1:67v,1:6at,6:67w.qh,1:qx.qh,1:r2.qh,2:qx.n6,1:qx.n6.qh,1:67s,1:67t,1:67w,1:67x,1:qx.qh,8a:qx,4:2z,1:6d,7:6ku,1a:6ls,1:6lt,1:6lu,1:6lv,1:6lw,1:6lx,1:6ly,1:6lz,1:6m0,1:6m1,1:6m2,1:6m3,1:6m4,1:6m5,1:6m6,1:6m7,k:6mc,mr:79s,1:79t,1:79u,1:79v,1:79w,1:79x,1:79y,1:79z,1:7a0,1:7a1,1:7a2,1:7a3,1:7a4,1:7a5,1:7a6,1:7a7,1:7a8,1:7a9,1:7aa,1:7ab,1:7ac,1:7ad,1:7ae,1:7af,1:7ag,1:7ah,1f5:8q8,1:8q9,1:8qa,1:8qb,1:8qc,1:8qd,1:8qe,1:8qf,1:8qg,1:8qh,1:8qi,1:8qj,1:8qk,1:8ql,1:8qm,1:8qn,1:8qo,1:8qp,1:8qq,1:8qr,1:8qs,1:8qt,1:8qu,1:8qv,1:8qw,1:8qx,1:8qy,1:8qz,1:8r0,1:8r1,1:8r2,1:8r3,1:8r4,1:8r5,1:8r6,1:8r7,1:8r8,1:8r9,1:8ra,1:8rb,1:8rc,1:8rd,1:8re,1:8rf,1:8rg,1:8rh,1:8ri,1:8rj,1d:8rl,2:h7,1:5tp,1:hp,3:8rs,2:8ru,2:8rw,2:gh,1:hd,1:gg,1:gi,2:8s3,3:8s6,9:fz,1:g0,1:8sh,2:8sj,2:8sl,2:8sn,2:8sp,2:8sr,2:8st,2:8sv,2:8sx,2:8sz,2:8t1,2:8t3,2:8t5,2:8t7,2:8t9,2:8tb,2:8td,2:8tf,2:8th,2:8tj,2:8tl,2:8tn,2:8tp,2:8tr,2:8tt,2:8tv,2:8tx,2:8tz,2:8u1,2:8u3,2:8u5,2:8u7,2:8u9,2:8ub,2:8ud,2:8uf,2:8uh,2:8uj,2:8ul,2:8un,2:8up,2:8ur,2:8ut,2:8uv,2:8ux,2:8uz,2:8v1,2:8v3,2:8v5,2:8v7,9:8vg,2:8vi,5:8vn,nym:wu9,2:wub,2:wud,2:wuf,2:wuh,2:wuj,2:wul,2:wun,2:wup,2:wur,2:wut,2:wuv,2:wux,2:wuz,2:wv1,2:wv3,2:wv5,2:wv7,2:wv9,2:wvb,2:wvd,2:wvf,2:wvh,k:ww1,2:ww3,2:ww5,2:ww7,2:ww9,2:wwb,2:wwd,2:wwf,2:wwh,2:wwj,2:wwl,2:wwn,2:wwp,2:wwr,3s:x0j,2:x0l,2:x0n,2:x0p,2:x0r,2:x0t,2:x0v,4:x0z,2:x11,2:x13,2:x15,2:x17,2:x19,2:x1b,2:x1d,2:x1f,2:x1h,2:x1j,2:x1l,2:x1n,2:x1p,2:x1r,2:x1t,2:x1v,2:x1x,2:x1z,2:x21,2:x23,2:x25,2:x27,2:x29,2:x2b,2:x2d,2:x2f,2:x2h,2:x2j,2:x2l,2:x2n,b:x2y,2:x30,2:5tl,1:x33,2:x35,2:x37,2:x39,2:x3b,5:x3g,2:h1,3:x3l,2:x3n,4:x3r,2:x3t,2:x3v,2:x3x,2:x3z,2:x41,2:x43,2:x45,2:x47,2:x49,2:h2,1:gs,1:gx,1:h8,1:h6,2:im,1:hz,1:il,1:xub,1:x4l,2:x4n,2:x4p,2:x4r,2:x4t,2:x4v,2:x4x,2:x4z,2:x3o,1:hu,1:5u6,1:x54,2:x56,7:x5d,6:x5j,2:x5l,t:x6e,or:3vk,1:3vl,1:3vm,1:3vn,1:3vo,1:3vp,1:3vq,1:3vr,1:3vs,1:3vt,1:3vu,1:3vv,1:3vw,1:3vx,1:3vy,1:3vz,1:3w0,1:3w1,1:3w2,1:3w3,1:3w4,1:3w5,1:3w6,1:3w7,1:3w8,1:3w9,1:3wa,1:3wb,1:3wc,1:3wd,1:3we,1:3wf,1:3wg,1:3wh,1:3wi,1:3wj,1:3wk,1:3wl,1:3wm,1:3wn,1:3wo,1:3wp,1:3wq,1:3wr,1:3ws,1:3wt,1:3wu,1:3wv,1:3ww,1:3wx,1:3wy,1:3wz,1:3x0,1:3x1,1:3x2,1:3x3,1:3x4,1:3x5,1:3x6,1:3x7,1:3x8,1:3x9,1:3xa,1:3xb,1:3xc,1:3xd,1:3xe,1:3xf,1:3xg,1:3xh,1:3xi,1:3xj,1:3xk,1:3xl,1:3xm,1:3xn,1:3xo,1:3xp,1:3xq,1:3xr,fnl:2u.2u,1:2u.2x,1:2u.30,1:2u.2u.2x,1:2u.2u.30,1:37.38,1:37.38,d:12s.12u,1:12s.12d,1:12s.12j,1:132.12u,1:12s.12l,sq:1ef5,1:1ef6,1:1ef7,1:1ef8,1:1ef9,1:1efa,1:1efb,1:1efc,1:1efd,1:1efe,1:1eff,1:1efg,1:1efh,1:1efi,1:1efj,1:1efk,1:1efl,1:1efm,1:1efn,1:1efo,1:1efp,1:1efq,1:1efr,1:1efs,1:1eft,1:1efu,xy:1fe0,1:1fe1,1:1fe2,1:1fe3,1:1fe4,1:1fe5,1:1fe6,1:1fe7,1:1fe8,1:1fe9,1:1fea,1:1feb,1:1fec,1:1fed,1:1fee,1:1fef,1:1feg,1:1feh,1:1fei,1:1fej,1:1fek,1:1fel,1:1fem,1:1fen,1:1feo,1:1fep,1:1feq,1:1fer,1:1fes,1:1fet,1:1feu,1:1fev,1:1few,1:1fex,1:1fey,1:1fez,1:1ff0,1:1ff1,1:1ff2,1:1ff3,3t:1fiw,1:1fix,1:1fiy,1:1fiz,1:1fj0,1:1fj1,1:1fj2,1:1fj3,1:1fj4,1:1fj5,1:1fj6,1:1fj7,1:1fj8,1:1fj9,1:1fja,1:1fjb,1:1fjc,1:1fjd,1:1fje,1:1fjf,1:1fjg,1:1fjh,1:1fji,1:1fjj,1:1fjk,1:1fjl,1:1fjm,1:1fjn,1:1fjo,1:1fjp,1:1fjq,1:1fjr,1:1fjs,1:1fjt,1:1fju,1:1fjv,4d:1fo7,1:1fo8,1:1fo9,1:1foa,1:1fob,1:1foc,1:1fod,1:1foe,1:1fof,1:1fog,1:1foh,2:1foj,1:1fok,1:1fol,1:1fom,1:1fon,1:1foo,1:1fop,1:1foq,1:1for,1:1fos,1:1fot,1:1fou,1:1fov,1:1fow,1:1fox,2:1foz,1:1fp0,1:1fp1,1:1fp2,1:1fp3,1:1fp4,1:1fp5,2:1fp7,1:1fp8,1d7:1h34,1:1h35,1:1h36,1:1h37,1:1h38,1:1h39,1:1h3a,1:1h3b,1:1h3c,1:1h3d,1:1h3e,1:1h3f,1:1h3g,1:1h3h,1:1h3i,1:1h3j,1:1h3k,1:1h3l,1:1h3m,1:1h3n,1:1h3o,1:1h3p,1:1h3q,1:1h3r,1:1h3s,1:1h3t,1:1h3u,1:1h3v,1:1h3w,1:1h3x,1:1h3y,1:1h3z,1:1h40,1:1h41,1:1h42,1:1h43,1:1h44,1:1h45,1:1h46,1:1h47,1:1h48,1:1h49,1:1h4a,1:1h4b,1:1h4c,1:1h4d,1:1h4e,1:1h4f,1:1h4g,1:1h4h,1:1h4i,2cu:1jgg,1:1jgh,1:1jgi,1:1jgj,1:1jgk,1:1jgl,1:1jgm,1:1jgn,1:1jgo,1:1jgp,1:1jgq,1:1jgr,1:1jgs,1:1jgt,1:1jgu,1:1jgv,1:1jgw,1:1jgx,1:1jgy,1:1jgz,1:1jh0,1:1jh1,1:1jh2,1:1jh3,1:1jh4,1:1jh5,1:1jh6,1:1jh7,1:1jh8,1:1jh9,1:1jha,1:1jhb,gw1:20dc,1:20dd,1:20de,1:20df,1:20dg,1:20dh,1:20di,1:20dj,1:20dk,1:20dl,1:20dm,1:20dn,1:20do,1:20dp,1:20dq,1:20dr,1:20ds,1:20dt,1:20du,1:20dv,1:20dw,1:20dx,1:20dy,1:20dz,1:20e0,1:20e1,1:20e2,1:20e3,1:20e4,1:20e5,1:20e6,1:20e7,o81:2oma,1:2omb,1:2omc,1:2omd,1:2ome,1:2omf,1:2omg,1:2omh,1:2omi,1:2omj,1:2omk,1:2oml,1:2omm,1:2omn,1:2omo,1:2omp,1:2omq,1:2omr,1:2oms,1:2omt,1:2omu,1:2omv,1:2omw,1:2omx,1:2omy,1:2omz,1:2on0,1:2on1,1:2on2,1:2on3,1:2on4,1:2on5,1:2on6,1:2on7"; +export const STREAM_SAFE = "4o:0.1,7:0.1,5:0.1,4:0.1,8:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,4:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,5:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,4:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,y:0.1,1:0.1,e:0.1,1:0.1,k:0.1,1:0.1,1:0.1,7:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,2:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,4:0.1,1:0.1,3:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,7:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,4l:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,z:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:2.2,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,b:0.1,a:0.1,1:0.2,1:0.1,2:0.1,1:0.1,1:0.1,2:0.1,2:0.1,1:0.1,1:0.2,q:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,q:0.1,1:0.1,1:0.1,1:0.1,1:0.1,5:0.1,1:0.1,18:0.1,1:0.1,2:0.1,4:0.1,5:0.1,1:0.1,1:0.1,b:0.1,w:0.1,n:0.1,1:0.1,2:0.1,4:0.1,5:0.1,1:0.1,1:0.1,o:0.1,1:0.1,c:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1m:0.1,1:0.1,e:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,48:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,2:1.1,1:1.1,2:1.1,1:1.1,2:1.1,21:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,8:0.1,1:0.1,1:0.1,1:0.1,1:0.1,11:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,h:1.1,28:0.1,2:0.1,h:0.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,10:1.1,v:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,4h:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,a:1.1,p:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,18:1.1,1:1.1,1:1.1,1p:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,17:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,16:0.1,8:0.1,3:0.1,8:1.1,h:1.1,4:1.1,1:1.1,1:1.1,1:1.1,4:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2l:1.1,2:1.1,d:0.1,1:0.1,1:1.1,a:1.1,5:0.1,1:0.1,2:0.1,v:1.1,1h:0.1,3:0.1,6:1.1,h:1.1,c:0.1,1:0.1,1:0.1,3:0.1,2m:1.1,h:1.1,33:1.1,2:1.1,a:0.1,3:0.1,1:0.1,1:1.1,9:1.1,1:1.1,5:0.1,1:0.1,1j:0.1,16:1.1,c:0.1,1:0.1,1:0.1,1:1.1,a:1.1,2t:1.1,c:0.1,5:1.1,8:1.1,1:1.1,2u:1.1,4:0.1,2:1.1,5:0.1,1:0.1,2:0.1,1:0.2,2:1.1,8:1.1,1:1.1,2t:1.1,1:1.1,2:1.1,c:0.1,1:0.1,1:0.1,1:1.1,a:1.1,37:1.1,5:1.1,b:0.1,2:0.1,1:0.2,1:0.1,1:1.1,2h:1.1,1:1.1,1:1.1,e:1.1,1:1.1,1:1.1,1:1.1,31:1.1,1:1.1,1:1.1,e:1.1,1:1.1,1:1.1,1:1.1,25:1.1,1:1.1,s:1.1,2:1.1,2:1.1,1k:1.1,1:1.1,1:2.2,1:1.1,1:2.2,1:0.1,1:0.2,1:0.1,1:0.2,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:2.2,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1r:1.1,2o:0.1,8:1.1,9:1.1,2:1.1,1:1.1,2b:1.1,5w:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1f:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,bf:1.1,1:1.1,1:1.1,qd:1.1,1:1.1,v:1.1,4e:1.1,b:1.1,5o:1.1,40:1.1,1:1.1,1:1.1,64:1.1,1:1.1,20:1.1,l:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1d:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1k:0.1,2:0.1,2:0.1,2:0.1,2:0.1,4:0.1,y:1.1,1:1.1,6:0.1,2:0.1,3:0.1,1:0.1,2:0.1,1:1.1,13:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1j:1.1,1:1.1,1n:1.1,c:1.1,1:1.1,1w:1.1,49:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,5:1.1,7:1.1,4:1.1,1:1.1,5j:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,5:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,7:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,3:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,3:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,3:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,3:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,2:0.1,2:0.2,2:0.2,2:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.2,1:0.2,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.3,1:0.1,1:0.1,1:0.2,1:0.1,1:0.2,2:0.1,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.2,2:0.1,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,3:0.1,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,2:0.2,1:0.2,1:0.2,1:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.2,1:0.2,4:0.2,1:0.1,1:0.2,2:0.1,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,p:0.1,13:0.1,42:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,5:1.1,4:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1n:0.1,33:0.1,1:0.1,j:0.1,v:0.1,1:0.1,1:0.1,1h:0.1,5:0.1,3:0.1,o:0.1,2:0.1,r:0.1,3:0.1,3:0.1,2:0.1,n:0.1,2:0.1,b:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3:0.1,1:0.1,3:0.1,1:0.1,7:0.1,1:0.1,3:0.1,1:0.1,3:0.1,1:0.1,z:0.1,1:0.1,1:0.1,1:0.1,1d:0.1,1:0.1,1:0.1,1:0.1,7:0.1,1:0.1,1:0.1,1:0.1,1kf:0.1,er:1.1,1:1.1,1:1.1,3y:1.1,2p:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,ff:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,t:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,3:0.1,2:0.1,2:0.1,7:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,n:0.1,5:1.1,1:1.1,1:0.1,1:0.1,2:0.1,e:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,2:0.1,3:0.1,2:0.1,2:0.1,7:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,n:0.1,3:0.1,1:0.1,1:0.1,1:0.1,4:0.1,1h:1.1,2:1.1,1:1.1,4:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,g:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,7f:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,3q:0.1,3:0.1,9:0.1,e:0.1,3:0.1,h:0.1,9:0.1,5:0.1,b:0.1,3:0.1,mqp:1.1,5:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,x:1.1,1:1.1,29:1.1,1:1.1,7p:1.1,12:1.1,48:1.1,s:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1m:1.1,1:1.1,1:1.1,12:1.1,2o:1.1,d:1.1,6o:1.1,2:1.1,1:1.1,1:1.1,3:1.1,1:1.1,6:1.1,1:1.1,2:1.1,1h:1.1,6v:1.1,j:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,70a:0.1,1:1.1,1:0.1,b:0.1,1:0.1,1:0.2,1:0.2,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,2:0.1,1:0.1,2:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2e:0.1,1:0.1,b:0.1,1:0.1,4q:0.1,1:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,19:0.1,21:0.1,p:0.2,1:0.2,1:0.2,20:0.1,1:0.1,6b:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,q:0.1,1:0.1,1:0.1,1:0.1,10:0.1,1:0.1,1:0.1,2:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,2x:0.1,1:0.1,1:0.1,1:0.1,1:0.1,1:0.1,4k:1.1,1:1.1,4:1.1,2:1.1,1:1.1,4:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,j:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,7:0.1,ey:1.1,6b:1.1,46:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1ar:1.1,2:1.1,15:1.1,1:1.1,1:1.1,5:1.1,4m:1.1,1:1.1,fy:1.1,1:1.1,1:1.1,1:1.1,as:1.1,1:1.1,29:1.1,1:1.1,1:1.1,1z:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1e:1.1,1:1.1,1:1.1,1:1.1,5d:1.1,16:1.1,f:1.1,r:0.1,2:0.1,f:0.1,e:1.1,1:1.1,1y:1.1,1:1.1,1:1.1,11:1.1,7:0.1,1:0.1,4:1.1,1:1.1,1r:1.1,25:1.1,a:1.1,2z:1.1,1:1.1,4z:1.1,1:1.1,29:1.1,1:1.1,2:1.1,d:0.1,1:0.1,1:1.1,a:1.1,f:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,4:1.1,1:1.1,1:1.1,1:1.1,1:1.1,5q:1.1,4:1.1,o:1.1,2a:1.1,a:1.1,1:0.1,1:0.1,1:1.1,1:0.1,4:1.1,1:1.1,6k:1.1,b:0.1,1:0.1,4:1.1,1:1.1,3j:1.1,3b:1.1,1:1.1,38:1.1,7i:1.1,1:1.1,6u:1.1,8:0.1,5:1.1,1:1.1,5:1.1,4d:1.1,2c:1.1,j:1.1,2a:1.1,bq:1.1,77:1.1,2:1.1,1:1.1,2a:1.1,bu:1.1,1:1.1,ey6:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1o:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,xm:1.1,1:1.1,f59:1.1,43k:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,1:0.2,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,4:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,9:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,v:1.1,1:1.1,1:1.1,1:1.1,e:0.1,1:0.1,1:0.2,1:0.2,1:0.2,1:0.2,3m:1.1,1:1.1,1:1.1,2po:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,3:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2:1.1,1:1.1,2:1.1,1:1.1,1:1.1,1:1.1,1:1.1,2t:1.1,4h:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,ag:1.1,1q:1.1,1:1.1,1:1.1,1:1.1,e5:1.1,1:1.1,1:1.1,1:1.1,rl:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,32:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1:1.1,1qh:0.1"; diff --git a/packages/skill-tree/src/unicode-15.ts b/packages/skill-tree/src/unicode-15.ts index 9b3aee5..b20c8dc 100644 --- a/packages/skill-tree/src/unicode-15.ts +++ b/packages/skill-tree/src/unicode-15.ts @@ -13,6 +13,7 @@ import { COMBINING_CLASSES, FORMAT_RANGES, PRIMARY_COMPOSITES, + STREAM_SAFE, UNICODE_VERSION, } from "./unicode-15-tables"; @@ -62,6 +63,8 @@ const assigned = decodeRanges(ASSIGNED_RANGES); const format = decodeRanges(FORMAT_RANGES); const decompositions = decodeMap(CANONICAL_DECOMPOSITIONS); const folding = decodeMap(CASE_FOLDING); +/** Leading and trailing non-starter counts of x/text norm's Stream-Safe Text Processing. */ +const streamSafe = decodeMap(STREAM_SAFE); const combiningClasses = new Map(); { @@ -129,50 +132,115 @@ function decomposeInto(cp: number, out: number[]): void { else for (const m of mapping) decomposeInto(m, out); } -/** Canonical decomposition with canonical ordering (NFD) over code points. */ -function nfdCodePoints(cps: Iterable): number[] { - const out: number[] = []; - for (const cp of cps) decomposeInto(cp, out); - // Canonical ordering: stable insertion sort of each run of non-starters. - for (let i = 1; i < out.length; i++) { - const cc = combiningClass(out[i]!); - if (cc === 0) continue; - let j = i; - while (j > 0 && combiningClass(out[j - 1]!) > cc) { - [out[j - 1], out[j]] = [out[j]!, out[j - 1]!]; - j--; +/** U+034F COMBINING GRAPHEME JOINER, a starter that never composes. */ +const CGJ = 0x034f; +const MAX_NON_STARTERS = 30; + +/** Code points that are the second of a primary composite pair (x/text "combines backward"). */ +const combinesBackward = new Set(); +for (const key of compositions.keys()) combinesBackward.add(key % 0x110000); + +/** + * Splits code points into the segments Go's x/text norm normalizes one at a + * time, each decomposed and canonically ordered. A segment starts at a code + * point with no leading non-starter. Stream-Safe Text Processing: when a + * code point would extend a run past 30 non-starters (counted over + * compatibility decompositions, as x/text does), a CGJ ends the segment and + * the code point starts the next one, so a string with such a run is never + * NFC. + */ +function segments(cps: Iterable): number[][] { + const out: number[][] = []; + let segment: number[] = []; + let run = 0; + for (const cp of cps) { + const [lead = 0, trail = 0] = streamSafe.get(cp) ?? []; + if (lead > 0 && run + lead > MAX_NON_STARTERS) { + segment.push(CGJ); + run = 0; + out.push(segment); + segment = []; + } else if (lead === 0 && segment.length > 0) { + out.push(segment); + segment = []; + } + run = lead === 0 ? trail : run + lead; + decomposeInto(cp, segment); + } + if (segment.length > 0) out.push(segment); + for (const s of out) { + // Canonical ordering: stable insertion sort of each run of non-starters. + for (let i = 1; i < s.length; i++) { + const cc = combiningClass(s[i]!); + if (cc === 0) continue; + let j = i; + while (j > 0 && combiningClass(s[j - 1]!) > cc) { + [s[j - 1], s[j]] = [s[j]!, s[j - 1]!]; + j--; + } } } return out; } -function composePair(a: number, b: number): number | undefined { - const l = a - L_BASE, v = b - V_BASE; - if (l >= 0 && l < L_COUNT && v >= 0 && v < V_COUNT) return S_BASE + (l * V_COUNT + v) * T_COUNT; - const s = a - S_BASE, t = b - T_BASE; - if (s >= 0 && s < S_COUNT && s % T_COUNT === 0 && t > 0 && t < T_COUNT) return a + t; - return compositions.get(pairKey(a, b)); +/** + * Recomposes one segment exactly as x/text reorderBuffer.compose does. It + * differs from UAX #15 in one way: a starter only becomes the composition + * target when a code point that combines backward follows it directly, so a + * starter such as U+FF9E inside a segment does not block. + */ +function composeSegment(b: number[]): number[] { + const ccc = b.map(combiningClass); + let k = 1; + let s = 0; + const keep = (i: number) => { + b[k] = b[i]!; + ccc[k++] = ccc[i]!; + }; + const assign = (cp: number) => { + b[s] = cp; + ccc[s] = 0; + }; + for (let i = 1; i < b.length; i++) { + if (b[i]! >= 0x1100 && b[i]! <= 0x11ff) { + // Hangul mode for the rest of the segment, as in x/text combineHangul. + for (; i < b.length; i++) { + const cccB = ccc[k - 1]!; + if (cccB === 0) s = k - 1; + if (s !== k - 1 && cccB >= ccc[i]!) { + keep(i); + continue; + } + const l = b[s]! - L_BASE, v = b[i]! - V_BASE, lv = b[s]! - S_BASE, t = b[i]! - T_BASE; + if (l >= 0 && l < L_COUNT && v >= 0 && v < V_COUNT) assign(S_BASE + (l * V_COUNT + v) * T_COUNT); + else if (lv >= 0 && lv < S_COUNT && lv % T_COUNT === 0 && t > 0 && t < T_COUNT) assign(b[s]! + t); + else keep(i); + } + break; + } + if (combinesBackward.has(b[i]!)) { + const cccB = ccc[k - 1]!; + let blocked = false; + if (cccB === 0) s = k - 1; + else blocked = s !== k - 1 && cccB >= ccc[i]!; + const composite = blocked ? undefined : compositions.get(pairKey(b[s]!, b[i]!)); + if (composite !== undefined) { + assign(composite); + continue; + } + } + keep(i); + } + b.length = Math.min(k, b.length); + return b; +} + +function nfdCodePoints(cps: Iterable): number[] { + return segments(cps).flat(); } function nfcCodePoints(cps: Iterable): number[] { - const d = nfdCodePoints(cps); - if (d.length === 0) return d; - const out = [d[0]!]; - let starterPos = 0; - let lastClass = combiningClass(d[0]!) === 0 ? 0 : 256; - for (let i = 1; i < d.length; i++) { - const ch = d[i]!; - const chClass = combiningClass(ch); - const composite = composePair(out[starterPos]!, ch); - if (composite !== undefined && (lastClass < chClass || lastClass === 0)) { - out[starterPos] = composite; - continue; - } - if (chClass === 0) starterPos = out.length; - lastClass = chClass; - out.push(ch); - } - return out; + return segments(cps).flatMap(composeSegment); } const codePoints = (s: string): number[] => Array.from(s, (ch) => ch.codePointAt(0)!); diff --git a/packages/skill-tree/src/zip-reader.ts b/packages/skill-tree/src/zip-reader.ts index d360735..0aaafd5 100644 --- a/packages/skill-tree/src/zip-reader.ts +++ b/packages/skill-tree/src/zip-reader.ts @@ -57,7 +57,7 @@ async function* rawData(src: RandomAccessSource, start: number, length: number): } /** Content of an entry, inflated when deflated, with its CRC-32 and size checked at the end. */ -async function* content(src: RandomAccessSource, central: CentralEntry, dataStart: number, verify: boolean): AsyncGenerator { +async function* content(src: RandomAccessSource, central: CentralEntry, dataStart: number): AsyncGenerator { const raw = rawData(src, dataStart, central.csize); const data = central.method === 8 ? decompress(raw, "deflate-raw") : raw; let crc = 0; @@ -67,7 +67,7 @@ async function* content(src: RandomAccessSource, central: CentralEntry, dataStar size += chunk.length; yield chunk; } - if (verify && (crc !== central.crc || size !== central.usize)) throw readFailed("zip entry data does not match its CRC-32 or size"); + if (crc !== central.crc || size !== central.usize) throw readFailed("zip entry data does not match its CRC-32 or size"); } async function readEntries(src: RandomAccessSource, collector: EntryCollector, limits: TreeLimits): Promise { @@ -106,16 +106,18 @@ async function readEntries(src: RandomAccessSource, collector: EntryCollector, l fault ??= sizesDisagree(local, c, descriptor); const type = (c.externalAttrs >>> 16) & S_IFMT; const base = { path: name.path, utf8Valid: name.utf8Valid, ...(fault === undefined ? {} : { reason: fault }) }; - if (type === S_IFDIR && fault === undefined) { - collector.add({ ...base, mode: "", size: 0, sha256: "", kind: "directory" }); + if (fault !== undefined) { + // A faulted entry (header disagreement, encryption, unknown method, + // non-regular type) is unsupported: its data is never inflated and it + // counts toward no file or byte limit, as a tar special entry. + collector.add({ ...base, mode: headerMode(c.externalAttrs >>> 16), size: 0, sha256: "", kind: "special" }); continue; } - if (dataEnd > dir.cdOffset) { - collector.add({ ...base, mode: "", size: 0, sha256: "", kind: "special" }); + if (type === S_IFDIR) { + collector.add({ ...base, mode: "", size: 0, sha256: "", kind: "directory" }); continue; } - // Header agreement comes first; only agreeing entries are checked against their CRC-32. - const hashed = await collector.hashFile(name.path, content(src, c, local.dataStart, fault === undefined)); + const hashed = await collector.hashFile(name.path, content(src, c, local.dataStart)); collector.add({ ...base, mode: headerMode(c.externalAttrs >>> 16), ...hashed, kind: "regular" }); } if (pos !== dir.cdOffset) archiveFault ??= "bytes between the last local entry and the central directory"; diff --git a/packages/skill-tree/test/path-fuzz.test.ts b/packages/skill-tree/test/path-fuzz.test.ts index a937304..c2f4f7d 100644 --- a/packages/skill-tree/test/path-fuzz.test.ts +++ b/packages/skill-tree/test/path-fuzz.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vitest"; +import { foldKey } from "../src/collision"; import { decodeName } from "../src/entry-collector"; import { buildTree, frontmatterExposure, validatePath } from "../src/index"; import { errorCodeOf } from "./vector-helpers"; @@ -44,6 +45,19 @@ describe("path validation never throws", () => { }); }); +describe("collision keys", () => { + it("fold each segment independently, so directory keys are prefixes of file keys", () => { + const next = rng(0xf01d); + const marks = ["́", "̅", "̖", "̈́", "͏"]; + const tokens = [...ALPHABET, ...marks, ...marks, ...marks]; + for (let i = 0; i < 5_000; i++) { + const path = Array.from({ length: 1 + Math.floor(next() * 40) }, () => tokens[Math.floor(next() * tokens.length)]).join(""); + expect(foldKey(path).split("/"), JSON.stringify(path)).toEqual(path.split("/").map(foldKey)); + } + expect(foldKey("a" + "̅".repeat(20) + "/" + "̅".repeat(20))).toBe(foldKey("a" + "̅".repeat(20)) + "/" + foldKey("̅".repeat(20))); + }); +}); + describe("frontmatter exposure never throws", () => { it.each([ ["", "AUTO", false], diff --git a/packages/skill-tree/test/provenance.test.ts b/packages/skill-tree/test/provenance.test.ts index c38bb59..5ea2b7f 100644 --- a/packages/skill-tree/test/provenance.test.ts +++ b/packages/skill-tree/test/provenance.test.ts @@ -6,7 +6,8 @@ import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; -import { UNICODE_VERSION, caseFoldEntries, combiningClass, isAssigned, isFormat, nfc, nfd } from "../src/unicode-15"; +import { validatePath } from "../src/path-rules"; +import { UNICODE_VERSION, caseFoldEntries, combiningClass, isAssigned, isFormat, isNfc, nfc, nfd } from "../src/unicode-15"; import { fixtureBytes, sha256 } from "./vector-helpers"; const PINS: Record = { @@ -14,7 +15,7 @@ const PINS: Record = { "vectors/identity-v1-vectors.json": "1ab9e013c229d78871abd60e3cd3bf26fcfd0e6067d98dcdd79b4f6bcc1daefb", "ucd/CaseFolding-15.0.0.txt": "cdd49e55eae3bbf1f0a3f6580c974a0263cb86a6a08daa10fbf705b4808a56f7", }; -const GO_TABLES_SHA256 = "baa335155dcbaf0cfe8f40fcc0a98232c4134e821a08c3f198f829a51d911ad5"; +const GO_TABLES_SHA256 = "0d0155948ceea434fa241b59937db1a41689fa2ccb8231d35d96a2c56f57b52b"; const MAX_CP = 0x10ffff; interface GoTables { @@ -28,6 +29,13 @@ interface GoTables { const goBytes = readFileSync(fileURLToPath(new URL("../scripts/unicode-15.0.0-go.json", import.meta.url))); const go = JSON.parse(goBytes.toString("utf8")) as GoTables; +const STREAM_SAFE_VECTORS_SHA256 = "de0331152c6f83ed05e2c5013c9d383426731d2c7423c1127f15c86f395ed378"; +const streamSafeBytes = readFileSync(fileURLToPath(new URL("../scripts/stream-safe-15.0.0-go-vectors.json", import.meta.url))); + +interface StreamSafeVectors { + alphabet: number[]; + cases: Array<{ in: string; isNfc: boolean; nfd: string; nfc: string }>; +} function rangeSet(ranges: Array<[number, number]>): Uint8Array { const set = new Uint8Array(MAX_CP + 1); @@ -90,6 +98,41 @@ describe("normalization agrees with the runtime on Unicode 15.0.0 characters", ( expect(checked).toBeGreaterThan(149_000); }); + it("inserts a CGJ into runs of more than 30 non-starters, like Go x/text norm", () => { + const mark = "̅"; + const cases: Array<[string, boolean]> = [ + ["a" + mark.repeat(30), true], + ["a" + mark.repeat(31), false], + [mark.repeat(30), true], + [mark.repeat(31), false], + ["á" + mark.repeat(29), true], // á carries one trailing non-starter + ["á" + mark.repeat(30), false], + ["a" + mark.repeat(29) + "̈́", false], // U+0344 adds two + ["a" + mark.repeat(30) + "͏" + mark.repeat(30), true], + ]; + for (const [s, want] of cases) expect(isNfc(s), `${s.length} code units`).toBe(want); + // Go: the CGJ goes before the overflowing mark, and the next run counts it. + expect(nfd("a" + "́".repeat(62))).toBe( + "a" + "́".repeat(30) + "͏" + "́".repeat(30) + "͏" + "́".repeat(2), + ); + expect(validatePath("x/a" + mark.repeat(31) + ".md")?.code).toBe("tree.non_nfc_path"); + expect(validatePath("x/a" + mark.repeat(30) + ".md")).toBeNull(); + }); + + it("matches the Go stream-safe vectors", () => { + expect(sha256(streamSafeBytes)).toBe(STREAM_SAFE_VECTORS_SHA256); + const vectors = JSON.parse(streamSafeBytes.toString("utf8")) as StreamSafeVectors; + expect(vectors.cases.length).toBe(800); + const short = (s: string) => sha256(s).slice(0, 16); + let normal = 0; + for (const v of vectors.cases) { + const s = String.fromCodePoint(...Array.from(v.in, (c) => vectors.alphabet[c.charCodeAt(0) - 65]!)); + expect([isNfc(s), short(nfd(s)), short(nfc(s))], v.in).toEqual([v.isNfc, v.nfd, v.nfc]); + if (v.isNfc) normal++; + } + expect(normal).toBeGreaterThan(100); + }); + it("composes, reorders and blocks sequences", () => { const samples = [ "é", "Ǻ", "ḍ̇", "q̣̇", "각", "각", diff --git a/packages/skill-tree/test/tar-reader.test.ts b/packages/skill-tree/test/tar-reader.test.ts index ae2826b..1f9b0a7 100644 --- a/packages/skill-tree/test/tar-reader.test.ts +++ b/packages/skill-tree/test/tar-reader.test.ts @@ -2,7 +2,8 @@ import { once } from "node:events"; import { createGzip, gzipSync } from "node:zlib"; import { describe, expect, it } from "vitest"; import { buildTree, readTarTree, readZipTree } from "../src/index"; -import { tarBytes, tarStream } from "./tar-writer"; +import { parsePax } from "../src/tar-header"; +import { concat, paxData, tarBytes, tarHeader, tarStream } from "./tar-writer"; import type { TarSpec } from "./tar-writer"; import { zipBytes } from "./zip-writer"; import { errorCodeOf, sha256 } from "./vector-helpers"; @@ -16,6 +17,35 @@ function file(name: string, data: Uint8Array | string = "x\n", mode = 0o644): Ta const skill = file("SKILL.md", SKILL); +const SPARSE_1_0 = { "GNU.sparse.major": "1", "GNU.sparse.minor": "0" }; + +/** A GNU 1.0 sparse data section: the map (decimal lines, padded to a block), then the data. */ +function sparse1x0Data(data: string, map = "0\n"): Uint8Array { + const block = new Uint8Array(Math.ceil(map.length / 512) * 512); + block.set(enc.encode(map)); + return concat([block, enc.encode(data)]); +} + +/** Overwrites header fields of a tar block and recomputes its checksum. */ +function patchHeader(block: Uint8Array, fields: Array<[number, string | number[]]>): Uint8Array { + const b = block.slice(); + for (const [at, value] of fields) b.set(typeof value === "string" ? enc.encode(value) : value, at); + b.fill(0x20, 148, 156); + const sum = b.reduce((n, x) => n + x, 0); + b.set(enc.encode(`${sum.toString(8).padStart(6, "0")}\0 `), 148); + return b; +} + +const pad = (size: number) => new Uint8Array((512 - (size % 512)) % 512); + +/** One entry as raw blocks: a (patched) header, its data and padding. */ +function rawEntry(name: string, typeflag: string, data: Uint8Array, fields: Array<[number, string | number[]]> = [], size = data.length): Uint8Array { + return concat([patchHeader(tarHeader(enc.encode(name), typeflag, 0o644, size), fields), data, pad(data.length)]); +} + +const END = new Uint8Array(1024); +const skillBytes = () => tarBytes([skill], false); + /** Gzips a stream without holding its uncompressed bytes. */ async function gzipStream(source: AsyncIterable): Promise { const parts: Buffer[] = []; @@ -50,7 +80,7 @@ describe("tar reader rejects unsafe entries", () => { ["hard link", [{ name: enc.encode("hard"), typeflag: "1", mode: 0o644 }], "tree.unsupported_entry"], ["FIFO", [{ name: enc.encode("pipe"), typeflag: "6", mode: 0o644 }], "tree.unsupported_entry"], ["contiguous file", [{ ...file("big.bin"), typeflag: "7" }], "tree.unsupported_entry"], - ["sparse PAX file", [{ ...file("sparse.bin"), pax: { "GNU.sparse.major": "1", "GNU.sparse.minor": "0" } }], "tree.unsupported_entry"], + ["sparse PAX file", [{ ...file("sparse.bin", sparse1x0Data("x")), pax: SPARSE_1_0 }], "tree.unsupported_entry"], ["setuid file", [file("run.sh", "#!/bin/sh\n", 0o4755)], "tree.unsupported_entry"], ["group-writable file", [file("w.md", "x\n", 0o664)], "tree.unsupported_entry"], ] as const)("%s", async (_name, specs, code) => { @@ -151,3 +181,184 @@ describe("one tree, one digest", () => { expect(digests[0]).toMatch(/^sha256:[0-9a-f]{64}$/); }); }); + +describe("tar headers parse like Go archive/tar", () => { + const data = enc.encode("x\n"); + const expected = async () => (await readTarTree(await tarBytes([skill, file("refs/a.md")]))).digest; + const read = async (...parts: Uint8Array[]) => readTarTree(concat([await skillBytes(), ...parts, END])); + const code = (...parts: Uint8Array[]) => errorCodeOf(() => read(...parts)); + const ff = (n: number) => new Array(n).fill(0xff); + + it("cuts an octal field at its first NUL", async () => { + expect((await read(rawEntry("refs/a.md", "0", data, [[100, "644\0zzz\0"]]))).digest).toBe(await expected()); + }); + + it("accepts negative and wide base-256 ids and times", async () => { + const wide = [0x80, 0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff]; + expect((await read(rawEntry("refs/a.md", "0", data, [[108, ff(8)], [116, wide], [136, ff(12)]]))).digest).toBe(await expected()); + }); + + it("rejects numeric fields that do not parse, used or not", async () => { + expect(await code(rawEntry("refs/a.md", "0", data, [[108, "0000009\0"]]))).toBe("tree.read_failed"); + expect(await code(rawEntry("refs/a.md", "0", data, [[329, "zz\0"]]))).toBe("tree.read_failed"); + // A base-256 value beyond int64 overflows, as in Go. + expect(await code(rawEntry("refs/a.md", "0", data, [[136, [0x80, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]]))).toBe("tree.read_failed"); + }); + + it("rejects a negative size, on files and extension headers", async () => { + expect(await code(rawEntry("refs/a.md", "0", data, [[124, ff(12)]]))).toBe("tree.read_failed"); + expect(await code(rawEntry("PaxHeader", "x", new Uint8Array(0), [[124, ff(12)]]), rawEntry("refs/a.md", "0", data))).toBe("tree.read_failed"); + // Header-only types ignore their size. + expect(await code(rawEntry("refs/", "5", new Uint8Array(0), [[124, ff(12)]]), rawEntry("refs/a.md", "0", data))).toBeNull(); + }); + + it("never truncates a base-256 mode to 32 bits", async () => { + const mode = [0x80, 0, 0, 0x01, 0, 0, 0x01, 0xa4]; // 2^32 + 0o644 + expect(await code(rawEntry("refs/a.md", "0", data, [[100, mode]]))).toBe("tree.unsupported_entry"); + expect(await code(rawEntry("refs/a.md", "0", data, [[100, ff(8)]]))).toBe("tree.unsupported_entry"); + }); + + it("joins a USTAR prefix whatever the version field holds", async () => { + expect((await read(rawEntry("a.md", "0", data, [[263, [0, 0]], [345, "refs\0"]]))).digest).toBe(await expected()); + }); + + it("falls back to a USTAR prefix where a GNU header's times do not parse", async () => { + expect((await read(rawEntry("a.md", "0", data, [[257, "ustar \0"], [345, "refs\0"]]))).digest).toBe(await expected()); + }); + + it("accepts PAX record lengths with a sign or leading zeros", async () => { + for (const len of ["0020", "+020"]) { + const pax = rawEntry("PaxHeader", "x", enc.encode(`${len} path=refs/a.md\n`)); + expect((await read(pax, rawEntry("placeholder.md", "0", data))).digest, len).toBe(await expected()); + } + expect(await code(rawEntry("PaxHeader", "x", enc.encode("-20 path=refs/a.md\n")), rawEntry("a.md", "0", data))).toBe("tree.read_failed"); + }); + + it.each([ + [{ mtime: "1." }, null], + [{ mtime: "-1.5" }, null], + [{ mtime: ".5" }, "tree.read_failed"], + [{ mtime: "1.5x" }, "tree.read_failed"], + [{ uid: "-5" }, null], + [{ uid: "+5" }, null], + [{ uid: "9223372036854775808" }, "tree.read_failed"], + [{ size: "" }, null], + [{ size: "+2" }, null], + ] as const)("PAX values %j", async (pax, want) => { + expect(await tarCode([skill, { ...file("refs/a.md"), pax }])).toBe(want); + }); + + it("an empty GNU long name clears an earlier one", async () => { + const longName = (name: string) => rawEntry("././@LongLink", "L", enc.encode(`${name}\0`)); + expect((await read(longName("refs/long-name.md"), longName(""), rawEntry("refs/a.md", "0", data))).digest).toBe(await expected()); + }); + + it("keeps PAX records in a prototype-free object", () => { + const { records } = parsePax(paxData({ ["__proto__"]: "x", constructor: "y", path: "p" })); + expect(Object.getPrototypeOf(records)).toBeNull(); + expect(Object.keys(records).sort()).toEqual(["__proto__", "constructor", "path"]); + expect(records["__proto__"]).toBe("x"); + }); +}); + +describe("tar reader bounds bytes that no file limit counts", () => { + const limits = { maxEntries: 10, maxFiles: 10, maxFileSize: 1 << 20, maxTreeSize: 2 << 20 }; + + async function readCounted(source: AsyncIterable): Promise<{ code: string | null; pulled: number }> { + let pulled = 0; + const counted = (async function* () { + for await (const chunk of source) { + pulled += chunk.length; + yield chunk; + } + })(); + const code = await errorCodeOf(() => readTarTree(counted, { limits })); + return { code, pulled }; + } + + it("stops in the data of a non-regular entry", async () => { + const got = await readCounted(tarStream([skill, { name: enc.encode("big.bin"), typeflag: "7", mode: 0o644, fill: { size: 64 << 20, byte: 0 } }])); + expect(got.code).toBe("tree.limit_exceeded"); + expect(got.pulled).toBeLessThan(4 << 20); + }); + + it("stops in a chain of PAX headers", async () => { + const chain = (async function* () { + yield* tarStream([skill], false); + const header = rawEntry("PaxHeader", "x", paxData({ comment: "c".repeat(60_000) })); + for (let i = 0; i < 100_000; i++) yield header; + })(); + const got = await readCounted(chain); + expect(got.code).toBe("tree.limit_exceeded"); + expect(got.pulled).toBeLessThan(4 << 20); + }); +}); + +describe("tar reader handles GNU sparse files like Go", () => { + const sparse = (pax: Record, data: Uint8Array | string, name = "data.bin"): TarSpec => ({ + name: enc.encode(name), + typeflag: "0", + mode: 0o644, + data: typeof data === "string" ? enc.encode(data) : data, + pax, + }); + const v01 = (numblocks: string, map: string) => ({ "GNU.sparse.major": "0", "GNU.sparse.minor": "1", "GNU.sparse.numblocks": numblocks, "GNU.sparse.map": map }); + + it.each([ + ["1.0 with an empty map", sparse(SPARSE_1_0, sparse1x0Data("x")), "tree.unsupported_entry"], + ["1.0 with a map entry", sparse(SPARSE_1_0, sparse1x0Data("x", "1\n0\n1\n")), "tree.unsupported_entry"], + ["0.1 map", sparse(v01("1", "0,1"), "xy"), "tree.unsupported_entry"], + ["0.0 offset and numbytes records", sparse({ "GNU.sparse.numblocks": "1", "GNU.sparse.offset": "0", "GNU.sparse.numbytes": "1" }, "x"), "tree.unsupported_entry"], + ["unknown version: not sparse, records still unsupported", sparse({ "GNU.sparse.major": "2", "GNU.sparse.minor": "0" }, "x"), "tree.unsupported_entry"], + ["size record wins over realsize", sparse({ ...SPARSE_1_0, "GNU.sparse.size": "1", "GNU.sparse.realsize": String(64 << 20) }, sparse1x0Data("x")), "tree.unsupported_entry"], + ["0.1 map with too few fields", sparse(v01("2", "0,1"), "xy"), "tree.read_failed"], + ["0.1 entry beyond the logical size", sparse(v01("1", "0,5"), "xy"), "tree.read_failed"], + ["0.1 overlapping entries", sparse(v01("2", "0,2,1,1"), "xyz"), "tree.read_failed"], + ["0.1 negative offset", sparse(v01("1", "-1,1"), "xy"), "tree.read_failed"], + ["0.1 missing entry count", sparse({ "GNU.sparse.major": "0", "GNU.sparse.minor": "1", "GNU.sparse.map": "0,1" }, "xy"), "tree.read_failed"], + ["numbytes before offset", sparse({ "GNU.sparse.numblocks": "1", "GNU.sparse.numbytes": "1", "GNU.sparse.offset": "0" }, "x"), "tree.read_failed"], + ["1.0 map that is not decimal", sparse(SPARSE_1_0, sparse1x0Data("x", "1\nzero\n1\n")), "tree.read_failed"], + ["1.0 map past the data section", sparse(SPARSE_1_0, "1\n"), "tree.read_failed"], + ["invalid GNU.sparse.size", sparse({ ...SPARSE_1_0, "GNU.sparse.size": "x" }, sparse1x0Data("x")), "tree.read_failed"], + ["negative GNU.sparse.size", sparse({ ...SPARSE_1_0, "GNU.sparse.size": "-1" }, sparse1x0Data("x")), "tree.read_failed"], + ] as const)("%s", async (_name, spec, want) => { + expect(await tarCode([skill, spec])).toBe(want); + }); + + it("applies GNU.sparse.name before the noise rules", async () => { + const got = await readTarTree(tarStream([skill, sparse({ ...SPARSE_1_0, "GNU.sparse.name": ".DS_Store" }, sparse1x0Data("x"))])); + expect(got.digest).toBe((await readTarTree(tarStream([skill]))).digest); + }); + + it("counts the logical size toward the limits", async () => { + expect(await tarCode([skill, sparse({ ...SPARSE_1_0, "GNU.sparse.realsize": String(64 << 20) }, sparse1x0Data("x"))])).toBe("tree.limit_exceeded"); + }); + + describe("old GNU sparse headers", () => { + const data = enc.encode("xy"); + const gnu: Array<[number, string | number[]]> = [[257, "ustar \0"], [483, "00000000002\0"]]; + const code = (...parts: Uint8Array[]) => errorCodeOf(async () => readTarTree(concat([await skillBytes(), ...parts, END]))); + + it("are rejected outside the GNU format", async () => { + expect(await code(rawEntry("data.bin", "S", data))).toBe("tree.read_failed"); + }); + + it("are unsupported with a valid map", async () => { + expect(await code(rawEntry("data.bin", "S", data, [...gnu, [386, "00000000000\0"], [398, "00000000001\0"]]))).toBe("tree.unsupported_entry"); + }); + + it("fail with a map beyond the real size", async () => { + expect(await code(rawEntry("data.bin", "S", data, [...gnu, [386, "00000000000\0"], [398, "00000000005\0"]]))).toBe("tree.read_failed"); + }); + + it("read extension blocks before the data", async () => { + const ext = new Uint8Array(512); + ext.set(enc.encode("00000000001\0"), 0); + ext.set(enc.encode("00000000001\0"), 12); + const header = patchHeader(tarHeader(enc.encode("data.bin"), "S", 0o644, data.length), [...gnu, [482, [1]]]); + expect(await code(concat([header, ext, data, pad(data.length)]), rawEntry("refs/a.md", "0", enc.encode("x\n")))).toBe("tree.unsupported_entry"); + ext.set(enc.encode("00000000009\0"), 12); + expect(await code(concat([header, ext, data, pad(data.length)]))).toBe("tree.read_failed"); + }); + }); +}); diff --git a/packages/skill-tree/test/tree-rules.test.ts b/packages/skill-tree/test/tree-rules.test.ts new file mode 100644 index 0000000..7d52d50 --- /dev/null +++ b/packages/skill-tree/test/tree-rules.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from "vitest"; +import { LIMITS, buildTree, checkLimits, headerMode } from "../src/tree"; +import type { TreeEntry } from "../src/tree"; +import { errorCodeOf } from "./vector-helpers"; + +describe("headerMode", () => { + it.each([ + [0o100644, "100644"], + [0o644, "100644"], + [0o100755, "100755"], + [0o170644, "100644"], // type bits are cleared, as Go's &^ 0o170000 + ])("maps %o to a mode class", (mode, want) => { + expect(headerMode(mode)).toBe(want); + }); + + it.each([ + [2 ** 32 + 0o644, "040000000644"], + [2 ** 32 + 0o100755, "040000100755"], + [0o7777777 + 1, "010000000"], + [-1, "0-1"], + [-(2 ** 32) + 0o644, "0-37777777134"], + [1.5, "01.4"], + [Number.MAX_SAFE_INTEGER + 1, `0${(2 ** 53).toString(8)}`], + [NaN, "0NaN"], + [Infinity, "0Infinity"], + ])("rejects %s without truncating it", (mode, want) => { + expect(headerMode(mode)).toBe(want); + }); +}); + +describe("checkLimits", () => { + const file = (size: number): TreeEntry => ({ path: "a.md", mode: "100644", size, sha256: "0".repeat(64) }); + + it.each([NaN, 1.5, Infinity, 2 ** 53])("rejects size %s as tree.limit_exceeded", (size) => { + expect(checkLimits([file(size)], 1, LIMITS)?.code).toBe("tree.limit_exceeded"); + }); + + it("lets validation reject a negative size", async () => { + expect(checkLimits([file(-1)], 1, LIMITS)).toBeNull(); + expect(await errorCodeOf(() => buildTree([file(-1)]))).toBe("tree.unsupported_entry"); + }); +}); diff --git a/packages/skill-tree/test/tree-vectors.test.ts b/packages/skill-tree/test/tree-vectors.test.ts index fd8ceef..a3a17a1 100644 --- a/packages/skill-tree/test/tree-vectors.test.ts +++ b/packages/skill-tree/test/tree-vectors.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { SkillTreeError, buildTree, readTarTree, readZipTree, serializeTree } from "../src/index"; import type { TreeManifest } from "../src/index"; -import { tarStream } from "./tar-writer"; +import { concat, tarStream } from "./tar-writer"; import type { TarSpec } from "./tar-writer"; import { zipBytes } from "./zip-writer"; import type { ZipSpec } from "./zip-writer"; @@ -11,6 +11,11 @@ import type { TreeVector, VectorFile } from "./vector-helpers"; const doc = loadTreeVectors(); const vectors = doc.vectors; +/** Vectors each archive harness presents today; lower them only with a reason. */ +const MIN_TAR_VECTORS = 133; +const MIN_ZIP_VECTORS = 113; +const ran = { tar: 0, zip: 0 }; + const VECTOR_KEYS = new Set(["id", "description", "files", "synthesize", "archiveOnly", "expect"]); const FILE_KEYS = new Set(["path", "rawPathBase64", "mode", "headerMode", "type", "paxRecords", "content", "contentBase64"]); const SYNTH_KEYS = new Set(["pathPattern", "count", "size", "fill", "mode", "type"]); @@ -42,6 +47,15 @@ const TAR_TYPES: Record = { }; const HEADER_ONLY = new Set(["1", "2", "3", "4", "5", "6"]); +/** An empty GNU 1.0 sparse map ("0\n" in one block), which Go reads from the start of the data section. */ +const EMPTY_SPARSE_1_0_MAP = (() => { + const block = new Uint8Array(512); + block.set(new TextEncoder().encode("0\n")); + return block; +})(); + +const isSparse1x0 = (pax?: Record) => pax?.["GNU.sparse.major"] === "1" && pax["GNU.sparse.minor"] === "0"; + /** The vector as a tar stream, or undefined when tar cannot present it (walker-only types, NUL names). */ function tarSpecs(v: TreeVector): TarSpec[] | undefined { const specs: TarSpec[] = []; @@ -51,7 +65,9 @@ function tarSpecs(v: TreeVector): TarSpec[] | undefined { if (typeflag === undefined || name.includes(0) || (typeflag !== "g" && f.paxRecords?.path !== undefined)) return undefined; const pax = f.paxRecords; // Header-only types (links, devices, directories, FIFOs) carry no data, as Go's tar writer enforces. - const data = typeflag === "g" || HEADER_ONLY.has(typeflag) ? undefined : fileBytes(f); + let data = typeflag === "g" || HEADER_ONLY.has(typeflag) ? undefined : fileBytes(f); + // A GNU 1.0 sparse file's data section starts with its map; without one Go's reader fails. + if (data !== undefined && typeflag !== "g" && isSparse1x0(pax)) data = concat([EMPTY_SPARSE_1_0_MAP, data]); specs.push({ name, typeflag, mode: archiveMode(f), data, ...(pax ? { pax } : {}) } as TarSpec); } for (const s of v.synthesize ?? []) { @@ -117,11 +133,20 @@ describe("skill-tree-v1 vectors (vendored unedited from AgentKit)", () => { const specs = tarSpecs(v); if (specs === undefined) return; expectOutcome(await outcome(() => readTarTree(tarStream(specs))), v); + ran.tar++; }, 120_000); it.each(vectors.map((v) => [v.id, v] as const))("zip reader agrees: %s", async (_id, v) => { const specs = zipSpecs(v); if (specs === undefined) return; expectOutcome(await outcome(() => readZipTree(zipBytes(specs))), v); + ran.zip++; }, 60_000); + + // Tests in a file run in order, so this sees every reader run above; it + // stops a harness change from silently skipping most vectors. + it("each archive reader ran most vectors", () => { + expect(ran.tar).toBeGreaterThanOrEqual(MIN_TAR_VECTORS); + expect(ran.zip).toBeGreaterThanOrEqual(MIN_ZIP_VECTORS); + }); }); diff --git a/packages/skill-tree/test/zip-reader.test.ts b/packages/skill-tree/test/zip-reader.test.ts index d626f60..21a4d07 100644 --- a/packages/skill-tree/test/zip-reader.test.ts +++ b/packages/skill-tree/test/zip-reader.test.ts @@ -63,6 +63,25 @@ describe("zip reader rejects unsafe or unsupported entries", () => { expect(await errorCodeOf(() => readZipTree(bytes))).toBe("tree.read_failed"); }); + it("never inflates an encrypted deflate entry", async () => { + const bytes = zipBytes([skill, entry("a.md", "z".repeat(4096), { method: 8, flags: 0x1 })]); + const local = Buffer.from(bytes).indexOf("a.md") + 4; + bytes.fill(0xff, local, local + 6); // ciphertext is not a deflate stream + expect(await errorCodeOf(() => readZipTree(bytes))).toBe("tree.unsupported_entry"); + }); + + it("counts unsupported entries toward no file limit", async () => { + const files = Array.from({ length: 4095 }, (_, n) => entry(`f/${n}.md`)); + expect(await zipCode([skill, ...files, entry("link", "/etc", { unixMode: 0o120777 })])).toBe("tree.unsupported_entry"); + expect(await zipCode([skill, ...files, entry("extra.md")])).toBe("tree.limit_exceeded"); + }); + + it("does not count a faulted entry's data toward the byte limit", async () => { + const limits = { maxEntries: 10, maxFiles: 10, maxFileSize: 1024, maxTreeSize: 4096 }; + const bytes = zipBytes([skill, entry("big.bin", "0".repeat(1 << 20), { method: 8, centralCrc: 0x12345678 })]); + expect(await errorCodeOf(() => readZipTree(bytes, { limits }))).toBe("tree.unsupported_entry"); + }); + it("rejects deflate data that is corrupt", async () => { const bytes = zipBytes([skill, entry("a.md", "z".repeat(4096), { method: 8 })]); const local = Buffer.from(bytes).indexOf("a.md") + 4; From dd28390dedb3ab3a32e907bed2f9c092bfd23f4b Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 13 Oct 2026 11:04:04 +0700 Subject: [PATCH 4/5] fix(skill-tree): normalize tar type NUL and scope the ingest overhead guard Rewrite type NUL from the merged name before sparse handling, as Go Reader.Next does, and use that type for the data length, the sparse header-only check and the entry kind. Check the raw header size for negativity before a PAX size overrides it. The tar byte budget now counts only bytes that are not hashed file content, at maxFiles x 64 KiB, and its detail names the ingest overhead guard. Document the guard and the nodejs_compat requirement. --- packages/skill-tree/README.md | 30 +++++++++++ packages/skill-tree/src/byte-source.ts | 22 ++++++-- packages/skill-tree/src/tar-reader.ts | 35 +++++++----- packages/skill-tree/src/tar-sparse.ts | 4 +- packages/skill-tree/test/tar-reader.test.ts | 59 ++++++++++++++++++--- 5 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 packages/skill-tree/README.md diff --git a/packages/skill-tree/README.md b/packages/skill-tree/README.md new file mode 100644 index 0000000..06276b3 --- /dev/null +++ b/packages/skill-tree/README.md @@ -0,0 +1,30 @@ +# @skillx/skill-tree + +TypeScript port of the AgentKit `agentkit.skill-tree/v1` digest. It reads a tar, +tar.gz or zip archive (or presented entries) into a validated tree manifest +and its digest. Go parity is pinned by the vendored conformance vectors under +`fixtures/`. + +## Runtime requirements + +- Node.js 21.2 or later (`DecompressionStream("deflate-raw")`). +- Cloudflare Workers: enable the `nodejs_compat` compatibility flag. The + package imports `node:crypto` (`createHash`) for SHA-256. + +## Ingest overhead guard (tar) + +The tar reader caps the bytes it reads beyond hashed regular-file content at +`maxFiles × 64 KiB` (256 MiB at the default limits). That overhead covers +headers, PAX `x`/`g` and GNU `L`/`K` records, sparse maps, padding and the data +of non-regular entries. Regular-file content is bounded by the tree limits +(`maxFileSize`, `maxTreeSize`, `maxFiles`) as before. + +- It only rejects (`tree.limit_exceeded`, detail naming the ingest overhead + guard). It never changes a digest. +- It is a SkillX resource guard outside the Go parity claim. Go + `archive/tar` has no such bound, and AgentKit has no tar reader; the + contract governs `Build`. +- Known divergence: a non-regular entry (for example type `7` or a sparse + file) whose data exceeds the guard fails with `tree.limit_exceeded`, where + Go `Reader.Next` plus `Build` would read it fully and report + `tree.unsupported_entry`. diff --git a/packages/skill-tree/src/byte-source.ts b/packages/skill-tree/src/byte-source.ts index 893444a..f24d0f3 100644 --- a/packages/skill-tree/src/byte-source.ts +++ b/packages/skill-tree/src/byte-source.ts @@ -100,7 +100,11 @@ export class StreamReader { private ended = false; private consumed = 0; - /** `budget` caps the total bytes taken from the stream: headers, skipped data and file content alike. */ + /** + * `budget` is the ingest overhead guard: it caps the bytes taken from the + * stream that are not hashed file content (headers, extension records, + * skipped data). Hashed content is bounded by the tree limits instead. + */ constructor(source: AsyncIterable, private readonly budget = Infinity) { this.it = source[Symbol.asyncIterator](); } @@ -108,7 +112,11 @@ export class StreamReader { private spend(n: number): void { this.consumed += n; if (this.consumed > this.budget) { - throw new SkillTreeError(ERROR_CODES.limitExceeded, "", `archive data exceeds ${this.budget} bytes`); + throw new SkillTreeError( + ERROR_CODES.limitExceeded, + "", + `archive overhead exceeds the ${this.budget}-byte ingest overhead guard`, + ); } } @@ -149,15 +157,19 @@ export class StreamReader { return out; } - /** Yields exactly `n` bytes in chunks; throws `tree.read_failed` if the stream ends first. */ - async *chunks(n: number): AsyncGenerator { + /** + * Yields exactly `n` bytes in chunks; throws `tree.read_failed` if the + * stream ends first. `overhead` false exempts content the caller hashes + * and counts against the tree limits from the overhead guard. + */ + async *chunks(n: number, overhead = true): AsyncGenerator { let left = n; while (left > 0) { if (this.offset >= this.chunk.length && !(await this.nextChunk())) { throw readFailed(`stream ends ${left} bytes before the end of an entry`); } const take = Math.min(left, this.chunk.length - this.offset); - this.spend(take); + if (overhead) this.spend(take); const piece = this.chunk.subarray(this.offset, this.offset + take); this.offset += take; left -= take; diff --git a/packages/skill-tree/src/tar-reader.ts b/packages/skill-tree/src/tar-reader.ts index 551ee72..048ebc5 100644 --- a/packages/skill-tree/src/tar-reader.ts +++ b/packages/skill-tree/src/tar-reader.ts @@ -91,16 +91,19 @@ function dataLength(typeflag: string, size: number): number { return n; } -/** Bytes an archive may take beyond its file content: headers, extension records and skipped data. */ -const ENTRY_OVERHEAD = 16 * 1024; +/** Overhead allowance per file (of `maxFiles`) for the ingest overhead guard. */ +const ENTRY_OVERHEAD = 64 * 1024; /** - * The total byte budget of one archive. Go archive/tar has no such limit; - * it bounds data that no file limit counts (non-regular entry data, PAX and - * GNU extension chains), so a stream cannot be read without end. + * The ingest overhead guard of one archive: the bytes it may take beyond + * hashed regular-file content (headers, PAX/GNU extension records, sparse + * maps, padding and the data of non-regular entries). Hashed content counts + * against the tree limits instead. This is a SkillX resource guard outside + * the Go parity claim (Go archive/tar has no such bound): it only ever + * rejects with `tree.limit_exceeded` and never changes a digest. */ -export function tarByteBudget(limits: TreeLimits): number { - return limits.maxTreeSize + limits.maxEntries * ENTRY_OVERHEAD; +export function tarOverheadBudget(limits: TreeLimits): number { + return limits.maxFiles * ENTRY_OVERHEAD; } async function readEntries(reader: StreamReader, collector: EntryCollector): Promise { @@ -142,15 +145,20 @@ async function readEntries(reader: StreamReader, collector: EntryCollector): Pro longName = undefined; continue; } + // Go checks the raw header size before any PAX record can override it. + dataLength(h.typeflag, h.size); const records = pax?.records ?? (Object.create(null) as Record); const size = mergePaxValues(records) ?? h.size; let rawName = longName ?? (records.path ? pax!.raw.get("path")! : h.name); - const physical = dataLength(h.typeflag, size); + // Go rewrites TypeRegA ('\0') from the merged name, before sparse handling: + // a directory when it ends in "/", a regular file otherwise. + const type = h.typeflag === "\0" ? (rawName[rawName.length - 1] === 0x2f ? "5" : "0") : h.typeflag; + const physical = dataLength(type, size); let logical = size; let consumed = 0; - if (h.typeflag === "S") await readOldGnuSparse(reader, h); + if (type === "S") await readOldGnuSparse(reader, h); else { - const sparse = await readPaxSparse(reader, h, pax, size, physical); + const sparse = await readPaxSparse(reader, type, pax, size, physical); if (sparse !== undefined) { rawName = sparse.name ?? rawName; logical = sparse.size; @@ -158,10 +166,11 @@ async function readEntries(reader: StreamReader, collector: EntryCollector): Pro } } const name = decodeName(rawName); - const kind = tarEntryKind(h.typeflag, name.path); + // The kind follows the effective type, never the sparse-overridden name. + const kind = tarEntryKind(type, name.path); const sparse = logical !== size || consumed > 0 || Object.keys(records).some((k) => k.startsWith("GNU.sparse.")); let hashed = { size: 0, sha256: "" }; - if (kind === "regular" && !sparse) hashed = await collector.hashFile(name.path, reader.chunks(physical)); + if (kind === "regular" && !sparse) hashed = await collector.hashFile(name.path, reader.chunks(physical, false)); else { // Sparse files are rejected later, but their logical size counts toward the limits first. if (kind === "regular") { @@ -187,7 +196,7 @@ export async function readTarTree(source: ByteSource, options: TarReadOptions = const collector = new EntryCollector(limits); let reader: StreamReader | undefined; try { - reader = new StreamReader(await gunzipIfNeeded(toAsyncIterable(source), options.compression ?? "auto"), tarByteBudget(limits)); + reader = new StreamReader(await gunzipIfNeeded(toAsyncIterable(source), options.compression ?? "auto"), tarOverheadBudget(limits)); await readEntries(reader, collector); } catch (err) { throw asTreeError(err); diff --git a/packages/skill-tree/src/tar-sparse.ts b/packages/skill-tree/src/tar-sparse.ts index 24ad96f..a4b9cff 100644 --- a/packages/skill-tree/src/tar-sparse.ts +++ b/packages/skill-tree/src/tar-sparse.ts @@ -116,7 +116,7 @@ export interface PaxSparse { */ export async function readPaxSparse( reader: StreamReader, - h: RawHeader, + typeflag: string, pax: PaxRecords | undefined, size: number, physical: number, @@ -133,7 +133,7 @@ export async function readPaxSparse( logical = n; } const { entries, consumed } = version === "1.0" ? await map1x0(reader, physical) : { entries: map0x1(records), consumed: 0 }; - if (isHeaderOnly(h.typeflag) || !validSparseEntries(entries, logical)) throw readFailed("invalid GNU sparse map"); + if (isHeaderOnly(typeflag) || !validSparseEntries(entries, logical)) throw readFailed("invalid GNU sparse map"); return { ...(nameText === "" ? {} : { name: pax?.raw.get("GNU.sparse.name") }), size: Number(logical), consumed }; } diff --git a/packages/skill-tree/test/tar-reader.test.ts b/packages/skill-tree/test/tar-reader.test.ts index 1f9b0a7..7852dd1 100644 --- a/packages/skill-tree/test/tar-reader.test.ts +++ b/packages/skill-tree/test/tar-reader.test.ts @@ -212,6 +212,13 @@ describe("tar headers parse like Go archive/tar", () => { expect(await code(rawEntry("refs/", "5", new Uint8Array(0), [[124, ff(12)]]), rawEntry("refs/a.md", "0", data))).toBeNull(); }); + it("checks the raw header size before a PAX size overrides it", async () => { + const paxSize = (size: string) => rawEntry("PaxHeader", "x", paxData({ size })); + expect(await code(paxSize("2"), rawEntry("refs/a.md", "0", data, [[124, ff(12)]]))).toBe("tree.read_failed"); + // A negative merged size is fine once type NUL becomes a header-only directory. + expect(await code(paxSize("-1"), rawEntry("refs/", "\0", new Uint8Array(0)), rawEntry("refs/a.md", "0", data))).toBeNull(); + }); + it("never truncates a base-256 mode to 32 bits", async () => { const mode = [0x80, 0, 0, 0x01, 0, 0, 0x01, 0xa4]; // 2^32 + 0o644 expect(await code(rawEntry("refs/a.md", "0", data, [[100, mode]]))).toBe("tree.unsupported_entry"); @@ -261,10 +268,31 @@ describe("tar headers parse like Go archive/tar", () => { }); }); -describe("tar reader bounds bytes that no file limit counts", () => { +describe("tar reader rewrites type NUL like Go archive/tar", () => { + const data = enc.encode("x\n"); + const v01 = { "GNU.sparse.major": "0", "GNU.sparse.minor": "1", "GNU.sparse.numblocks": "0", "GNU.sparse.map": "" }; + + it("reads no data for a type NUL directory, so the next block is a header", async () => { + const smuggled = rawEntry("evil.md", "0", data); + const manifest = await readTarTree(concat([await skillBytes(), rawEntry("refs/", "\0", smuggled), END])); + expect(manifest.files.map((f) => f.path)).toEqual(["SKILL.md", "evil.md"]); + expect(manifest.digest).toBe((await readTarTree(await tarBytes([skill, file("evil.md")]))).digest); + }); + + it("rejects a sparse map on a type NUL directory", async () => { + expect(await tarCode([skill, { name: enc.encode("refs/"), typeflag: "\0", mode: 0o755, pax: v01 }])).toBe("tree.read_failed"); + }); + + it("decides the type from the name before GNU.sparse.name replaces it", async () => { + const spec = { name: enc.encode("placeholder"), typeflag: "\0", mode: 0o644, data: enc.encode("x"), pax: { ...v01, path: "a", "GNU.sparse.name": "a/" } }; + expect(await tarCode([skill, spec])).toBe("tree.unsupported_entry"); + }); +}); + +describe("tar reader ingest overhead guard", () => { const limits = { maxEntries: 10, maxFiles: 10, maxFileSize: 1 << 20, maxTreeSize: 2 << 20 }; - async function readCounted(source: AsyncIterable): Promise<{ code: string | null; pulled: number }> { + async function readCounted(source: AsyncIterable): Promise<{ error: unknown; pulled: number }> { let pulled = 0; const counted = (async function* () { for await (const chunk of source) { @@ -272,13 +300,18 @@ describe("tar reader bounds bytes that no file limit counts", () => { yield chunk; } })(); - const code = await errorCodeOf(() => readTarTree(counted, { limits })); - return { code, pulled }; + const error = await readTarTree(counted, { limits }).then( + () => null, + (err: unknown) => err, + ); + return { error, pulled }; } + const overheadGuard = expect.objectContaining({ code: "tree.limit_exceeded", detail: expect.stringContaining("ingest overhead guard") }); + it("stops in the data of a non-regular entry", async () => { const got = await readCounted(tarStream([skill, { name: enc.encode("big.bin"), typeflag: "7", mode: 0o644, fill: { size: 64 << 20, byte: 0 } }])); - expect(got.code).toBe("tree.limit_exceeded"); + expect(got.error).toEqual(overheadGuard); expect(got.pulled).toBeLessThan(4 << 20); }); @@ -289,9 +322,23 @@ describe("tar reader bounds bytes that no file limit counts", () => { for (let i = 0; i < 100_000; i++) yield header; })(); const got = await readCounted(chain); - expect(got.code).toBe("tree.limit_exceeded"); + expect(got.error).toEqual(overheadGuard); expect(got.pulled).toBeLessThan(4 << 20); }); + + it("accepts a near-limit tree with a 40 KiB xattr on every file at the default limits", async () => { + // 4096 files (the file limit) totalling exactly 256 MiB (the tree limit), + // each behind a PAX header with a 40 KiB SCHILY.xattr record: about 170 MiB + // of overhead on top of the content. Specs share one buffer and stream lazily. + const content = new Uint8Array(64 << 10).fill(0x61); + const pax = { "SCHILY.xattr.user.blob": "x".repeat(40 << 10) }; + const specs: TarSpec[] = [{ ...file("SKILL.md", SKILL), pax }]; + specs.push({ ...file("f/0000.md", new Uint8Array((128 << 10) - SKILL.length).fill(0x62)), pax }); + for (let n = 1; n < 4095; n++) specs.push({ ...file(`f/${String(n).padStart(4, "0")}.md`, content), pax }); + const manifest = await readTarTree(tarStream(specs)); + expect(manifest.files).toHaveLength(4096); + expect(manifest.files.reduce((sum, f) => sum + f.size, 0)).toBe(256 << 20); + }, 300_000); }); describe("tar reader handles GNU sparse files like Go", () => { From 653b61c1846eaeb29267a31502922342d69909e2 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 13 Oct 2026 11:09:33 +0700 Subject: [PATCH 5/5] test(skill-tree): cover type NUL directories named by merged metadata Pin that a type NUL entry whose trailing slash comes from a PAX path or a GNU long name reads no data, and keep the vector helper from writing data for a type NUL directory. --- packages/skill-tree/test/tar-reader.test.ts | 9 +++++++++ packages/skill-tree/test/tree-vectors.test.ts | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/skill-tree/test/tar-reader.test.ts b/packages/skill-tree/test/tar-reader.test.ts index 7852dd1..45f4880 100644 --- a/packages/skill-tree/test/tar-reader.test.ts +++ b/packages/skill-tree/test/tar-reader.test.ts @@ -279,6 +279,15 @@ describe("tar reader rewrites type NUL like Go archive/tar", () => { expect(manifest.digest).toBe((await readTarTree(await tarBytes([skill, file("evil.md")]))).digest); }); + it.each([ + ["a PAX path", () => rawEntry("PaxHeader", "x", paxData({ path: "refs/" }))], + ["a GNU long name", () => rawEntry("././@LongLink", "L", enc.encode("refs/\0"))], + ] as const)("takes the directory slash from %s, not the raw header name", async (_name, meta) => { + const smuggled = rawEntry("evil.md", "0", data); + const manifest = await readTarTree(concat([await skillBytes(), meta(), rawEntry("refs", "\0", smuggled), END])); + expect(manifest.files.map((f) => f.path)).toEqual(["SKILL.md", "evil.md"]); + }); + it("rejects a sparse map on a type NUL directory", async () => { expect(await tarCode([skill, { name: enc.encode("refs/"), typeflag: "\0", mode: 0o755, pax: v01 }])).toBe("tree.read_failed"); }); diff --git a/packages/skill-tree/test/tree-vectors.test.ts b/packages/skill-tree/test/tree-vectors.test.ts index a3a17a1..c32e9ec 100644 --- a/packages/skill-tree/test/tree-vectors.test.ts +++ b/packages/skill-tree/test/tree-vectors.test.ts @@ -65,7 +65,9 @@ function tarSpecs(v: TreeVector): TarSpec[] | undefined { if (typeflag === undefined || name.includes(0) || (typeflag !== "g" && f.paxRecords?.path !== undefined)) return undefined; const pax = f.paxRecords; // Header-only types (links, devices, directories, FIFOs) carry no data, as Go's tar writer enforces. - let data = typeflag === "g" || HEADER_ONLY.has(typeflag) ? undefined : fileBytes(f); + // Type NUL with a name ending in "/" is a directory to Go's reader, so it is header-only too. + const nulDir = typeflag === "\0" && name[name.length - 1] === 0x2f; + let data = typeflag === "g" || nulDir || HEADER_ONLY.has(typeflag) ? undefined : fileBytes(f); // A GNU 1.0 sparse file's data section starts with its map; without one Go's reader fails. if (data !== undefined && typeflag !== "g" && isSparse1x0(pax)) data = concat([EMPTY_SPARSE_1_0_MAP, data]); specs.push({ name, typeflag, mode: archiveMode(f), data, ...(pax ? { pax } : {}) } as TarSpec);