@datumesh/verify 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +54 -2
- package/dist/cjs/ed25519.d.ts +2 -0
- package/dist/cjs/ed25519.js +82 -0
- package/dist/cjs/errors.d.ts +14 -0
- package/dist/cjs/errors.js +61 -0
- package/dist/cjs/hash.d.ts +6 -0
- package/dist/cjs/hash.js +27 -0
- package/dist/cjs/index.d.ts +27 -0
- package/dist/cjs/index.js +83 -0
- package/dist/cjs/jcs.d.ts +5 -0
- package/dist/cjs/jcs.js +25 -0
- package/dist/cjs/json.d.ts +29 -0
- package/dist/cjs/json.js +321 -0
- package/dist/cjs/keys.d.ts +73 -0
- package/dist/cjs/keys.js +257 -0
- package/dist/cjs/lexical.d.ts +59 -0
- package/dist/cjs/lexical.js +207 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/unicode-data.d.ts +8 -0
- package/dist/cjs/unicode-data.js +14 -0
- package/dist/cjs/unicode.d.ts +12 -0
- package/dist/cjs/unicode.js +192 -0
- package/dist/cjs/uri.d.ts +31 -0
- package/dist/cjs/uri.js +201 -0
- package/dist/cjs/utf8.d.ts +10 -0
- package/dist/cjs/utf8.js +101 -0
- package/dist/cjs/validate.d.ts +17 -0
- package/dist/cjs/validate.js +349 -0
- package/dist/cjs/verify.d.ts +38 -0
- package/dist/cjs/verify.js +192 -0
- package/dist/esm/ed25519.d.ts +2 -0
- package/dist/esm/ed25519.js +79 -0
- package/dist/esm/errors.d.ts +14 -0
- package/dist/esm/errors.js +56 -0
- package/dist/esm/hash.d.ts +6 -0
- package/dist/esm/hash.js +21 -0
- package/dist/esm/index.d.ts +27 -0
- package/dist/esm/index.js +63 -0
- package/dist/esm/jcs.d.ts +5 -0
- package/dist/esm/jcs.js +18 -0
- package/dist/esm/json.d.ts +29 -0
- package/dist/esm/json.js +309 -0
- package/dist/esm/keys.d.ts +73 -0
- package/dist/esm/keys.js +249 -0
- package/dist/esm/lexical.d.ts +59 -0
- package/dist/esm/lexical.js +187 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/unicode-data.d.ts +8 -0
- package/dist/esm/unicode-data.js +11 -0
- package/dist/esm/unicode.d.ts +12 -0
- package/dist/esm/unicode.js +184 -0
- package/dist/esm/uri.d.ts +31 -0
- package/dist/esm/uri.js +196 -0
- package/dist/esm/utf8.d.ts +10 -0
- package/dist/esm/utf8.js +96 -0
- package/dist/esm/validate.d.ts +17 -0
- package/dist/esm/validate.js +340 -0
- package/dist/esm/verify.d.ts +38 -0
- package/dist/esm/verify.js +189 -0
- package/package.json +54 -4
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// GENERATED by tools/gen-unicode.mjs from the Unicode 15.1.0 Character Database
|
|
2
|
+
// (UnicodeData.txt, DerivedNormalizationProps.txt) and spec/tools/unicode-15.1-assigned.txt.
|
|
3
|
+
// Do not edit by hand.
|
|
4
|
+
/** Assigned code point ranges (General_Category != Cn), inclusive pairs, ascending. */
|
|
5
|
+
export const 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, 12351, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12771, 12783, 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, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743, 917505, 917505, 917536, 917631, 917760, 917999, 983040, 1048573, 1048576, 1114109];
|
|
6
|
+
/** Non-zero canonical combining classes: "start:end:class" in hex/hex/decimal, ';'-separated. */
|
|
7
|
+
export const CCC = '300:314:230;315:315:232;316:319:220;31a:31a:232;31b:31b:216;31c:320:220;321:322:202;323:326:220;327:328:202;329:333:220;334:338:1;339:33c:220;33d:344:230;345:345:240;346:346:230;347:349:220;34a:34c:230;34d:34e:220;350:352:230;353:356:220;357:357:230;358:358:232;359:35a:220;35b:35b:230;35c:35c:233;35d:35e:234;35f:35f:233;360:361:234;362:362:233;363:36f:230;483:487:230;591:591:220;592:595:230;596:596:220;597:599:230;59a:59a:222;59b:59b:220;59c:5a1:230;5a2:5a7:220;5a8:5a9:230;5aa:5aa:220;5ab:5ac:230;5ad:5ad:222;5ae:5ae:228;5af:5af:230;5b0:5b0:10;5b1:5b1:11;5b2:5b2:12;5b3:5b3:13;5b4:5b4:14;5b5:5b5:15;5b6:5b6:16;5b7:5b7:17;5b8:5b8:18;5b9:5ba:19;5bb:5bb:20;5bc:5bc:21;5bd:5bd:22;5bf:5bf:23;5c1:5c1:24;5c2:5c2:25;5c4:5c4:230;5c5:5c5:220;5c7:5c7:18;610:617:230;618:618:30;619:619:31;61a:61a:32;64b:64b:27;64c:64c:28;64d:64d:29;64e:64e:30;64f:64f:31;650:650:32;651:651:33;652:652:34;653:654:230;655:656:220;657:65b:230;65c:65c:220;65d:65e:230;65f:65f:220;670:670:35;6d6:6dc:230;6df:6e2:230;6e3:6e3:220;6e4:6e4:230;6e7:6e8:230;6ea:6ea:220;6eb:6ec:230;6ed:6ed:220;711:711:36;730:730:230;731:731:220;732:733:230;734:734:220;735:736:230;737:739:220;73a:73a:230;73b:73c:220;73d:73d:230;73e:73e:220;73f:741:230;742:742:220;743:743:230;744:744:220;745:745:230;746:746:220;747:747:230;748:748:220;749:74a:230;7eb:7f1:230;7f2:7f2:220;7f3:7f3:230;7fd:7fd:220;816:819:230;81b:823:230;825:827:230;829:82d:230;859:85b:220;898:898:230;899:89b:220;89c:89f:230;8ca:8ce:230;8cf:8d3:220;8d4:8e1:230;8e3:8e3:220;8e4:8e5:230;8e6:8e6:220;8e7:8e8:230;8e9:8e9:220;8ea:8ec:230;8ed:8ef:220;8f0:8f0:27;8f1:8f1:28;8f2:8f2:29;8f3:8f5:230;8f6:8f6:220;8f7:8f8:230;8f9:8fa:220;8fb:8ff:230;93c:93c:7;94d:94d:9;951:951:230;952:952:220;953:954:230;9bc:9bc:7;9cd:9cd:9;9fe:9fe:230;a3c:a3c:7;a4d:a4d:9;abc:abc:7;acd:acd:9;b3c:b3c:7;b4d:b4d:9;bcd:bcd:9;c3c:c3c:7;c4d:c4d:9;c55:c55:84;c56:c56:91;cbc:cbc:7;ccd:ccd:9;d3b:d3c:9;d4d:d4d:9;dca:dca:9;e38:e39:103;e3a:e3a:9;e48:e4b:107;eb8:eb9:118;eba:eba:9;ec8:ecb:122;f18:f19:220;f35:f35:220;f37:f37:220;f39:f39:216;f71:f71:129;f72:f72:130;f74:f74:132;f7a:f7d:130;f80:f80:130;f82:f83:230;f84:f84:9;f86:f87:230;fc6:fc6:220;1037:1037:7;1039:103a:9;108d:108d:220;135d:135f:230;1714:1715:9;1734:1734:9;17d2:17d2:9;17dd:17dd:230;18a9:18a9:228;1939:1939:222;193a:193a:230;193b:193b:220;1a17:1a17:230;1a18:1a18:220;1a60:1a60:9;1a75:1a7c:230;1a7f:1a7f:220;1ab0:1ab4:230;1ab5:1aba:220;1abb:1abc:230;1abd:1abd:220;1abf:1ac0:220;1ac1:1ac2:230;1ac3:1ac4:220;1ac5:1ac9:230;1aca:1aca:220;1acb:1ace:230;1b34:1b34:7;1b44:1b44:9;1b6b:1b6b:230;1b6c:1b6c:220;1b6d:1b73:230;1baa:1bab:9;1be6:1be6:7;1bf2:1bf3:9;1c37:1c37:7;1cd0:1cd2:230;1cd4:1cd4:1;1cd5:1cd9:220;1cda:1cdb:230;1cdc:1cdf:220;1ce0:1ce0:230;1ce2:1ce8:1;1ced:1ced:220;1cf4:1cf4:230;1cf8:1cf9:230;1dc0:1dc1:230;1dc2:1dc2:220;1dc3:1dc9:230;1dca:1dca:220;1dcb:1dcc:230;1dcd:1dcd:234;1dce:1dce:214;1dcf:1dcf:220;1dd0:1dd0:202;1dd1:1df5:230;1df6:1df6:232;1df7:1df8:228;1df9:1df9:220;1dfa:1dfa:218;1dfb:1dfb:230;1dfc:1dfc:233;1dfd:1dfd:220;1dfe:1dfe:230;1dff:1dff:220;20d0:20d1:230;20d2:20d3:1;20d4:20d7:230;20d8:20da:1;20db:20dc:230;20e1:20e1:230;20e5:20e6:1;20e7:20e7:230;20e8:20e8:220;20e9:20e9:230;20ea:20eb:1;20ec:20ef:220;20f0:20f0:230;2cef:2cf1:230;2d7f:2d7f:9;2de0:2dff:230;302a:302a:218;302b:302b:228;302c:302c:232;302d:302d:222;302e:302f:224;3099:309a:8;a66f:a66f:230;a674:a67d:230;a69e:a69f:230;a6f0:a6f1:230;a806:a806:9;a82c:a82c:9;a8c4:a8c4:9;a8e0:a8f1:230;a92b:a92d:220;a953:a953:9;a9b3:a9b3:7;a9c0:a9c0:9;aab0:aab0:230;aab2:aab3:230;aab4:aab4:220;aab7:aab8:230;aabe:aabf:230;aac1:aac1:230;aaf6:aaf6:9;abed:abed:9;fb1e:fb1e:26;fe20:fe26:230;fe27:fe2d:220;fe2e:fe2f:230;101fd:101fd:220;102e0:102e0:220;10376:1037a:230;10a0d:10a0d:220;10a0f:10a0f:230;10a38:10a38:230;10a39:10a39:1;10a3a:10a3a:220;10a3f:10a3f:9;10ae5:10ae5:230;10ae6:10ae6:220;10d24:10d27:230;10eab:10eac:230;10efd:10eff:220;10f46:10f47:220;10f48:10f4a:230;10f4b:10f4b:220;10f4c:10f4c:230;10f4d:10f50:220;10f82:10f82:230;10f83:10f83:220;10f84:10f84:230;10f85:10f85:220;11046:11046:9;11070:11070:9;1107f:1107f:9;110b9:110b9:9;110ba:110ba:7;11100:11102:230;11133:11134:9;11173:11173:7;111c0:111c0:9;111ca:111ca:7;11235:11235:9;11236:11236:7;112e9:112e9:7;112ea:112ea:9;1133b:1133c:7;1134d:1134d:9;11366:1136c:230;11370:11374:230;11442:11442:9;11446:11446:7;1145e:1145e:230;114c2:114c2:9;114c3:114c3:7;115bf:115bf:9;115c0:115c0:7;1163f:1163f:9;116b6:116b6:9;116b7:116b7:7;1172b:1172b:9;11839:11839:9;1183a:1183a:7;1193d:1193e:9;11943:11943:7;119e0:119e0:9;11a34:11a34:9;11a47:11a47:9;11a99:11a99:9;11c3f:11c3f:9;11d42:11d42:7;11d44:11d45:9;11d97:11d97:9;11f41:11f42:9;16af0:16af4:1;16b30:16b36:230;16ff0:16ff1:6;1bc9e:1bc9e:1;1d165:1d166:216;1d167:1d169:1;1d16d:1d16d:226;1d16e:1d172:216;1d17b:1d182:220;1d185:1d189:230;1d18a:1d18b:220;1d1aa:1d1ad:230;1d242:1d244:230;1e000:1e006:230;1e008:1e018:230;1e01b:1e021:230;1e023:1e024:230;1e026:1e02a:230;1e08f:1e08f:230;1e130:1e136:230;1e2ae:1e2ae:230;1e2ec:1e2ef:230;1e4ec:1e4ed:232;1e4ee:1e4ee:220;1e4ef:1e4ef:230;1e8d0:1e8d6:220;1e944:1e949:230;1e94a:1e94a:7';
|
|
8
|
+
/** Full canonical decompositions (non-Hangul): "cp:cp.cp..." in hex, ';'-separated. */
|
|
9
|
+
export const DECOMP = 'c0:41.300;c1:41.301;c2:41.302;c3:41.303;c4:41.308;c5:41.30a;c7:43.327;c8:45.300;c9:45.301;ca:45.302;cb:45.308;cc:49.300;cd:49.301;ce:49.302;cf:49.308;d1:4e.303;d2:4f.300;d3:4f.301;d4:4f.302;d5:4f.303;d6:4f.308;d9:55.300;da:55.301;db:55.302;dc:55.308;dd:59.301;e0:61.300;e1:61.301;e2:61.302;e3:61.303;e4:61.308;e5:61.30a;e7:63.327;e8:65.300;e9:65.301;ea:65.302;eb:65.308;ec:69.300;ed:69.301;ee:69.302;ef:69.308;f1:6e.303;f2:6f.300;f3:6f.301;f4:6f.302;f5:6f.303;f6:6f.308;f9:75.300;fa:75.301;fb:75.302;fc:75.308;fd:79.301;ff:79.308;100:41.304;101:61.304;102:41.306;103:61.306;104:41.328;105:61.328;106:43.301;107:63.301;108:43.302;109:63.302;10a:43.307;10b:63.307;10c:43.30c;10d:63.30c;10e:44.30c;10f:64.30c;112:45.304;113:65.304;114:45.306;115:65.306;116:45.307;117:65.307;118:45.328;119:65.328;11a:45.30c;11b:65.30c;11c:47.302;11d:67.302;11e:47.306;11f:67.306;120:47.307;121:67.307;122:47.327;123:67.327;124:48.302;125:68.302;128:49.303;129:69.303;12a:49.304;12b:69.304;12c:49.306;12d:69.306;12e:49.328;12f:69.328;130:49.307;134:4a.302;135:6a.302;136:4b.327;137:6b.327;139:4c.301;13a:6c.301;13b:4c.327;13c:6c.327;13d:4c.30c;13e:6c.30c;143:4e.301;144:6e.301;145:4e.327;146:6e.327;147:4e.30c;148:6e.30c;14c:4f.304;14d:6f.304;14e:4f.306;14f:6f.306;150:4f.30b;151:6f.30b;154:52.301;155:72.301;156:52.327;157:72.327;158:52.30c;159:72.30c;15a:53.301;15b:73.301;15c:53.302;15d:73.302;15e:53.327;15f:73.327;160:53.30c;161:73.30c;162:54.327;163:74.327;164:54.30c;165:74.30c;168:55.303;169:75.303;16a:55.304;16b:75.304;16c:55.306;16d:75.306;16e:55.30a;16f:75.30a;170:55.30b;171:75.30b;172:55.328;173:75.328;174:57.302;175:77.302;176:59.302;177:79.302;178:59.308;179:5a.301;17a:7a.301;17b:5a.307;17c:7a.307;17d:5a.30c;17e:7a.30c;1a0:4f.31b;1a1:6f.31b;1af:55.31b;1b0:75.31b;1cd:41.30c;1ce:61.30c;1cf:49.30c;1d0:69.30c;1d1:4f.30c;1d2:6f.30c;1d3:55.30c;1d4:75.30c;1d5:55.308.304;1d6:75.308.304;1d7:55.308.301;1d8:75.308.301;1d9:55.308.30c;1da:75.308.30c;1db:55.308.300;1dc:75.308.300;1de:41.308.304;1df:61.308.304;1e0:41.307.304;1e1:61.307.304;1e2:c6.304;1e3:e6.304;1e6:47.30c;1e7:67.30c;1e8:4b.30c;1e9:6b.30c;1ea:4f.328;1eb:6f.328;1ec:4f.328.304;1ed:6f.328.304;1ee:1b7.30c;1ef:292.30c;1f0:6a.30c;1f4:47.301;1f5:67.301;1f8:4e.300;1f9:6e.300;1fa:41.30a.301;1fb:61.30a.301;1fc:c6.301;1fd:e6.301;1fe:d8.301;1ff:f8.301;200:41.30f;201:61.30f;202:41.311;203:61.311;204:45.30f;205:65.30f;206:45.311;207:65.311;208:49.30f;209:69.30f;20a:49.311;20b:69.311;20c:4f.30f;20d:6f.30f;20e:4f.311;20f:6f.311;210:52.30f;211:72.30f;212:52.311;213:72.311;214:55.30f;215:75.30f;216:55.311;217:75.311;218:53.326;219:73.326;21a:54.326;21b:74.326;21e:48.30c;21f:68.30c;226:41.307;227:61.307;228:45.327;229:65.327;22a:4f.308.304;22b:6f.308.304;22c:4f.303.304;22d:6f.303.304;22e:4f.307;22f:6f.307;230:4f.307.304;231:6f.307.304;232:59.304;233:79.304;340:300;341:301;343:313;344:308.301;374:2b9;37e:3b;385:a8.301;386:391.301;387:b7;388:395.301;389:397.301;38a:399.301;38c:39f.301;38e:3a5.301;38f:3a9.301;390:3b9.308.301;3aa:399.308;3ab:3a5.308;3ac:3b1.301;3ad:3b5.301;3ae:3b7.301;3af:3b9.301;3b0:3c5.308.301;3ca:3b9.308;3cb:3c5.308;3cc:3bf.301;3cd:3c5.301;3ce:3c9.301;3d3:3d2.301;3d4:3d2.308;400:415.300;401:415.308;403:413.301;407:406.308;40c:41a.301;40d:418.300;40e:423.306;419:418.306;439:438.306;450:435.300;451:435.308;453:433.301;457:456.308;45c:43a.301;45d:438.300;45e:443.306;476:474.30f;477:475.30f;4c1:416.306;4c2:436.306;4d0:410.306;4d1:430.306;4d2:410.308;4d3:430.308;4d6:415.306;4d7:435.306;4da:4d8.308;4db:4d9.308;4dc:416.308;4dd:436.308;4de:417.308;4df:437.308;4e2:418.304;4e3:438.304;4e4:418.308;4e5:438.308;4e6:41e.308;4e7:43e.308;4ea:4e8.308;4eb:4e9.308;4ec:42d.308;4ed:44d.308;4ee:423.304;4ef:443.304;4f0:423.308;4f1:443.308;4f2:423.30b;4f3:443.30b;4f4:427.308;4f5:447.308;4f8:42b.308;4f9:44b.308;622:627.653;623:627.654;624:648.654;625:627.655;626:64a.654;6c0:6d5.654;6c2:6c1.654;6d3:6d2.654;929:928.93c;931:930.93c;934:933.93c;958:915.93c;959:916.93c;95a:917.93c;95b:91c.93c;95c:921.93c;95d:922.93c;95e:92b.93c;95f:92f.93c;9cb:9c7.9be;9cc:9c7.9d7;9dc:9a1.9bc;9dd:9a2.9bc;9df:9af.9bc;a33:a32.a3c;a36:a38.a3c;a59:a16.a3c;a5a:a17.a3c;a5b:a1c.a3c;a5e:a2b.a3c;b48:b47.b56;b4b:b47.b3e;b4c:b47.b57;b5c:b21.b3c;b5d:b22.b3c;b94:b92.bd7;bca:bc6.bbe;bcb:bc7.bbe;bcc:bc6.bd7;c48:c46.c56;cc0:cbf.cd5;cc7:cc6.cd5;cc8:cc6.cd6;cca:cc6.cc2;ccb:cc6.cc2.cd5;d4a:d46.d3e;d4b:d47.d3e;d4c:d46.d57;dda:dd9.dca;ddc:dd9.dcf;ddd:dd9.dcf.dca;dde:dd9.ddf;f43:f42.fb7;f4d:f4c.fb7;f52:f51.fb7;f57:f56.fb7;f5c:f5b.fb7;f69:f40.fb5;f73:f71.f72;f75:f71.f74;f76:fb2.f80;f78:fb3.f80;f81:f71.f80;f93:f92.fb7;f9d:f9c.fb7;fa2:fa1.fb7;fa7:fa6.fb7;fac:fab.fb7;fb9:f90.fb5;1026:1025.102e;1b06:1b05.1b35;1b08:1b07.1b35;1b0a:1b09.1b35;1b0c:1b0b.1b35;1b0e:1b0d.1b35;1b12:1b11.1b35;1b3b:1b3a.1b35;1b3d:1b3c.1b35;1b40:1b3e.1b35;1b41:1b3f.1b35;1b43:1b42.1b35;1e00:41.325;1e01:61.325;1e02:42.307;1e03:62.307;1e04:42.323;1e05:62.323;1e06:42.331;1e07:62.331;1e08:43.327.301;1e09:63.327.301;1e0a:44.307;1e0b:64.307;1e0c:44.323;1e0d:64.323;1e0e:44.331;1e0f:64.331;1e10:44.327;1e11:64.327;1e12:44.32d;1e13:64.32d;1e14:45.304.300;1e15:65.304.300;1e16:45.304.301;1e17:65.304.301;1e18:45.32d;1e19:65.32d;1e1a:45.330;1e1b:65.330;1e1c:45.327.306;1e1d:65.327.306;1e1e:46.307;1e1f:66.307;1e20:47.304;1e21:67.304;1e22:48.307;1e23:68.307;1e24:48.323;1e25:68.323;1e26:48.308;1e27:68.308;1e28:48.327;1e29:68.327;1e2a:48.32e;1e2b:68.32e;1e2c:49.330;1e2d:69.330;1e2e:49.308.301;1e2f:69.308.301;1e30:4b.301;1e31:6b.301;1e32:4b.323;1e33:6b.323;1e34:4b.331;1e35:6b.331;1e36:4c.323;1e37:6c.323;1e38:4c.323.304;1e39:6c.323.304;1e3a:4c.331;1e3b:6c.331;1e3c:4c.32d;1e3d:6c.32d;1e3e:4d.301;1e3f:6d.301;1e40:4d.307;1e41:6d.307;1e42:4d.323;1e43:6d.323;1e44:4e.307;1e45:6e.307;1e46:4e.323;1e47:6e.323;1e48:4e.331;1e49:6e.331;1e4a:4e.32d;1e4b:6e.32d;1e4c:4f.303.301;1e4d:6f.303.301;1e4e:4f.303.308;1e4f:6f.303.308;1e50:4f.304.300;1e51:6f.304.300;1e52:4f.304.301;1e53:6f.304.301;1e54:50.301;1e55:70.301;1e56:50.307;1e57:70.307;1e58:52.307;1e59:72.307;1e5a:52.323;1e5b:72.323;1e5c:52.323.304;1e5d:72.323.304;1e5e:52.331;1e5f:72.331;1e60:53.307;1e61:73.307;1e62:53.323;1e63:73.323;1e64:53.301.307;1e65:73.301.307;1e66:53.30c.307;1e67:73.30c.307;1e68:53.323.307;1e69:73.323.307;1e6a:54.307;1e6b:74.307;1e6c:54.323;1e6d:74.323;1e6e:54.331;1e6f:74.331;1e70:54.32d;1e71:74.32d;1e72:55.324;1e73:75.324;1e74:55.330;1e75:75.330;1e76:55.32d;1e77:75.32d;1e78:55.303.301;1e79:75.303.301;1e7a:55.304.308;1e7b:75.304.308;1e7c:56.303;1e7d:76.303;1e7e:56.323;1e7f:76.323;1e80:57.300;1e81:77.300;1e82:57.301;1e83:77.301;1e84:57.308;1e85:77.308;1e86:57.307;1e87:77.307;1e88:57.323;1e89:77.323;1e8a:58.307;1e8b:78.307;1e8c:58.308;1e8d:78.308;1e8e:59.307;1e8f:79.307;1e90:5a.302;1e91:7a.302;1e92:5a.323;1e93:7a.323;1e94:5a.331;1e95:7a.331;1e96:68.331;1e97:74.308;1e98:77.30a;1e99:79.30a;1e9b:17f.307;1ea0:41.323;1ea1:61.323;1ea2:41.309;1ea3:61.309;1ea4:41.302.301;1ea5:61.302.301;1ea6:41.302.300;1ea7:61.302.300;1ea8:41.302.309;1ea9:61.302.309;1eaa:41.302.303;1eab:61.302.303;1eac:41.323.302;1ead:61.323.302;1eae:41.306.301;1eaf:61.306.301;1eb0:41.306.300;1eb1:61.306.300;1eb2:41.306.309;1eb3:61.306.309;1eb4:41.306.303;1eb5:61.306.303;1eb6:41.323.306;1eb7:61.323.306;1eb8:45.323;1eb9:65.323;1eba:45.309;1ebb:65.309;1ebc:45.303;1ebd:65.303;1ebe:45.302.301;1ebf:65.302.301;1ec0:45.302.300;1ec1:65.302.300;1ec2:45.302.309;1ec3:65.302.309;1ec4:45.302.303;1ec5:65.302.303;1ec6:45.323.302;1ec7:65.323.302;1ec8:49.309;1ec9:69.309;1eca:49.323;1ecb:69.323;1ecc:4f.323;1ecd:6f.323;1ece:4f.309;1ecf:6f.309;1ed0:4f.302.301;1ed1:6f.302.301;1ed2:4f.302.300;1ed3:6f.302.300;1ed4:4f.302.309;1ed5:6f.302.309;1ed6:4f.302.303;1ed7:6f.302.303;1ed8:4f.323.302;1ed9:6f.323.302;1eda:4f.31b.301;1edb:6f.31b.301;1edc:4f.31b.300;1edd:6f.31b.300;1ede:4f.31b.309;1edf:6f.31b.309;1ee0:4f.31b.303;1ee1:6f.31b.303;1ee2:4f.31b.323;1ee3:6f.31b.323;1ee4:55.323;1ee5:75.323;1ee6:55.309;1ee7:75.309;1ee8:55.31b.301;1ee9:75.31b.301;1eea:55.31b.300;1eeb:75.31b.300;1eec:55.31b.309;1eed:75.31b.309;1eee:55.31b.303;1eef:75.31b.303;1ef0:55.31b.323;1ef1:75.31b.323;1ef2:59.300;1ef3:79.300;1ef4:59.323;1ef5:79.323;1ef6:59.309;1ef7:79.309;1ef8:59.303;1ef9:79.303;1f00:3b1.313;1f01:3b1.314;1f02:3b1.313.300;1f03:3b1.314.300;1f04:3b1.313.301;1f05:3b1.314.301;1f06:3b1.313.342;1f07:3b1.314.342;1f08:391.313;1f09:391.314;1f0a:391.313.300;1f0b:391.314.300;1f0c:391.313.301;1f0d:391.314.301;1f0e:391.313.342;1f0f:391.314.342;1f10:3b5.313;1f11:3b5.314;1f12:3b5.313.300;1f13:3b5.314.300;1f14:3b5.313.301;1f15:3b5.314.301;1f18:395.313;1f19:395.314;1f1a:395.313.300;1f1b:395.314.300;1f1c:395.313.301;1f1d:395.314.301;1f20:3b7.313;1f21:3b7.314;1f22:3b7.313.300;1f23:3b7.314.300;1f24:3b7.313.301;1f25:3b7.314.301;1f26:3b7.313.342;1f27:3b7.314.342;1f28:397.313;1f29:397.314;1f2a:397.313.300;1f2b:397.314.300;1f2c:397.313.301;1f2d:397.314.301;1f2e:397.313.342;1f2f:397.314.342;1f30:3b9.313;1f31:3b9.314;1f32:3b9.313.300;1f33:3b9.314.300;1f34:3b9.313.301;1f35:3b9.314.301;1f36:3b9.313.342;1f37:3b9.314.342;1f38:399.313;1f39:399.314;1f3a:399.313.300;1f3b:399.314.300;1f3c:399.313.301;1f3d:399.314.301;1f3e:399.313.342;1f3f:399.314.342;1f40:3bf.313;1f41:3bf.314;1f42:3bf.313.300;1f43:3bf.314.300;1f44:3bf.313.301;1f45:3bf.314.301;1f48:39f.313;1f49:39f.314;1f4a:39f.313.300;1f4b:39f.314.300;1f4c:39f.313.301;1f4d:39f.314.301;1f50:3c5.313;1f51:3c5.314;1f52:3c5.313.300;1f53:3c5.314.300;1f54:3c5.313.301;1f55:3c5.314.301;1f56:3c5.313.342;1f57:3c5.314.342;1f59:3a5.314;1f5b:3a5.314.300;1f5d:3a5.314.301;1f5f:3a5.314.342;1f60:3c9.313;1f61:3c9.314;1f62:3c9.313.300;1f63:3c9.314.300;1f64:3c9.313.301;1f65:3c9.314.301;1f66:3c9.313.342;1f67:3c9.314.342;1f68:3a9.313;1f69:3a9.314;1f6a:3a9.313.300;1f6b:3a9.314.300;1f6c:3a9.313.301;1f6d:3a9.314.301;1f6e:3a9.313.342;1f6f:3a9.314.342;1f70:3b1.300;1f71:3b1.301;1f72:3b5.300;1f73:3b5.301;1f74:3b7.300;1f75:3b7.301;1f76:3b9.300;1f77:3b9.301;1f78:3bf.300;1f79:3bf.301;1f7a:3c5.300;1f7b:3c5.301;1f7c:3c9.300;1f7d:3c9.301;1f80:3b1.313.345;1f81:3b1.314.345;1f82:3b1.313.300.345;1f83:3b1.314.300.345;1f84:3b1.313.301.345;1f85:3b1.314.301.345;1f86:3b1.313.342.345;1f87:3b1.314.342.345;1f88:391.313.345;1f89:391.314.345;1f8a:391.313.300.345;1f8b:391.314.300.345;1f8c:391.313.301.345;1f8d:391.314.301.345;1f8e:391.313.342.345;1f8f:391.314.342.345;1f90:3b7.313.345;1f91:3b7.314.345;1f92:3b7.313.300.345;1f93:3b7.314.300.345;1f94:3b7.313.301.345;1f95:3b7.314.301.345;1f96:3b7.313.342.345;1f97:3b7.314.342.345;1f98:397.313.345;1f99:397.314.345;1f9a:397.313.300.345;1f9b:397.314.300.345;1f9c:397.313.301.345;1f9d:397.314.301.345;1f9e:397.313.342.345;1f9f:397.314.342.345;1fa0:3c9.313.345;1fa1:3c9.314.345;1fa2:3c9.313.300.345;1fa3:3c9.314.300.345;1fa4:3c9.313.301.345;1fa5:3c9.314.301.345;1fa6:3c9.313.342.345;1fa7:3c9.314.342.345;1fa8:3a9.313.345;1fa9:3a9.314.345;1faa:3a9.313.300.345;1fab:3a9.314.300.345;1fac:3a9.313.301.345;1fad:3a9.314.301.345;1fae:3a9.313.342.345;1faf:3a9.314.342.345;1fb0:3b1.306;1fb1:3b1.304;1fb2:3b1.300.345;1fb3:3b1.345;1fb4:3b1.301.345;1fb6:3b1.342;1fb7:3b1.342.345;1fb8:391.306;1fb9:391.304;1fba:391.300;1fbb:391.301;1fbc:391.345;1fbe:3b9;1fc1:a8.342;1fc2:3b7.300.345;1fc3:3b7.345;1fc4:3b7.301.345;1fc6:3b7.342;1fc7:3b7.342.345;1fc8:395.300;1fc9:395.301;1fca:397.300;1fcb:397.301;1fcc:397.345;1fcd:1fbf.300;1fce:1fbf.301;1fcf:1fbf.342;1fd0:3b9.306;1fd1:3b9.304;1fd2:3b9.308.300;1fd3:3b9.308.301;1fd6:3b9.342;1fd7:3b9.308.342;1fd8:399.306;1fd9:399.304;1fda:399.300;1fdb:399.301;1fdd:1ffe.300;1fde:1ffe.301;1fdf:1ffe.342;1fe0:3c5.306;1fe1:3c5.304;1fe2:3c5.308.300;1fe3:3c5.308.301;1fe4:3c1.313;1fe5:3c1.314;1fe6:3c5.342;1fe7:3c5.308.342;1fe8:3a5.306;1fe9:3a5.304;1fea:3a5.300;1feb:3a5.301;1fec:3a1.314;1fed:a8.300;1fee:a8.301;1fef:60;1ff2:3c9.300.345;1ff3:3c9.345;1ff4:3c9.301.345;1ff6:3c9.342;1ff7:3c9.342.345;1ff8:39f.300;1ff9:39f.301;1ffa:3a9.300;1ffb:3a9.301;1ffc:3a9.345;1ffd:b4;2000:2002;2001:2003;2126:3a9;212a:4b;212b:41.30a;219a:2190.338;219b:2192.338;21ae:2194.338;21cd:21d0.338;21ce:21d4.338;21cf:21d2.338;2204:2203.338;2209:2208.338;220c:220b.338;2224:2223.338;2226:2225.338;2241:223c.338;2244:2243.338;2247:2245.338;2249:2248.338;2260:3d.338;2262:2261.338;226d:224d.338;226e:3c.338;226f:3e.338;2270:2264.338;2271:2265.338;2274:2272.338;2275:2273.338;2278:2276.338;2279:2277.338;2280:227a.338;2281:227b.338;2284:2282.338;2285:2283.338;2288:2286.338;2289:2287.338;22ac:22a2.338;22ad:22a8.338;22ae:22a9.338;22af:22ab.338;22e0:227c.338;22e1:227d.338;22e2:2291.338;22e3:2292.338;22ea:22b2.338;22eb:22b3.338;22ec:22b4.338;22ed:22b5.338;2329:3008;232a:3009;2adc:2add.338;304c:304b.3099;304e:304d.3099;3050:304f.3099;3052:3051.3099;3054:3053.3099;3056:3055.3099;3058:3057.3099;305a:3059.3099;305c:305b.3099;305e:305d.3099;3060:305f.3099;3062:3061.3099;3065:3064.3099;3067:3066.3099;3069:3068.3099;3070:306f.3099;3071:306f.309a;3073:3072.3099;3074:3072.309a;3076:3075.3099;3077:3075.309a;3079:3078.3099;307a:3078.309a;307c:307b.3099;307d:307b.309a;3094:3046.3099;309e:309d.3099;30ac:30ab.3099;30ae:30ad.3099;30b0:30af.3099;30b2:30b1.3099;30b4:30b3.3099;30b6:30b5.3099;30b8:30b7.3099;30ba:30b9.3099;30bc:30bb.3099;30be:30bd.3099;30c0:30bf.3099;30c2:30c1.3099;30c5:30c4.3099;30c7:30c6.3099;30c9:30c8.3099;30d0:30cf.3099;30d1:30cf.309a;30d3:30d2.3099;30d4:30d2.309a;30d6:30d5.3099;30d7:30d5.309a;30d9:30d8.3099;30da:30d8.309a;30dc:30db.3099;30dd:30db.309a;30f4:30a6.3099;30f7:30ef.3099;30f8:30f0.3099;30f9:30f1.3099;30fa:30f2.3099;30fe:30fd.3099;f900:8c48;f901:66f4;f902:8eca;f903:8cc8;f904:6ed1;f905:4e32;f906:53e5;f907:9f9c;f908:9f9c;f909:5951;f90a:91d1;f90b:5587;f90c:5948;f90d:61f6;f90e:7669;f90f:7f85;f910:863f;f911:87ba;f912:88f8;f913:908f;f914:6a02;f915:6d1b;f916:70d9;f917:73de;f918:843d;f919:916a;f91a:99f1;f91b:4e82;f91c:5375;f91d:6b04;f91e:721b;f91f:862d;f920:9e1e;f921:5d50;f922:6feb;f923:85cd;f924:8964;f925:62c9;f926:81d8;f927:881f;f928:5eca;f929:6717;f92a:6d6a;f92b:72fc;f92c:90ce;f92d:4f86;f92e:51b7;f92f:52de;f930:64c4;f931:6ad3;f932:7210;f933:76e7;f934:8001;f935:8606;f936:865c;f937:8def;f938:9732;f939:9b6f;f93a:9dfa;f93b:788c;f93c:797f;f93d:7da0;f93e:83c9;f93f:9304;f940:9e7f;f941:8ad6;f942:58df;f943:5f04;f944:7c60;f945:807e;f946:7262;f947:78ca;f948:8cc2;f949:96f7;f94a:58d8;f94b:5c62;f94c:6a13;f94d:6dda;f94e:6f0f;f94f:7d2f;f950:7e37;f951:964b;f952:52d2;f953:808b;f954:51dc;f955:51cc;f956:7a1c;f957:7dbe;f958:83f1;f959:9675;f95a:8b80;f95b:62cf;f95c:6a02;f95d:8afe;f95e:4e39;f95f:5be7;f960:6012;f961:7387;f962:7570;f963:5317;f964:78fb;f965:4fbf;f966:5fa9;f967:4e0d;f968:6ccc;f969:6578;f96a:7d22;f96b:53c3;f96c:585e;f96d:7701;f96e:8449;f96f:8aaa;f970:6bba;f971:8fb0;f972:6c88;f973:62fe;f974:82e5;f975:63a0;f976:7565;f977:4eae;f978:5169;f979:51c9;f97a:6881;f97b:7ce7;f97c:826f;f97d:8ad2;f97e:91cf;f97f:52f5;f980:5442;f981:5973;f982:5eec;f983:65c5;f984:6ffe;f985:792a;f986:95ad;f987:9a6a;f988:9e97;f989:9ece;f98a:529b;f98b:66c6;f98c:6b77;f98d:8f62;f98e:5e74;f98f:6190;f990:6200;f991:649a;f992:6f23;f993:7149;f994:7489;f995:79ca;f996:7df4;f997:806f;f998:8f26;f999:84ee;f99a:9023;f99b:934a;f99c:5217;f99d:52a3;f99e:54bd;f99f:70c8;f9a0:88c2;f9a1:8aaa;f9a2:5ec9;f9a3:5ff5;f9a4:637b;f9a5:6bae;f9a6:7c3e;f9a7:7375;f9a8:4ee4;f9a9:56f9;f9aa:5be7;f9ab:5dba;f9ac:601c;f9ad:73b2;f9ae:7469;f9af:7f9a;f9b0:8046;f9b1:9234;f9b2:96f6;f9b3:9748;f9b4:9818;f9b5:4f8b;f9b6:79ae;f9b7:91b4;f9b8:96b8;f9b9:60e1;f9ba:4e86;f9bb:50da;f9bc:5bee;f9bd:5c3f;f9be:6599;f9bf:6a02;f9c0:71ce;f9c1:7642;f9c2:84fc;f9c3:907c;f9c4:9f8d;f9c5:6688;f9c6:962e;f9c7:5289;f9c8:677b;f9c9:67f3;f9ca:6d41;f9cb:6e9c;f9cc:7409;f9cd:7559;f9ce:786b;f9cf:7d10;f9d0:985e;f9d1:516d;f9d2:622e;f9d3:9678;f9d4:502b;f9d5:5d19;f9d6:6dea;f9d7:8f2a;f9d8:5f8b;f9d9:6144;f9da:6817;f9db:7387;f9dc:9686;f9dd:5229;f9de:540f;f9df:5c65;f9e0:6613;f9e1:674e;f9e2:68a8;f9e3:6ce5;f9e4:7406;f9e5:75e2;f9e6:7f79;f9e7:88cf;f9e8:88e1;f9e9:91cc;f9ea:96e2;f9eb:533f;f9ec:6eba;f9ed:541d;f9ee:71d0;f9ef:7498;f9f0:85fa;f9f1:96a3;f9f2:9c57;f9f3:9e9f;f9f4:6797;f9f5:6dcb;f9f6:81e8;f9f7:7acb;f9f8:7b20;f9f9:7c92;f9fa:72c0;f9fb:7099;f9fc:8b58;f9fd:4ec0;f9fe:8336;f9ff:523a;fa00:5207;fa01:5ea6;fa02:62d3;fa03:7cd6;fa04:5b85;fa05:6d1e;fa06:66b4;fa07:8f3b;fa08:884c;fa09:964d;fa0a:898b;fa0b:5ed3;fa0c:5140;fa0d:55c0;fa10:585a;fa12:6674;fa15:51de;fa16:732a;fa17:76ca;fa18:793c;fa19:795e;fa1a:7965;fa1b:798f;fa1c:9756;fa1d:7cbe;fa1e:7fbd;fa20:8612;fa22:8af8;fa25:9038;fa26:90fd;fa2a:98ef;fa2b:98fc;fa2c:9928;fa2d:9db4;fa2e:90de;fa2f:96b7;fa30:4fae;fa31:50e7;fa32:514d;fa33:52c9;fa34:52e4;fa35:5351;fa36:559d;fa37:5606;fa38:5668;fa39:5840;fa3a:58a8;fa3b:5c64;fa3c:5c6e;fa3d:6094;fa3e:6168;fa3f:618e;fa40:61f2;fa41:654f;fa42:65e2;fa43:6691;fa44:6885;fa45:6d77;fa46:6e1a;fa47:6f22;fa48:716e;fa49:722b;fa4a:7422;fa4b:7891;fa4c:793e;fa4d:7949;fa4e:7948;fa4f:7950;fa50:7956;fa51:795d;fa52:798d;fa53:798e;fa54:7a40;fa55:7a81;fa56:7bc0;fa57:7df4;fa58:7e09;fa59:7e41;fa5a:7f72;fa5b:8005;fa5c:81ed;fa5d:8279;fa5e:8279;fa5f:8457;fa60:8910;fa61:8996;fa62:8b01;fa63:8b39;fa64:8cd3;fa65:8d08;fa66:8fb6;fa67:9038;fa68:96e3;fa69:97ff;fa6a:983b;fa6b:6075;fa6c:242ee;fa6d:8218;fa70:4e26;fa71:51b5;fa72:5168;fa73:4f80;fa74:5145;fa75:5180;fa76:52c7;fa77:52fa;fa78:559d;fa79:5555;fa7a:5599;fa7b:55e2;fa7c:585a;fa7d:58b3;fa7e:5944;fa7f:5954;fa80:5a62;fa81:5b28;fa82:5ed2;fa83:5ed9;fa84:5f69;fa85:5fad;fa86:60d8;fa87:614e;fa88:6108;fa89:618e;fa8a:6160;fa8b:61f2;fa8c:6234;fa8d:63c4;fa8e:641c;fa8f:6452;fa90:6556;fa91:6674;fa92:6717;fa93:671b;fa94:6756;fa95:6b79;fa96:6bba;fa97:6d41;fa98:6edb;fa99:6ecb;fa9a:6f22;fa9b:701e;fa9c:716e;fa9d:77a7;fa9e:7235;fa9f:72af;faa0:732a;faa1:7471;faa2:7506;faa3:753b;faa4:761d;faa5:761f;faa6:76ca;faa7:76db;faa8:76f4;faa9:774a;faaa:7740;faab:78cc;faac:7ab1;faad:7bc0;faae:7c7b;faaf:7d5b;fab0:7df4;fab1:7f3e;fab2:8005;fab3:8352;fab4:83ef;fab5:8779;fab6:8941;fab7:8986;fab8:8996;fab9:8abf;faba:8af8;fabb:8acb;fabc:8b01;fabd:8afe;fabe:8aed;fabf:8b39;fac0:8b8a;fac1:8d08;fac2:8f38;fac3:9072;fac4:9199;fac5:9276;fac6:967c;fac7:96e3;fac8:9756;fac9:97db;faca:97ff;facb:980b;facc:983b;facd:9b12;face:9f9c;facf:2284a;fad0:22844;fad1:233d5;fad2:3b9d;fad3:4018;fad4:4039;fad5:25249;fad6:25cd0;fad7:27ed3;fad8:9f43;fad9:9f8e;fb1d:5d9.5b4;fb1f:5f2.5b7;fb2a:5e9.5c1;fb2b:5e9.5c2;fb2c:5e9.5bc.5c1;fb2d:5e9.5bc.5c2;fb2e:5d0.5b7;fb2f:5d0.5b8;fb30:5d0.5bc;fb31:5d1.5bc;fb32:5d2.5bc;fb33:5d3.5bc;fb34:5d4.5bc;fb35:5d5.5bc;fb36:5d6.5bc;fb38:5d8.5bc;fb39:5d9.5bc;fb3a:5da.5bc;fb3b:5db.5bc;fb3c:5dc.5bc;fb3e:5de.5bc;fb40:5e0.5bc;fb41:5e1.5bc;fb43:5e3.5bc;fb44:5e4.5bc;fb46:5e6.5bc;fb47:5e7.5bc;fb48:5e8.5bc;fb49:5e9.5bc;fb4a:5ea.5bc;fb4b:5d5.5b9;fb4c:5d1.5bf;fb4d:5db.5bf;fb4e:5e4.5bf;1109a:11099.110ba;1109c:1109b.110ba;110ab:110a5.110ba;1112e:11131.11127;1112f:11132.11127;1134b:11347.1133e;1134c:11347.11357;114bb:114b9.114ba;114bc:114b9.114b0;114be:114b9.114bd;115ba:115b8.115af;115bb:115b9.115af;11938:11935.11930;1d15e:1d157.1d165;1d15f:1d158.1d165;1d160:1d158.1d165.1d16e;1d161:1d158.1d165.1d16f;1d162:1d158.1d165.1d170;1d163:1d158.1d165.1d171;1d164:1d158.1d165.1d172;1d1bb:1d1b9.1d165;1d1bc:1d1ba.1d165;1d1bd:1d1b9.1d165.1d16e;1d1be:1d1ba.1d165.1d16e;1d1bf:1d1b9.1d165.1d16f;1d1c0:1d1ba.1d165.1d16f;2f800:4e3d;2f801:4e38;2f802:4e41;2f803:20122;2f804:4f60;2f805:4fae;2f806:4fbb;2f807:5002;2f808:507a;2f809:5099;2f80a:50e7;2f80b:50cf;2f80c:349e;2f80d:2063a;2f80e:514d;2f80f:5154;2f810:5164;2f811:5177;2f812:2051c;2f813:34b9;2f814:5167;2f815:518d;2f816:2054b;2f817:5197;2f818:51a4;2f819:4ecc;2f81a:51ac;2f81b:51b5;2f81c:291df;2f81d:51f5;2f81e:5203;2f81f:34df;2f820:523b;2f821:5246;2f822:5272;2f823:5277;2f824:3515;2f825:52c7;2f826:52c9;2f827:52e4;2f828:52fa;2f829:5305;2f82a:5306;2f82b:5317;2f82c:5349;2f82d:5351;2f82e:535a;2f82f:5373;2f830:537d;2f831:537f;2f832:537f;2f833:537f;2f834:20a2c;2f835:7070;2f836:53ca;2f837:53df;2f838:20b63;2f839:53eb;2f83a:53f1;2f83b:5406;2f83c:549e;2f83d:5438;2f83e:5448;2f83f:5468;2f840:54a2;2f841:54f6;2f842:5510;2f843:5553;2f844:5563;2f845:5584;2f846:5584;2f847:5599;2f848:55ab;2f849:55b3;2f84a:55c2;2f84b:5716;2f84c:5606;2f84d:5717;2f84e:5651;2f84f:5674;2f850:5207;2f851:58ee;2f852:57ce;2f853:57f4;2f854:580d;2f855:578b;2f856:5832;2f857:5831;2f858:58ac;2f859:214e4;2f85a:58f2;2f85b:58f7;2f85c:5906;2f85d:591a;2f85e:5922;2f85f:5962;2f860:216a8;2f861:216ea;2f862:59ec;2f863:5a1b;2f864:5a27;2f865:59d8;2f866:5a66;2f867:36ee;2f868:36fc;2f869:5b08;2f86a:5b3e;2f86b:5b3e;2f86c:219c8;2f86d:5bc3;2f86e:5bd8;2f86f:5be7;2f870:5bf3;2f871:21b18;2f872:5bff;2f873:5c06;2f874:5f53;2f875:5c22;2f876:3781;2f877:5c60;2f878:5c6e;2f879:5cc0;2f87a:5c8d;2f87b:21de4;2f87c:5d43;2f87d:21de6;2f87e:5d6e;2f87f:5d6b;2f880:5d7c;2f881:5de1;2f882:5de2;2f883:382f;2f884:5dfd;2f885:5e28;2f886:5e3d;2f887:5e69;2f888:3862;2f889:22183;2f88a:387c;2f88b:5eb0;2f88c:5eb3;2f88d:5eb6;2f88e:5eca;2f88f:2a392;2f890:5efe;2f891:22331;2f892:22331;2f893:8201;2f894:5f22;2f895:5f22;2f896:38c7;2f897:232b8;2f898:261da;2f899:5f62;2f89a:5f6b;2f89b:38e3;2f89c:5f9a;2f89d:5fcd;2f89e:5fd7;2f89f:5ff9;2f8a0:6081;2f8a1:393a;2f8a2:391c;2f8a3:6094;2f8a4:226d4;2f8a5:60c7;2f8a6:6148;2f8a7:614c;2f8a8:614e;2f8a9:614c;2f8aa:617a;2f8ab:618e;2f8ac:61b2;2f8ad:61a4;2f8ae:61af;2f8af:61de;2f8b0:61f2;2f8b1:61f6;2f8b2:6210;2f8b3:621b;2f8b4:625d;2f8b5:62b1;2f8b6:62d4;2f8b7:6350;2f8b8:22b0c;2f8b9:633d;2f8ba:62fc;2f8bb:6368;2f8bc:6383;2f8bd:63e4;2f8be:22bf1;2f8bf:6422;2f8c0:63c5;2f8c1:63a9;2f8c2:3a2e;2f8c3:6469;2f8c4:647e;2f8c5:649d;2f8c6:6477;2f8c7:3a6c;2f8c8:654f;2f8c9:656c;2f8ca:2300a;2f8cb:65e3;2f8cc:66f8;2f8cd:6649;2f8ce:3b19;2f8cf:6691;2f8d0:3b08;2f8d1:3ae4;2f8d2:5192;2f8d3:5195;2f8d4:6700;2f8d5:669c;2f8d6:80ad;2f8d7:43d9;2f8d8:6717;2f8d9:671b;2f8da:6721;2f8db:675e;2f8dc:6753;2f8dd:233c3;2f8de:3b49;2f8df:67fa;2f8e0:6785;2f8e1:6852;2f8e2:6885;2f8e3:2346d;2f8e4:688e;2f8e5:681f;2f8e6:6914;2f8e7:3b9d;2f8e8:6942;2f8e9:69a3;2f8ea:69ea;2f8eb:6aa8;2f8ec:236a3;2f8ed:6adb;2f8ee:3c18;2f8ef:6b21;2f8f0:238a7;2f8f1:6b54;2f8f2:3c4e;2f8f3:6b72;2f8f4:6b9f;2f8f5:6bba;2f8f6:6bbb;2f8f7:23a8d;2f8f8:21d0b;2f8f9:23afa;2f8fa:6c4e;2f8fb:23cbc;2f8fc:6cbf;2f8fd:6ccd;2f8fe:6c67;2f8ff:6d16;2f900:6d3e;2f901:6d77;2f902:6d41;2f903:6d69;2f904:6d78;2f905:6d85;2f906:23d1e;2f907:6d34;2f908:6e2f;2f909:6e6e;2f90a:3d33;2f90b:6ecb;2f90c:6ec7;2f90d:23ed1;2f90e:6df9;2f90f:6f6e;2f910:23f5e;2f911:23f8e;2f912:6fc6;2f913:7039;2f914:701e;2f915:701b;2f916:3d96;2f917:704a;2f918:707d;2f919:7077;2f91a:70ad;2f91b:20525;2f91c:7145;2f91d:24263;2f91e:719c;2f91f:243ab;2f920:7228;2f921:7235;2f922:7250;2f923:24608;2f924:7280;2f925:7295;2f926:24735;2f927:24814;2f928:737a;2f929:738b;2f92a:3eac;2f92b:73a5;2f92c:3eb8;2f92d:3eb8;2f92e:7447;2f92f:745c;2f930:7471;2f931:7485;2f932:74ca;2f933:3f1b;2f934:7524;2f935:24c36;2f936:753e;2f937:24c92;2f938:7570;2f939:2219f;2f93a:7610;2f93b:24fa1;2f93c:24fb8;2f93d:25044;2f93e:3ffc;2f93f:4008;2f940:76f4;2f941:250f3;2f942:250f2;2f943:25119;2f944:25133;2f945:771e;2f946:771f;2f947:771f;2f948:774a;2f949:4039;2f94a:778b;2f94b:4046;2f94c:4096;2f94d:2541d;2f94e:784e;2f94f:788c;2f950:78cc;2f951:40e3;2f952:25626;2f953:7956;2f954:2569a;2f955:256c5;2f956:798f;2f957:79eb;2f958:412f;2f959:7a40;2f95a:7a4a;2f95b:7a4f;2f95c:2597c;2f95d:25aa7;2f95e:25aa7;2f95f:7aee;2f960:4202;2f961:25bab;2f962:7bc6;2f963:7bc9;2f964:4227;2f965:25c80;2f966:7cd2;2f967:42a0;2f968:7ce8;2f969:7ce3;2f96a:7d00;2f96b:25f86;2f96c:7d63;2f96d:4301;2f96e:7dc7;2f96f:7e02;2f970:7e45;2f971:4334;2f972:26228;2f973:26247;2f974:4359;2f975:262d9;2f976:7f7a;2f977:2633e;2f978:7f95;2f979:7ffa;2f97a:8005;2f97b:264da;2f97c:26523;2f97d:8060;2f97e:265a8;2f97f:8070;2f980:2335f;2f981:43d5;2f982:80b2;2f983:8103;2f984:440b;2f985:813e;2f986:5ab5;2f987:267a7;2f988:267b5;2f989:23393;2f98a:2339c;2f98b:8201;2f98c:8204;2f98d:8f9e;2f98e:446b;2f98f:8291;2f990:828b;2f991:829d;2f992:52b3;2f993:82b1;2f994:82b3;2f995:82bd;2f996:82e6;2f997:26b3c;2f998:82e5;2f999:831d;2f99a:8363;2f99b:83ad;2f99c:8323;2f99d:83bd;2f99e:83e7;2f99f:8457;2f9a0:8353;2f9a1:83ca;2f9a2:83cc;2f9a3:83dc;2f9a4:26c36;2f9a5:26d6b;2f9a6:26cd5;2f9a7:452b;2f9a8:84f1;2f9a9:84f3;2f9aa:8516;2f9ab:273ca;2f9ac:8564;2f9ad:26f2c;2f9ae:455d;2f9af:4561;2f9b0:26fb1;2f9b1:270d2;2f9b2:456b;2f9b3:8650;2f9b4:865c;2f9b5:8667;2f9b6:8669;2f9b7:86a9;2f9b8:8688;2f9b9:870e;2f9ba:86e2;2f9bb:8779;2f9bc:8728;2f9bd:876b;2f9be:8786;2f9bf:45d7;2f9c0:87e1;2f9c1:8801;2f9c2:45f9;2f9c3:8860;2f9c4:8863;2f9c5:27667;2f9c6:88d7;2f9c7:88de;2f9c8:4635;2f9c9:88fa;2f9ca:34bb;2f9cb:278ae;2f9cc:27966;2f9cd:46be;2f9ce:46c7;2f9cf:8aa0;2f9d0:8aed;2f9d1:8b8a;2f9d2:8c55;2f9d3:27ca8;2f9d4:8cab;2f9d5:8cc1;2f9d6:8d1b;2f9d7:8d77;2f9d8:27f2f;2f9d9:20804;2f9da:8dcb;2f9db:8dbc;2f9dc:8df0;2f9dd:208de;2f9de:8ed4;2f9df:8f38;2f9e0:285d2;2f9e1:285ed;2f9e2:9094;2f9e3:90f1;2f9e4:9111;2f9e5:2872e;2f9e6:911b;2f9e7:9238;2f9e8:92d7;2f9e9:92d8;2f9ea:927c;2f9eb:93f9;2f9ec:9415;2f9ed:28bfa;2f9ee:958b;2f9ef:4995;2f9f0:95b7;2f9f1:28d77;2f9f2:49e6;2f9f3:96c3;2f9f4:5db2;2f9f5:9723;2f9f6:29145;2f9f7:2921a;2f9f8:4a6e;2f9f9:4a76;2f9fa:97e0;2f9fb:2940a;2f9fc:4ab2;2f9fd:29496;2f9fe:980b;2f9ff:980b;2fa00:9829;2fa01:295b6;2fa02:98e2;2fa03:4b33;2fa04:9929;2fa05:99a7;2fa06:99c2;2fa07:99fe;2fa08:4bce;2fa09:29b30;2fa0a:9b12;2fa0b:9c40;2fa0c:9cfd;2fa0d:4cce;2fa0e:4ced;2fa0f:9d67;2fa10:2a0ce;2fa11:4cf8;2fa12:2a105;2fa13:2a20e;2fa14:2a291;2fa15:9ebb;2fa16:4d56;2fa17:9ef9;2fa18:9efe;2fa19:9f05;2fa1a:9f0f;2fa1b:9f16;2fa1c:9f3b;2fa1d:2a600';
|
|
10
|
+
/** Primary composites: "first.second:composite" in hex, ';'-separated. */
|
|
11
|
+
export const COMP = '41.300:c0;41.301:c1;41.302:c2;41.303:c3;41.308:c4;41.30a:c5;43.327:c7;45.300:c8;45.301:c9;45.302:ca;45.308:cb;49.300:cc;49.301:cd;49.302:ce;49.308:cf;4e.303:d1;4f.300:d2;4f.301:d3;4f.302:d4;4f.303:d5;4f.308:d6;55.300:d9;55.301:da;55.302:db;55.308:dc;59.301:dd;61.300:e0;61.301:e1;61.302:e2;61.303:e3;61.308:e4;61.30a:e5;63.327:e7;65.300:e8;65.301:e9;65.302:ea;65.308:eb;69.300:ec;69.301:ed;69.302:ee;69.308:ef;6e.303:f1;6f.300:f2;6f.301:f3;6f.302:f4;6f.303:f5;6f.308:f6;75.300:f9;75.301:fa;75.302:fb;75.308:fc;79.301:fd;79.308:ff;41.304:100;61.304:101;41.306:102;61.306:103;41.328:104;61.328:105;43.301:106;63.301:107;43.302:108;63.302:109;43.307:10a;63.307:10b;43.30c:10c;63.30c:10d;44.30c:10e;64.30c:10f;45.304:112;65.304:113;45.306:114;65.306:115;45.307:116;65.307:117;45.328:118;65.328:119;45.30c:11a;65.30c:11b;47.302:11c;67.302:11d;47.306:11e;67.306:11f;47.307:120;67.307:121;47.327:122;67.327:123;48.302:124;68.302:125;49.303:128;69.303:129;49.304:12a;69.304:12b;49.306:12c;69.306:12d;49.328:12e;69.328:12f;49.307:130;4a.302:134;6a.302:135;4b.327:136;6b.327:137;4c.301:139;6c.301:13a;4c.327:13b;6c.327:13c;4c.30c:13d;6c.30c:13e;4e.301:143;6e.301:144;4e.327:145;6e.327:146;4e.30c:147;6e.30c:148;4f.304:14c;6f.304:14d;4f.306:14e;6f.306:14f;4f.30b:150;6f.30b:151;52.301:154;72.301:155;52.327:156;72.327:157;52.30c:158;72.30c:159;53.301:15a;73.301:15b;53.302:15c;73.302:15d;53.327:15e;73.327:15f;53.30c:160;73.30c:161;54.327:162;74.327:163;54.30c:164;74.30c:165;55.303:168;75.303:169;55.304:16a;75.304:16b;55.306:16c;75.306:16d;55.30a:16e;75.30a:16f;55.30b:170;75.30b:171;55.328:172;75.328:173;57.302:174;77.302:175;59.302:176;79.302:177;59.308:178;5a.301:179;7a.301:17a;5a.307:17b;7a.307:17c;5a.30c:17d;7a.30c:17e;4f.31b:1a0;6f.31b:1a1;55.31b:1af;75.31b:1b0;41.30c:1cd;61.30c:1ce;49.30c:1cf;69.30c:1d0;4f.30c:1d1;6f.30c:1d2;55.30c:1d3;75.30c:1d4;dc.304:1d5;fc.304:1d6;dc.301:1d7;fc.301:1d8;dc.30c:1d9;fc.30c:1da;dc.300:1db;fc.300:1dc;c4.304:1de;e4.304:1df;226.304:1e0;227.304:1e1;c6.304:1e2;e6.304:1e3;47.30c:1e6;67.30c:1e7;4b.30c:1e8;6b.30c:1e9;4f.328:1ea;6f.328:1eb;1ea.304:1ec;1eb.304:1ed;1b7.30c:1ee;292.30c:1ef;6a.30c:1f0;47.301:1f4;67.301:1f5;4e.300:1f8;6e.300:1f9;c5.301:1fa;e5.301:1fb;c6.301:1fc;e6.301:1fd;d8.301:1fe;f8.301:1ff;41.30f:200;61.30f:201;41.311:202;61.311:203;45.30f:204;65.30f:205;45.311:206;65.311:207;49.30f:208;69.30f:209;49.311:20a;69.311:20b;4f.30f:20c;6f.30f:20d;4f.311:20e;6f.311:20f;52.30f:210;72.30f:211;52.311:212;72.311:213;55.30f:214;75.30f:215;55.311:216;75.311:217;53.326:218;73.326:219;54.326:21a;74.326:21b;48.30c:21e;68.30c:21f;41.307:226;61.307:227;45.327:228;65.327:229;d6.304:22a;f6.304:22b;d5.304:22c;f5.304:22d;4f.307:22e;6f.307:22f;22e.304:230;22f.304:231;59.304:232;79.304:233;a8.301:385;391.301:386;395.301:388;397.301:389;399.301:38a;39f.301:38c;3a5.301:38e;3a9.301:38f;3ca.301:390;399.308:3aa;3a5.308:3ab;3b1.301:3ac;3b5.301:3ad;3b7.301:3ae;3b9.301:3af;3cb.301:3b0;3b9.308:3ca;3c5.308:3cb;3bf.301:3cc;3c5.301:3cd;3c9.301:3ce;3d2.301:3d3;3d2.308:3d4;415.300:400;415.308:401;413.301:403;406.308:407;41a.301:40c;418.300:40d;423.306:40e;418.306:419;438.306:439;435.300:450;435.308:451;433.301:453;456.308:457;43a.301:45c;438.300:45d;443.306:45e;474.30f:476;475.30f:477;416.306:4c1;436.306:4c2;410.306:4d0;430.306:4d1;410.308:4d2;430.308:4d3;415.306:4d6;435.306:4d7;4d8.308:4da;4d9.308:4db;416.308:4dc;436.308:4dd;417.308:4de;437.308:4df;418.304:4e2;438.304:4e3;418.308:4e4;438.308:4e5;41e.308:4e6;43e.308:4e7;4e8.308:4ea;4e9.308:4eb;42d.308:4ec;44d.308:4ed;423.304:4ee;443.304:4ef;423.308:4f0;443.308:4f1;423.30b:4f2;443.30b:4f3;427.308:4f4;447.308:4f5;42b.308:4f8;44b.308:4f9;627.653:622;627.654:623;648.654:624;627.655:625;64a.654:626;6d5.654:6c0;6c1.654:6c2;6d2.654:6d3;928.93c:929;930.93c:931;933.93c:934;9c7.9be:9cb;9c7.9d7:9cc;b47.b56:b48;b47.b3e:b4b;b47.b57:b4c;b92.bd7:b94;bc6.bbe:bca;bc7.bbe:bcb;bc6.bd7:bcc;c46.c56:c48;cbf.cd5:cc0;cc6.cd5:cc7;cc6.cd6:cc8;cc6.cc2:cca;cca.cd5:ccb;d46.d3e:d4a;d47.d3e:d4b;d46.d57:d4c;dd9.dca:dda;dd9.dcf:ddc;ddc.dca:ddd;dd9.ddf:dde;1025.102e:1026;1b05.1b35:1b06;1b07.1b35:1b08;1b09.1b35:1b0a;1b0b.1b35:1b0c;1b0d.1b35:1b0e;1b11.1b35:1b12;1b3a.1b35:1b3b;1b3c.1b35:1b3d;1b3e.1b35:1b40;1b3f.1b35:1b41;1b42.1b35:1b43;41.325:1e00;61.325:1e01;42.307:1e02;62.307:1e03;42.323:1e04;62.323:1e05;42.331:1e06;62.331:1e07;c7.301:1e08;e7.301:1e09;44.307:1e0a;64.307:1e0b;44.323:1e0c;64.323:1e0d;44.331:1e0e;64.331:1e0f;44.327:1e10;64.327:1e11;44.32d:1e12;64.32d:1e13;112.300:1e14;113.300:1e15;112.301:1e16;113.301:1e17;45.32d:1e18;65.32d:1e19;45.330:1e1a;65.330:1e1b;228.306:1e1c;229.306:1e1d;46.307:1e1e;66.307:1e1f;47.304:1e20;67.304:1e21;48.307:1e22;68.307:1e23;48.323:1e24;68.323:1e25;48.308:1e26;68.308:1e27;48.327:1e28;68.327:1e29;48.32e:1e2a;68.32e:1e2b;49.330:1e2c;69.330:1e2d;cf.301:1e2e;ef.301:1e2f;4b.301:1e30;6b.301:1e31;4b.323:1e32;6b.323:1e33;4b.331:1e34;6b.331:1e35;4c.323:1e36;6c.323:1e37;1e36.304:1e38;1e37.304:1e39;4c.331:1e3a;6c.331:1e3b;4c.32d:1e3c;6c.32d:1e3d;4d.301:1e3e;6d.301:1e3f;4d.307:1e40;6d.307:1e41;4d.323:1e42;6d.323:1e43;4e.307:1e44;6e.307:1e45;4e.323:1e46;6e.323:1e47;4e.331:1e48;6e.331:1e49;4e.32d:1e4a;6e.32d:1e4b;d5.301:1e4c;f5.301:1e4d;d5.308:1e4e;f5.308:1e4f;14c.300:1e50;14d.300:1e51;14c.301:1e52;14d.301:1e53;50.301:1e54;70.301:1e55;50.307:1e56;70.307:1e57;52.307:1e58;72.307:1e59;52.323:1e5a;72.323:1e5b;1e5a.304:1e5c;1e5b.304:1e5d;52.331:1e5e;72.331:1e5f;53.307:1e60;73.307:1e61;53.323:1e62;73.323:1e63;15a.307:1e64;15b.307:1e65;160.307:1e66;161.307:1e67;1e62.307:1e68;1e63.307:1e69;54.307:1e6a;74.307:1e6b;54.323:1e6c;74.323:1e6d;54.331:1e6e;74.331:1e6f;54.32d:1e70;74.32d:1e71;55.324:1e72;75.324:1e73;55.330:1e74;75.330:1e75;55.32d:1e76;75.32d:1e77;168.301:1e78;169.301:1e79;16a.308:1e7a;16b.308:1e7b;56.303:1e7c;76.303:1e7d;56.323:1e7e;76.323:1e7f;57.300:1e80;77.300:1e81;57.301:1e82;77.301:1e83;57.308:1e84;77.308:1e85;57.307:1e86;77.307:1e87;57.323:1e88;77.323:1e89;58.307:1e8a;78.307:1e8b;58.308:1e8c;78.308:1e8d;59.307:1e8e;79.307:1e8f;5a.302:1e90;7a.302:1e91;5a.323:1e92;7a.323:1e93;5a.331:1e94;7a.331:1e95;68.331:1e96;74.308:1e97;77.30a:1e98;79.30a:1e99;17f.307:1e9b;41.323:1ea0;61.323:1ea1;41.309:1ea2;61.309:1ea3;c2.301:1ea4;e2.301:1ea5;c2.300:1ea6;e2.300:1ea7;c2.309:1ea8;e2.309:1ea9;c2.303:1eaa;e2.303:1eab;1ea0.302:1eac;1ea1.302:1ead;102.301:1eae;103.301:1eaf;102.300:1eb0;103.300:1eb1;102.309:1eb2;103.309:1eb3;102.303:1eb4;103.303:1eb5;1ea0.306:1eb6;1ea1.306:1eb7;45.323:1eb8;65.323:1eb9;45.309:1eba;65.309:1ebb;45.303:1ebc;65.303:1ebd;ca.301:1ebe;ea.301:1ebf;ca.300:1ec0;ea.300:1ec1;ca.309:1ec2;ea.309:1ec3;ca.303:1ec4;ea.303:1ec5;1eb8.302:1ec6;1eb9.302:1ec7;49.309:1ec8;69.309:1ec9;49.323:1eca;69.323:1ecb;4f.323:1ecc;6f.323:1ecd;4f.309:1ece;6f.309:1ecf;d4.301:1ed0;f4.301:1ed1;d4.300:1ed2;f4.300:1ed3;d4.309:1ed4;f4.309:1ed5;d4.303:1ed6;f4.303:1ed7;1ecc.302:1ed8;1ecd.302:1ed9;1a0.301:1eda;1a1.301:1edb;1a0.300:1edc;1a1.300:1edd;1a0.309:1ede;1a1.309:1edf;1a0.303:1ee0;1a1.303:1ee1;1a0.323:1ee2;1a1.323:1ee3;55.323:1ee4;75.323:1ee5;55.309:1ee6;75.309:1ee7;1af.301:1ee8;1b0.301:1ee9;1af.300:1eea;1b0.300:1eeb;1af.309:1eec;1b0.309:1eed;1af.303:1eee;1b0.303:1eef;1af.323:1ef0;1b0.323:1ef1;59.300:1ef2;79.300:1ef3;59.323:1ef4;79.323:1ef5;59.309:1ef6;79.309:1ef7;59.303:1ef8;79.303:1ef9;3b1.313:1f00;3b1.314:1f01;1f00.300:1f02;1f01.300:1f03;1f00.301:1f04;1f01.301:1f05;1f00.342:1f06;1f01.342:1f07;391.313:1f08;391.314:1f09;1f08.300:1f0a;1f09.300:1f0b;1f08.301:1f0c;1f09.301:1f0d;1f08.342:1f0e;1f09.342:1f0f;3b5.313:1f10;3b5.314:1f11;1f10.300:1f12;1f11.300:1f13;1f10.301:1f14;1f11.301:1f15;395.313:1f18;395.314:1f19;1f18.300:1f1a;1f19.300:1f1b;1f18.301:1f1c;1f19.301:1f1d;3b7.313:1f20;3b7.314:1f21;1f20.300:1f22;1f21.300:1f23;1f20.301:1f24;1f21.301:1f25;1f20.342:1f26;1f21.342:1f27;397.313:1f28;397.314:1f29;1f28.300:1f2a;1f29.300:1f2b;1f28.301:1f2c;1f29.301:1f2d;1f28.342:1f2e;1f29.342:1f2f;3b9.313:1f30;3b9.314:1f31;1f30.300:1f32;1f31.300:1f33;1f30.301:1f34;1f31.301:1f35;1f30.342:1f36;1f31.342:1f37;399.313:1f38;399.314:1f39;1f38.300:1f3a;1f39.300:1f3b;1f38.301:1f3c;1f39.301:1f3d;1f38.342:1f3e;1f39.342:1f3f;3bf.313:1f40;3bf.314:1f41;1f40.300:1f42;1f41.300:1f43;1f40.301:1f44;1f41.301:1f45;39f.313:1f48;39f.314:1f49;1f48.300:1f4a;1f49.300:1f4b;1f48.301:1f4c;1f49.301:1f4d;3c5.313:1f50;3c5.314:1f51;1f50.300:1f52;1f51.300:1f53;1f50.301:1f54;1f51.301:1f55;1f50.342:1f56;1f51.342:1f57;3a5.314:1f59;1f59.300:1f5b;1f59.301:1f5d;1f59.342:1f5f;3c9.313:1f60;3c9.314:1f61;1f60.300:1f62;1f61.300:1f63;1f60.301:1f64;1f61.301:1f65;1f60.342:1f66;1f61.342:1f67;3a9.313:1f68;3a9.314:1f69;1f68.300:1f6a;1f69.300:1f6b;1f68.301:1f6c;1f69.301:1f6d;1f68.342:1f6e;1f69.342:1f6f;3b1.300:1f70;3b5.300:1f72;3b7.300:1f74;3b9.300:1f76;3bf.300:1f78;3c5.300:1f7a;3c9.300:1f7c;1f00.345:1f80;1f01.345:1f81;1f02.345:1f82;1f03.345:1f83;1f04.345:1f84;1f05.345:1f85;1f06.345:1f86;1f07.345:1f87;1f08.345:1f88;1f09.345:1f89;1f0a.345:1f8a;1f0b.345:1f8b;1f0c.345:1f8c;1f0d.345:1f8d;1f0e.345:1f8e;1f0f.345:1f8f;1f20.345:1f90;1f21.345:1f91;1f22.345:1f92;1f23.345:1f93;1f24.345:1f94;1f25.345:1f95;1f26.345:1f96;1f27.345:1f97;1f28.345:1f98;1f29.345:1f99;1f2a.345:1f9a;1f2b.345:1f9b;1f2c.345:1f9c;1f2d.345:1f9d;1f2e.345:1f9e;1f2f.345:1f9f;1f60.345:1fa0;1f61.345:1fa1;1f62.345:1fa2;1f63.345:1fa3;1f64.345:1fa4;1f65.345:1fa5;1f66.345:1fa6;1f67.345:1fa7;1f68.345:1fa8;1f69.345:1fa9;1f6a.345:1faa;1f6b.345:1fab;1f6c.345:1fac;1f6d.345:1fad;1f6e.345:1fae;1f6f.345:1faf;3b1.306:1fb0;3b1.304:1fb1;1f70.345:1fb2;3b1.345:1fb3;3ac.345:1fb4;3b1.342:1fb6;1fb6.345:1fb7;391.306:1fb8;391.304:1fb9;391.300:1fba;391.345:1fbc;a8.342:1fc1;1f74.345:1fc2;3b7.345:1fc3;3ae.345:1fc4;3b7.342:1fc6;1fc6.345:1fc7;395.300:1fc8;397.300:1fca;397.345:1fcc;1fbf.300:1fcd;1fbf.301:1fce;1fbf.342:1fcf;3b9.306:1fd0;3b9.304:1fd1;3ca.300:1fd2;3b9.342:1fd6;3ca.342:1fd7;399.306:1fd8;399.304:1fd9;399.300:1fda;1ffe.300:1fdd;1ffe.301:1fde;1ffe.342:1fdf;3c5.306:1fe0;3c5.304:1fe1;3cb.300:1fe2;3c1.313:1fe4;3c1.314:1fe5;3c5.342:1fe6;3cb.342:1fe7;3a5.306:1fe8;3a5.304:1fe9;3a5.300:1fea;3a1.314:1fec;a8.300:1fed;1f7c.345:1ff2;3c9.345:1ff3;3ce.345:1ff4;3c9.342:1ff6;1ff6.345:1ff7;39f.300:1ff8;3a9.300:1ffa;3a9.345:1ffc;2190.338:219a;2192.338:219b;2194.338:21ae;21d0.338:21cd;21d4.338:21ce;21d2.338:21cf;2203.338:2204;2208.338:2209;220b.338:220c;2223.338:2224;2225.338:2226;223c.338:2241;2243.338:2244;2245.338:2247;2248.338:2249;3d.338:2260;2261.338:2262;224d.338:226d;3c.338:226e;3e.338:226f;2264.338:2270;2265.338:2271;2272.338:2274;2273.338:2275;2276.338:2278;2277.338:2279;227a.338:2280;227b.338:2281;2282.338:2284;2283.338:2285;2286.338:2288;2287.338:2289;22a2.338:22ac;22a8.338:22ad;22a9.338:22ae;22ab.338:22af;227c.338:22e0;227d.338:22e1;2291.338:22e2;2292.338:22e3;22b2.338:22ea;22b3.338:22eb;22b4.338:22ec;22b5.338:22ed;304b.3099:304c;304d.3099:304e;304f.3099:3050;3051.3099:3052;3053.3099:3054;3055.3099:3056;3057.3099:3058;3059.3099:305a;305b.3099:305c;305d.3099:305e;305f.3099:3060;3061.3099:3062;3064.3099:3065;3066.3099:3067;3068.3099:3069;306f.3099:3070;306f.309a:3071;3072.3099:3073;3072.309a:3074;3075.3099:3076;3075.309a:3077;3078.3099:3079;3078.309a:307a;307b.3099:307c;307b.309a:307d;3046.3099:3094;309d.3099:309e;30ab.3099:30ac;30ad.3099:30ae;30af.3099:30b0;30b1.3099:30b2;30b3.3099:30b4;30b5.3099:30b6;30b7.3099:30b8;30b9.3099:30ba;30bb.3099:30bc;30bd.3099:30be;30bf.3099:30c0;30c1.3099:30c2;30c4.3099:30c5;30c6.3099:30c7;30c8.3099:30c9;30cf.3099:30d0;30cf.309a:30d1;30d2.3099:30d3;30d2.309a:30d4;30d5.3099:30d6;30d5.309a:30d7;30d8.3099:30d9;30d8.309a:30da;30db.3099:30dc;30db.309a:30dd;30a6.3099:30f4;30ef.3099:30f7;30f0.3099:30f8;30f1.3099:30f9;30f2.3099:30fa;30fd.3099:30fe;11099.110ba:1109a;1109b.110ba:1109c;110a5.110ba:110ab;11131.11127:1112e;11132.11127:1112f;11347.1133e:1134b;11347.11357:1134c;114b9.114ba:114bb;114b9.114b0:114bc;114b9.114bd:114be;115b8.115af:115ba;115b9.115af:115bb;11935.11930:11938';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** True when the code point is assigned in Unicode 15.1 (General_Category != Cn). */
|
|
2
|
+
export declare function isAssigned(cp: number): boolean;
|
|
3
|
+
/** Canonical combining class (Unicode 15.1). */
|
|
4
|
+
export declare function combiningClass(cp: number): number;
|
|
5
|
+
/** Normalization Form C of a code point sequence (UAX #15), using Unicode 15.1 data. */
|
|
6
|
+
export declare function nfc(cps: readonly number[]): number[];
|
|
7
|
+
/** Code points of a string (lone surrogates come out as themselves). */
|
|
8
|
+
export declare function codePoints(s: string): number[];
|
|
9
|
+
/** True when the string is in NFC under Unicode 15.1. */
|
|
10
|
+
export declare function isNFC(s: string): boolean;
|
|
11
|
+
/** True when the string contains an unpaired surrogate. */
|
|
12
|
+
export declare function hasLoneSurrogate(s: string): boolean;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Unicode 15.1 character checks for SPEC.md 3.5, from tables shipped with this library
|
|
2
|
+
// (src/unicode-data.ts). Nothing here calls String.prototype.normalize or uses \p{...}
|
|
3
|
+
// regular expressions, so results do not depend on the JavaScript engine's Unicode version.
|
|
4
|
+
import { ASSIGNED, CCC, COMP, DECOMP } from './unicode-data.js';
|
|
5
|
+
/** True when the code point is assigned in Unicode 15.1 (General_Category != Cn). */
|
|
6
|
+
export function isAssigned(cp) {
|
|
7
|
+
let lo = 0;
|
|
8
|
+
let hi = ASSIGNED.length / 2 - 1;
|
|
9
|
+
while (lo <= hi) {
|
|
10
|
+
const mid = (lo + hi) >> 1;
|
|
11
|
+
if (cp < ASSIGNED[2 * mid])
|
|
12
|
+
hi = mid - 1;
|
|
13
|
+
else if (cp > ASSIGNED[2 * mid + 1])
|
|
14
|
+
lo = mid + 1;
|
|
15
|
+
else
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
let cccMap = null;
|
|
21
|
+
let decompMap = null;
|
|
22
|
+
let compMap = null;
|
|
23
|
+
function tables() {
|
|
24
|
+
if (cccMap)
|
|
25
|
+
return;
|
|
26
|
+
const c = new Map();
|
|
27
|
+
for (const run of CCC.split(';')) {
|
|
28
|
+
const [a, b, k] = run.split(':');
|
|
29
|
+
const end = parseInt(b, 16);
|
|
30
|
+
for (let cp = parseInt(a, 16); cp <= end; cp++)
|
|
31
|
+
c.set(cp, Number(k));
|
|
32
|
+
}
|
|
33
|
+
const d = new Map();
|
|
34
|
+
for (const e of DECOMP.split(';')) {
|
|
35
|
+
const [cp, seq] = e.split(':');
|
|
36
|
+
d.set(parseInt(cp, 16), seq.split('.').map((h) => parseInt(h, 16)));
|
|
37
|
+
}
|
|
38
|
+
const m = new Map();
|
|
39
|
+
for (const e of COMP.split(';')) {
|
|
40
|
+
const [pair, cp] = e.split(':');
|
|
41
|
+
const [x, y] = pair.split('.').map((h) => parseInt(h, 16));
|
|
42
|
+
m.set(x * 0x110000 + y, parseInt(cp, 16));
|
|
43
|
+
}
|
|
44
|
+
cccMap = c;
|
|
45
|
+
decompMap = d;
|
|
46
|
+
compMap = m;
|
|
47
|
+
}
|
|
48
|
+
/** Canonical combining class (Unicode 15.1). */
|
|
49
|
+
export function combiningClass(cp) {
|
|
50
|
+
tables();
|
|
51
|
+
return cccMap.get(cp) ?? 0;
|
|
52
|
+
}
|
|
53
|
+
const SBASE = 0xac00;
|
|
54
|
+
const LBASE = 0x1100;
|
|
55
|
+
const VBASE = 0x1161;
|
|
56
|
+
const TBASE = 0x11a7;
|
|
57
|
+
const LCOUNT = 19;
|
|
58
|
+
const VCOUNT = 21;
|
|
59
|
+
const TCOUNT = 28;
|
|
60
|
+
const NCOUNT = VCOUNT * TCOUNT;
|
|
61
|
+
const SCOUNT = LCOUNT * NCOUNT;
|
|
62
|
+
function decompose(cp, out) {
|
|
63
|
+
const s = cp - SBASE;
|
|
64
|
+
if (s >= 0 && s < SCOUNT) {
|
|
65
|
+
out.push(LBASE + Math.floor(s / NCOUNT), VBASE + Math.floor((s % NCOUNT) / TCOUNT));
|
|
66
|
+
if (s % TCOUNT)
|
|
67
|
+
out.push(TBASE + (s % TCOUNT));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const d = decompMap.get(cp);
|
|
71
|
+
if (d)
|
|
72
|
+
out.push(...d);
|
|
73
|
+
else
|
|
74
|
+
out.push(cp);
|
|
75
|
+
}
|
|
76
|
+
function compose(a, b) {
|
|
77
|
+
const l = a - LBASE;
|
|
78
|
+
if (l >= 0 && l < LCOUNT) {
|
|
79
|
+
const v = b - VBASE;
|
|
80
|
+
if (v >= 0 && v < VCOUNT)
|
|
81
|
+
return SBASE + (l * VCOUNT + v) * TCOUNT;
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
const s = a - SBASE;
|
|
85
|
+
if (s >= 0 && s < SCOUNT && s % TCOUNT === 0) {
|
|
86
|
+
const t = b - TBASE;
|
|
87
|
+
if (t > 0 && t < TCOUNT)
|
|
88
|
+
return a + t;
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
return compMap.get(a * 0x110000 + b);
|
|
92
|
+
}
|
|
93
|
+
/** Normalization Form C of a code point sequence (UAX #15), using Unicode 15.1 data. */
|
|
94
|
+
export function nfc(cps) {
|
|
95
|
+
tables();
|
|
96
|
+
const d = [];
|
|
97
|
+
for (const cp of cps)
|
|
98
|
+
decompose(cp, d);
|
|
99
|
+
// Canonical ordering: stable sort of each run of non-starters by combining class.
|
|
100
|
+
for (let i = 1; i < d.length; i++) {
|
|
101
|
+
const cc = combiningClass(d[i]);
|
|
102
|
+
if (cc === 0)
|
|
103
|
+
continue;
|
|
104
|
+
let j = i;
|
|
105
|
+
while (j > 0) {
|
|
106
|
+
const pc = combiningClass(d[j - 1]);
|
|
107
|
+
if (pc <= cc)
|
|
108
|
+
break;
|
|
109
|
+
const t = d[j];
|
|
110
|
+
d[j] = d[j - 1];
|
|
111
|
+
d[j - 1] = t;
|
|
112
|
+
j--;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Canonical composition.
|
|
116
|
+
const res = [];
|
|
117
|
+
let starter = -1;
|
|
118
|
+
let lastCC = 0;
|
|
119
|
+
for (const ch of d) {
|
|
120
|
+
const cc = combiningClass(ch);
|
|
121
|
+
if (starter >= 0) {
|
|
122
|
+
const adjacent = res.length - 1 === starter;
|
|
123
|
+
if (adjacent || (lastCC !== 0 && lastCC < cc)) {
|
|
124
|
+
const c = compose(res[starter], ch);
|
|
125
|
+
if (c !== undefined) {
|
|
126
|
+
res[starter] = c;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (cc === 0)
|
|
132
|
+
starter = res.length;
|
|
133
|
+
lastCC = cc;
|
|
134
|
+
res.push(ch);
|
|
135
|
+
}
|
|
136
|
+
return res;
|
|
137
|
+
}
|
|
138
|
+
/** Code points of a string (lone surrogates come out as themselves). */
|
|
139
|
+
export function codePoints(s) {
|
|
140
|
+
const out = [];
|
|
141
|
+
for (let i = 0; i < s.length; i++) {
|
|
142
|
+
const c = s.charCodeAt(i);
|
|
143
|
+
if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
144
|
+
const d = s.charCodeAt(i + 1);
|
|
145
|
+
if (d >= 0xdc00 && d <= 0xdfff) {
|
|
146
|
+
out.push(0x10000 + ((c - 0xd800) << 10) + (d - 0xdc00));
|
|
147
|
+
i++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
out.push(c);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
/** True when the string is in NFC under Unicode 15.1. */
|
|
156
|
+
export function isNFC(s) {
|
|
157
|
+
const cps = codePoints(s);
|
|
158
|
+
// Below U+0300 every character is a starter with NFC_Quick_Check=Yes.
|
|
159
|
+
if (cps.every((c) => c < 0x300))
|
|
160
|
+
return true;
|
|
161
|
+
const n = nfc(cps);
|
|
162
|
+
if (n.length !== cps.length)
|
|
163
|
+
return false;
|
|
164
|
+
for (let i = 0; i < n.length; i++)
|
|
165
|
+
if (n[i] !== cps[i])
|
|
166
|
+
return false;
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
/** True when the string contains an unpaired surrogate. */
|
|
170
|
+
export function hasLoneSurrogate(s) {
|
|
171
|
+
for (let i = 0; i < s.length; i++) {
|
|
172
|
+
const c = s.charCodeAt(i);
|
|
173
|
+
if (c >= 0xd800 && c <= 0xdbff) {
|
|
174
|
+
const d = i + 1 < s.length ? s.charCodeAt(i + 1) : 0;
|
|
175
|
+
if (d >= 0xdc00 && d <= 0xdfff)
|
|
176
|
+
i++;
|
|
177
|
+
else
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
else if (c >= 0xdc00 && c <= 0xdfff)
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type TypeName } from './lexical.js';
|
|
2
|
+
/** A typed scalar (SPEC 4.1). */
|
|
3
|
+
export interface TypedScalar {
|
|
4
|
+
type: TypeName;
|
|
5
|
+
value: string | boolean;
|
|
6
|
+
}
|
|
7
|
+
/** A cell reference (SPEC 4.3): what a cell URI denotes. `"*"` marks a slice. */
|
|
8
|
+
export interface CellRef {
|
|
9
|
+
args: Record<string, TypedScalar | '*'>;
|
|
10
|
+
fn: string;
|
|
11
|
+
ns: string;
|
|
12
|
+
asof?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A function descriptor's `signature` member (SPEC 7). */
|
|
15
|
+
export interface Signature {
|
|
16
|
+
args: Record<string, {
|
|
17
|
+
type: TypeName;
|
|
18
|
+
valid: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
returns: TypeName;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Parse a cell URI into a cell reference, taking argument types from the function's
|
|
24
|
+
* signature (SPEC 5.4). Checks run in the order of SPEC 5.4 and the first failure is thrown as
|
|
25
|
+
* a DatumeshError.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseUri(uri: string, signature: Signature | unknown): CellRef;
|
|
28
|
+
/** Write the unique cell URI of a cell reference (SPEC 5.2). Throws DatumeshError if invalid. */
|
|
29
|
+
export declare function formatUri(ref: CellRef | unknown): string;
|
|
30
|
+
/** The HTTPS URL of a cell URI on mesh host `mesh` (SPEC 5.3). */
|
|
31
|
+
export declare function httpsUrl(uri: string, mesh: string): string;
|
package/dist/esm/uri.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// Cell URIs (SPEC.md section 5).
|
|
2
|
+
import { DatumeshError, fail } from './errors.js';
|
|
3
|
+
import { isObject, sortedKeys, toJson } from './json.js';
|
|
4
|
+
import { LIMITS, checkArgName, checkInstant, checkName, checkNamespace, checkTypedValue } from './lexical.js';
|
|
5
|
+
import { utf8Decode, utf8Encode } from './utf8.js';
|
|
6
|
+
import { canonSignature, structSignature, validate } from './validate.js';
|
|
7
|
+
const SCHEME = 'cell://';
|
|
8
|
+
function isLiteral(c) {
|
|
9
|
+
return /^[A-Za-z0-9\-._~:]$/.test(c);
|
|
10
|
+
}
|
|
11
|
+
function decodeValue(v, path) {
|
|
12
|
+
const bytes = [];
|
|
13
|
+
for (let i = 0; i < v.length;) {
|
|
14
|
+
const c = v[i];
|
|
15
|
+
if (c === '%') {
|
|
16
|
+
const h = v.slice(i + 1, i + 3);
|
|
17
|
+
if (!/^[0-9A-F]{2}$/.test(h))
|
|
18
|
+
fail('E_CANON_PERCENT', 'percent-encoding must be % and two uppercase hex digits', path);
|
|
19
|
+
const b = parseInt(h, 16);
|
|
20
|
+
if (isLiteral(String.fromCharCode(b)))
|
|
21
|
+
fail('E_CANON_PERCENT', `${JSON.stringify(String.fromCharCode(b))} must not be percent-encoded`, path);
|
|
22
|
+
bytes.push(b);
|
|
23
|
+
i += 3;
|
|
24
|
+
}
|
|
25
|
+
else if (isLiteral(c)) {
|
|
26
|
+
bytes.push(c.charCodeAt(0));
|
|
27
|
+
i++;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const cp = v.codePointAt(i);
|
|
31
|
+
fail('E_CANON_PERCENT', `${JSON.stringify(String.fromCodePoint(cp))} must be percent-encoded`, path);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const s = utf8Decode(Uint8Array.from(bytes));
|
|
35
|
+
if (s === null)
|
|
36
|
+
fail('E_CANON_PERCENT', 'percent-encoded bytes are not UTF-8', path);
|
|
37
|
+
return s;
|
|
38
|
+
}
|
|
39
|
+
function encodeValue(s) {
|
|
40
|
+
let out = '';
|
|
41
|
+
for (const b of utf8Encode(s)) {
|
|
42
|
+
const c = String.fromCharCode(b);
|
|
43
|
+
out += isLiteral(c) ? c : `%${b.toString(16).toUpperCase().padStart(2, '0')}`;
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function readSignature(signature) {
|
|
48
|
+
if (signature === null || signature === undefined)
|
|
49
|
+
throw new TypeError('parseUri needs the function signature (descriptor.signature)');
|
|
50
|
+
let sig;
|
|
51
|
+
try {
|
|
52
|
+
sig = toJson(signature);
|
|
53
|
+
structSignature(sig, 'signature');
|
|
54
|
+
canonSignature(sig, 'signature');
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (e instanceof DatumeshError)
|
|
58
|
+
throw new DatumeshError(e.code, `invalid signature: ${e.detail}`, e.path?.replace(/^\$/, 'signature') ?? 'signature');
|
|
59
|
+
throw e;
|
|
60
|
+
}
|
|
61
|
+
return sig;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Parse a cell URI into a cell reference, taking argument types from the function's
|
|
65
|
+
* signature (SPEC 5.4). Checks run in the order of SPEC 5.4 and the first failure is thrown as
|
|
66
|
+
* a DatumeshError.
|
|
67
|
+
*/
|
|
68
|
+
export function parseUri(uri, signature) {
|
|
69
|
+
if (typeof uri !== 'string')
|
|
70
|
+
throw new TypeError('uri must be a string');
|
|
71
|
+
const sig = readSignature(signature);
|
|
72
|
+
const declared = sig.args;
|
|
73
|
+
// 1. Outer grammar.
|
|
74
|
+
if (!uri.startsWith(SCHEME) || uri.includes('#'))
|
|
75
|
+
fail('E_PARSE_URI', 'not cell://<namespace>/<function>[?<query>] without fragment', '$');
|
|
76
|
+
const rest = uri.slice(SCHEME.length);
|
|
77
|
+
const q = rest.indexOf('?');
|
|
78
|
+
const path = q < 0 ? rest : rest.slice(0, q);
|
|
79
|
+
const query = q < 0 ? null : rest.slice(q + 1);
|
|
80
|
+
if (query === '')
|
|
81
|
+
fail('E_PARSE_URI', 'empty query', '$');
|
|
82
|
+
// SPEC 5.1 lists userinfo and a port among outer-grammar failures (E_PARSE_URI). (The
|
|
83
|
+
// reference tool reports them as E_CANON_NAME; see DEFECTS.md.)
|
|
84
|
+
const authority = path.split('/')[0];
|
|
85
|
+
if (authority.includes('@'))
|
|
86
|
+
fail('E_PARSE_URI', 'a cell URI has no userinfo', '$');
|
|
87
|
+
if (authority.includes(':'))
|
|
88
|
+
fail('E_PARSE_URI', 'a cell URI has no port', '$');
|
|
89
|
+
const params = (query === null ? [] : query.split('&')).map((p) => {
|
|
90
|
+
const e = p.indexOf('=');
|
|
91
|
+
if (e < 0)
|
|
92
|
+
fail('E_PARSE_URI', `parameter without '=': ${JSON.stringify(p)}`, '$');
|
|
93
|
+
return { name: p.slice(0, e), value: p.slice(e + 1) };
|
|
94
|
+
});
|
|
95
|
+
// 2. Namespace and function name.
|
|
96
|
+
const slash = path.lastIndexOf('/');
|
|
97
|
+
if (slash < 0)
|
|
98
|
+
fail('E_CANON_NAME', 'missing namespace', 'uri.path');
|
|
99
|
+
const ns = path.slice(0, slash);
|
|
100
|
+
const fn = path.slice(slash + 1);
|
|
101
|
+
checkNamespace(ns, 'uri.path');
|
|
102
|
+
checkName(fn, 'uri.path');
|
|
103
|
+
if (path.length > LIMITS.function_name)
|
|
104
|
+
fail('E_CANON_LIMIT', 'function name too long', 'uri.path');
|
|
105
|
+
// 3. Parameter names, left to right.
|
|
106
|
+
const at = (n) => `uri.query.${n}`;
|
|
107
|
+
// asof: when the last parameter is asof, that is the asof parameter and any earlier asof is a
|
|
108
|
+
// repetition (E_CANON_ARG_DUPLICATE); otherwise an asof anywhere is out of place
|
|
109
|
+
// (E_CANON_ARG_ORDER). SPEC 5.2 does not say which applies when both do; this matches the
|
|
110
|
+
// reference tool (DEFECTS.md).
|
|
111
|
+
let prev = null;
|
|
112
|
+
const lastIsAsof = params.length > 0 && params[params.length - 1].name === 'asof';
|
|
113
|
+
params.forEach((p, i) => {
|
|
114
|
+
if (p.name === 'asof') {
|
|
115
|
+
if (!lastIsAsof)
|
|
116
|
+
fail('E_CANON_ARG_ORDER', 'asof appears once, as the last parameter', at(p.name));
|
|
117
|
+
if (i !== params.length - 1)
|
|
118
|
+
fail('E_CANON_ARG_DUPLICATE', 'asof repeated', at(p.name));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
checkArgName(p.name, at(p.name));
|
|
122
|
+
if (prev !== null && p.name === prev)
|
|
123
|
+
fail('E_CANON_ARG_DUPLICATE', `argument ${JSON.stringify(p.name)} repeated`, at(p.name));
|
|
124
|
+
if (prev !== null && p.name < prev)
|
|
125
|
+
fail('E_CANON_ARG_ORDER', 'arguments must be sorted by name', at(p.name));
|
|
126
|
+
prev = p.name;
|
|
127
|
+
});
|
|
128
|
+
const argParams = params.filter((p) => p.name !== 'asof');
|
|
129
|
+
// 4. Argument count.
|
|
130
|
+
if (argParams.length > LIMITS.args)
|
|
131
|
+
fail('E_CANON_LIMIT', `more than ${LIMITS.args} arguments`, 'uri.query');
|
|
132
|
+
// 5. Against the signature: unknown arguments, then missing ones.
|
|
133
|
+
for (const p of argParams) {
|
|
134
|
+
if (!Object.prototype.hasOwnProperty.call(declared, p.name))
|
|
135
|
+
fail('E_ARG_UNKNOWN', `function declares no argument ${JSON.stringify(p.name)}`, at(p.name));
|
|
136
|
+
}
|
|
137
|
+
const present = new Set(argParams.map((p) => p.name));
|
|
138
|
+
for (const n of sortedKeys(declared)) {
|
|
139
|
+
if (!present.has(n))
|
|
140
|
+
fail('E_ARG_MISSING', `argument ${JSON.stringify(n)} absent; use ${n}=* for a slice`, 'uri.query');
|
|
141
|
+
}
|
|
142
|
+
// 6. Values, left to right: percent-encoding, then the lexical form.
|
|
143
|
+
const args = {};
|
|
144
|
+
for (const p of argParams) {
|
|
145
|
+
if (p.value === '*') {
|
|
146
|
+
args[p.name] = '*';
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const type = declared[p.name].type;
|
|
150
|
+
const s = decodeValue(p.value, at(p.name));
|
|
151
|
+
if (type === 'boolean') {
|
|
152
|
+
if (s !== 'true' && s !== 'false')
|
|
153
|
+
fail('E_CANON_TYPE', 'boolean must be true or false', at(p.name));
|
|
154
|
+
args[p.name] = { type, value: s === 'true' };
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
checkTypedValue(type, s, at(p.name));
|
|
158
|
+
args[p.name] = { type, value: s };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// 7. asof.
|
|
162
|
+
const ref = { args, fn, ns };
|
|
163
|
+
const asofParam = params.find((p) => p.name === 'asof');
|
|
164
|
+
if (asofParam) {
|
|
165
|
+
const s = decodeValue(asofParam.value, at('asof'));
|
|
166
|
+
checkInstant(s, at('asof'));
|
|
167
|
+
ref.asof = s;
|
|
168
|
+
}
|
|
169
|
+
return ref;
|
|
170
|
+
}
|
|
171
|
+
/** Write the unique cell URI of a cell reference (SPEC 5.2). Throws DatumeshError if invalid. */
|
|
172
|
+
export function formatUri(ref) {
|
|
173
|
+
const v = toJson(ref);
|
|
174
|
+
validate(v, 'ref');
|
|
175
|
+
const o = v;
|
|
176
|
+
const args = o.args;
|
|
177
|
+
const parts = [];
|
|
178
|
+
for (const k of sortedKeys(args)) {
|
|
179
|
+
const a = args[k];
|
|
180
|
+
if (a === '*')
|
|
181
|
+
parts.push(`${k}=*`);
|
|
182
|
+
else if (isObject(a) && typeof a.value === 'boolean')
|
|
183
|
+
parts.push(`${k}=${a.value ? 'true' : 'false'}`);
|
|
184
|
+
else
|
|
185
|
+
parts.push(`${k}=${encodeValue(a.value)}`);
|
|
186
|
+
}
|
|
187
|
+
if (typeof o.asof === 'string')
|
|
188
|
+
parts.push(`asof=${encodeValue(o.asof)}`);
|
|
189
|
+
return `${SCHEME}${o.ns}/${o.fn}${parts.length ? `?${parts.join('&')}` : ''}`;
|
|
190
|
+
}
|
|
191
|
+
/** The HTTPS URL of a cell URI on mesh host `mesh` (SPEC 5.3). */
|
|
192
|
+
export function httpsUrl(uri, mesh) {
|
|
193
|
+
if (!uri.startsWith(SCHEME))
|
|
194
|
+
fail('E_PARSE_URI', 'not a cell URI', '$');
|
|
195
|
+
return `https://${mesh}/cell/${uri.slice(SCHEME.length)}`;
|
|
196
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Encode a well-formed string as UTF-8. Lone surrogates must have been rejected already. */
|
|
2
|
+
export declare function utf8Encode(s: string): Uint8Array;
|
|
3
|
+
/** Number of UTF-8 bytes in a well-formed string. */
|
|
4
|
+
export declare function utf8Length(s: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* Decode strict UTF-8 (RFC 3629): no overlong forms, no surrogates, nothing above U+10FFFF,
|
|
7
|
+
* no truncated sequences. Returns null when the bytes are not UTF-8. A leading BOM is kept
|
|
8
|
+
* (as U+FEFF) so the caller can reject it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function utf8Decode(b: Uint8Array): string | null;
|
package/dist/esm/utf8.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Strict UTF-8 encoding and decoding, written out so results never depend on the host's
|
|
2
|
+
// TextDecoder (BOM handling, replacement characters) or its ICU build.
|
|
3
|
+
/** Encode a well-formed string as UTF-8. Lone surrogates must have been rejected already. */
|
|
4
|
+
export function utf8Encode(s) {
|
|
5
|
+
const out = [];
|
|
6
|
+
for (let i = 0; i < s.length; i++) {
|
|
7
|
+
let c = s.charCodeAt(i);
|
|
8
|
+
if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
9
|
+
const d = s.charCodeAt(i + 1);
|
|
10
|
+
if (d >= 0xdc00 && d <= 0xdfff) {
|
|
11
|
+
c = 0x10000 + ((c - 0xd800) << 10) + (d - 0xdc00);
|
|
12
|
+
i++;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (c < 0x80)
|
|
16
|
+
out.push(c);
|
|
17
|
+
else if (c < 0x800)
|
|
18
|
+
out.push(0xc0 | (c >> 6), 0x80 | (c & 63));
|
|
19
|
+
else if (c < 0x10000)
|
|
20
|
+
out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));
|
|
21
|
+
else
|
|
22
|
+
out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 63), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));
|
|
23
|
+
}
|
|
24
|
+
return Uint8Array.from(out);
|
|
25
|
+
}
|
|
26
|
+
/** Number of UTF-8 bytes in a well-formed string. */
|
|
27
|
+
export function utf8Length(s) {
|
|
28
|
+
let n = 0;
|
|
29
|
+
for (let i = 0; i < s.length; i++) {
|
|
30
|
+
const c = s.charCodeAt(i);
|
|
31
|
+
if (c < 0x80)
|
|
32
|
+
n += 1;
|
|
33
|
+
else if (c < 0x800)
|
|
34
|
+
n += 2;
|
|
35
|
+
else if (c >= 0xd800 && c <= 0xdbff) {
|
|
36
|
+
n += 4;
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
else
|
|
40
|
+
n += 3;
|
|
41
|
+
}
|
|
42
|
+
return n;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Decode strict UTF-8 (RFC 3629): no overlong forms, no surrogates, nothing above U+10FFFF,
|
|
46
|
+
* no truncated sequences. Returns null when the bytes are not UTF-8. A leading BOM is kept
|
|
47
|
+
* (as U+FEFF) so the caller can reject it.
|
|
48
|
+
*/
|
|
49
|
+
export function utf8Decode(b) {
|
|
50
|
+
let out = '';
|
|
51
|
+
const parts = [];
|
|
52
|
+
for (let i = 0; i < b.length;) {
|
|
53
|
+
const x = b[i];
|
|
54
|
+
let cp;
|
|
55
|
+
let need;
|
|
56
|
+
let min;
|
|
57
|
+
if (x < 0x80) {
|
|
58
|
+
cp = x;
|
|
59
|
+
need = 0;
|
|
60
|
+
min = 0;
|
|
61
|
+
}
|
|
62
|
+
else if (x >= 0xc2 && x <= 0xdf) {
|
|
63
|
+
cp = x & 0x1f;
|
|
64
|
+
need = 1;
|
|
65
|
+
min = 0x80;
|
|
66
|
+
}
|
|
67
|
+
else if (x >= 0xe0 && x <= 0xef) {
|
|
68
|
+
cp = x & 0x0f;
|
|
69
|
+
need = 2;
|
|
70
|
+
min = 0x800;
|
|
71
|
+
}
|
|
72
|
+
else if (x >= 0xf0 && x <= 0xf4) {
|
|
73
|
+
cp = x & 0x07;
|
|
74
|
+
need = 3;
|
|
75
|
+
min = 0x10000;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
return null;
|
|
79
|
+
for (let k = 1; k <= need; k++) {
|
|
80
|
+
const y = b[i + k];
|
|
81
|
+
if (y === undefined || (y & 0xc0) !== 0x80)
|
|
82
|
+
return null;
|
|
83
|
+
cp = (cp << 6) | (y & 0x3f);
|
|
84
|
+
}
|
|
85
|
+
if (cp < min || cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff))
|
|
86
|
+
return null;
|
|
87
|
+
out += String.fromCodePoint(cp);
|
|
88
|
+
if (out.length > 8192) {
|
|
89
|
+
parts.push(out);
|
|
90
|
+
out = '';
|
|
91
|
+
}
|
|
92
|
+
i += need + 1;
|
|
93
|
+
}
|
|
94
|
+
parts.push(out);
|
|
95
|
+
return parts.join('');
|
|
96
|
+
}
|