From cd8d31a730a14d22f2801ef3563204f72257b313 Mon Sep 17 00:00:00 2001 From: Tim Bray Date: Wed, 28 Aug 2024 14:20:39 -0700 Subject: [PATCH] numbits+base128 8-byte full-precision numbers (#349) * numbits+base128 8-byte full-precision numbers Signed-off-by: Tim Bray * fix up comments and README Signed-off-by: Tim Bray * make UTF-8 version of numbits variable-length Signed-off-by: Tim Bray * Address feedback from Arne, rewrite varwidth numbits Signed-off-by: Tim Bray * fix lint, use latest numbits.go Signed-off-by: Tim Bray --------- Signed-off-by: Tim Bray --- PATTERNS.md | 12 +- README.md | 5 +- case_folding.go | 942 +++++++++++++++++++++++------------------------ core_matcher.go | 8 +- flatten_json.go | 67 ++-- flattener.go | 2 +- numbers.go | 113 ++---- numbers_test.go | 125 ++++--- numbits.go | 58 +++ numbits_test.go | 71 ++++ quamina.go | 3 +- value_matcher.go | 53 +-- 12 files changed, 756 insertions(+), 703 deletions(-) create mode 100644 numbits.go create mode 100644 numbits_test.go diff --git a/PATTERNS.md b/PATTERNS.md index 81cf81d..efa5e8b 100644 --- a/PATTERNS.md +++ b/PATTERNS.md @@ -58,16 +58,8 @@ Thus, the following Pattern would match both JSON events above: ### Numeric Values -It would be convenient if Quamina knew, for matching purposes, that 35, -35.00, and 3.5e1 were all the same number. - -In many cases, Quamina can manage this. Specifically, for numbers that: - -* are between -5.0e9 and 5.0e9 inclusive. -* have five or fewer fractional digits. - -Numbers which do not meet these criteria will be treated as strings, which -usually produces good results. +Quamina can match numeric values with precision and range exactly the same as that provided by +Go's `float64` data type, which is said to conform to IEE 754 `binary64`. ## Extended Patterns An **Extended Pattern** **MUST** be a JSON object containing diff --git a/README.md b/README.md index f190749..8c3469d 100644 --- a/README.md +++ b/README.md @@ -150,9 +150,6 @@ The `"exists":true` and `"exists":false` patterns have corner cases; details are covered in [Patterns in Quamina](PATTERNS.md). -Quamina can match numeric values correctly, subject to -certain limits; details are in [Patterns in Quamina](PATTERNS.md). - ## Flattening and Matching The first step in finding matches for an Event is @@ -386,3 +383,5 @@ colonies before slavery was abolished. @embano1: CI/CD and project structure. @yosiat: Flattening optimization. + +@arnehormann: compact high-precision number representation. diff --git a/case_folding.go b/case_folding.go index 489dd4b..5715b7a 100644 --- a/case_folding.go +++ b/case_folding.go @@ -3,475 +3,475 @@ package quamina // Code generated by code_gen/code_gen - DO NOT EDIT. // built from the "C" records in CaseFolding.txt in the Unicode character database var caseFoldingPairs = map[rune]rune{ - 0x01A3: 0x01A2, 0x03DC: 0x03DD, 0xABA5: 0x13D5, 0x118D9: 0x118B9, 0x1E921: 0x1E943, 0x00FD: 0x00DD, - 0x0172: 0x0173, 0x0198: 0x0199, 0x1E0C: 0x1E0D, 0x2C3E: 0x2C0E, 0x0456: 0x0406, 0x044C: 0x042C, - 0x1CBE: 0x10FE, 0x2D08: 0x10A8, 0x1E20: 0x1E21, 0x1E67: 0x1E66, 0x1EFD: 0x1EFC, 0x1FF8: 0x1F78, - 0x00FF: 0x0178, 0x01F1: 0x01F3, 0x0248: 0x0249, 0xABBE: 0x13EE, 0x2C19: 0x2C49, 0xA76A: 0xA76B, - 0xA7A4: 0xA7A5, 0x10BE: 0x2D1E, 0x13F0: 0x13F8, 0x1F20: 0x1F28, 0x1F67: 0x1F6F, 0x2CA9: 0x2CA8, - 0x0454: 0x0404, 0x0460: 0x0461, 0x0479: 0x0478, 0x13D3: 0xABA3, 0xFF31: 0xFF51, 0x118D5: 0x118B5, - 0x03A9: 0x03C9, 0x0563: 0x0533, 0x10E4: 0x1CA4, 0x1EC1: 0x1EC0, 0x2C04: 0x2C34, 0x0150: 0x0151, - 0x01CD: 0x01CE, 0x021C: 0x021D, 0x16E4B: 0x16E6B, 0x1F0E: 0x1F06, 0x1F1C: 0x1F14, 0x24DD: 0x24C3, - 0xAB72: 0x13A2, 0xABA3: 0x13D3, 0x01A5: 0x01A4, 0x057F: 0x054F, 0x1EAC: 0x1EAD, 0x10426: 0x1044E, - 0x16E43: 0x16E63, 0x1F43: 0x1F4B, 0x217C: 0x216C, 0xA796: 0xA797, 0x16E6B: 0x16E4B, 0x04CF: 0x04C0, - 0x0510: 0x0511, 0xA68C: 0xA68D, 0x0526: 0x0527, 0x0230: 0x0231, 0x0466: 0x0467, 0x1CB1: 0x10F1, - 0x13B2: 0xAB82, 0x13DF: 0xABAF, 0x004B: 0x006B, 0x011D: 0x011C, 0x01A8: 0x01A7, 0x10CEF: 0x10CAF, - 0x04F2: 0x04F3, 0x2CD0: 0x2CD1, 0x2CF3: 0x2CF2, 0xAB8A: 0x13BA, 0x13C5: 0xAB95, 0xFF39: 0xFF59, - 0x0471: 0x0470, 0x2D17: 0x10B7, 0x2C26: 0x2C56, 0x1E6B: 0x1E6A, 0x1EEA: 0x1EEB, 0x0078: 0x0058, - 0x043F: 0x041F, 0x050E: 0x050F, 0xA655: 0xA654, 0xA7C6: 0x1D8E, 0x105BB: 0x10594, 0x0127: 0x0126, - 0x0154: 0x0155, 0x0160: 0x0161, 0x2CE0: 0x2CE1, 0x00C7: 0x00E7, 0x00F4: 0x00D4, 0x0518: 0x0519, - 0x10CE2: 0x10CA2, 0xA797: 0xA796, 0x00E2: 0x00C2, 0x04B5: 0x04B4, 0x04D4: 0x04D5, 0x1E83: 0x1E82, - 0x1F49: 0x1F41, 0x24E7: 0x24CD, 0x13A1: 0xAB71, 0xFF41: 0xFF21, 0x0110: 0x0111, 0x028B: 0x01B2, - 0x2D06: 0x10A6, 0x10442: 0x1041A, 0x10BA: 0x2D1A, 0x1F66: 0x1F6E, 0x1042D: 0x10405, 0x10CC8: 0x10C88, - 0x16E6F: 0x16E4F, 0x0269: 0x0196, 0x0426: 0x0446, 0x04A1: 0x04A0, 0x2CBD: 0x2CBC, 0xA689: 0xA688, - 0xFF22: 0xFF42, 0x1E92E: 0x1E90C, 0x0197: 0x0268, 0x1E7B: 0x1E7A, 0x1F6F: 0x1F67, 0x2CD9: 0x2CD8, - 0x13A3: 0xAB73, 0xFF43: 0xFF23, 0x1057A: 0x105A1, 0x118A6: 0x118C6, 0x03E7: 0x03E6, 0x1E81: 0x1E80, - 0x2C4F: 0x2C1F, 0x118CC: 0x118AC, 0x1E25: 0x1E24, 0x1E7E: 0x1E7F, 0x2CE2: 0x2CE3, 0x03AD: 0x0388, - 0x04E3: 0x04E2, 0x1C94: 0x10D4, 0x10CEB: 0x10CAB, 0x16E77: 0x16E57, 0x13FC: 0x13F4, 0x1F2C: 0x1F24, - 0x1FC9: 0x1F73, 0xFF2D: 0xFF4D, 0x04B3: 0x04B2, 0x2C49: 0x2C19, 0x2CB2: 0x2CB3, 0x2168: 0x2178, - 0x2C8A: 0x2C8B, 0x0059: 0x0079, 0x03DD: 0x03DC, 0x1FCB: 0x1F75, 0x0265: 0xA78D, 0x10B6: 0x2D16, - 0x10F2: 0x1CB2, 0x1CB4: 0x10F4, 0x1ED4: 0x1ED5, 0x104BB: 0x104E3, 0x10CC0: 0x10C80, 0x049A: 0x049B, - 0x0521: 0x0520, 0x1EB5: 0x1EB4, 0xA7B1: 0x0287, 0x104BA: 0x104E2, 0xA763: 0xA762, 0xA76C: 0xA76D, - 0x1E90D: 0x1E92F, 0x1E91C: 0x1E93E, 0x0136: 0x0137, 0x0401: 0x0451, 0x2C8F: 0x2C8E, 0x1E71: 0x1E70, - 0x104E1: 0x104B9, 0x10C8F: 0x10CCF, 0x01EF: 0x01EE, 0x1F44: 0x1F4C, 0xAB7B: 0x13AB, 0x2CD7: 0x2CD6, - 0x03E9: 0x03E8, 0x1CA6: 0x10E6, 0x2C0B: 0x2C3B, 0x1E35: 0x1E34, 0x1E51: 0x1E50, 0x1E900: 0x1E922, - 0x013C: 0x013B, 0x015D: 0x015C, 0x050B: 0x050A, 0x1EBB: 0x1EBA, 0x24E1: 0x24C7, 0xA758: 0xA759, - 0xFF47: 0xFF27, 0x10C86: 0x10CC6, 0x03E3: 0x03E2, 0x0418: 0x0438, 0x04CA: 0x04C9, 0x1E91E: 0x1E940, - 0x1F74: 0x1FCA, 0x216F: 0x217F, 0xFF35: 0xFF55, 0x024C: 0x024D, 0x2D0C: 0x10AC, 0x2D1E: 0x10BE, - 0x118A7: 0x118C7, 0x1E906: 0x1E928, 0x0388: 0x03AD, 0x0571: 0x0541, 0x1EBE: 0x1EBF, 0xA642: 0xA643, - 0x029D: 0xA7B2, 0x10411: 0x10439, 0x16E7C: 0x16E5C, 0x0041: 0x0061, 0x03DA: 0x03DB, 0x056C: 0x053C, - 0x24D4: 0x24BA, 0x10415: 0x1043D, 0x1E3D: 0x1E3C, 0x1E46: 0x1E47, 0x1E5C: 0x1E5D, 0x2C1D: 0x2C4D, - 0x2C93: 0x2C92, 0x0283: 0x01A9, 0x0406: 0x0456, 0x0492: 0x0493, 0x10CE6: 0x10CA6, 0x10CA7: 0x10CE7, - 0x2CA8: 0x2CA9, 0xA74E: 0xA74F, 0x10421: 0x10449, 0x10588: 0x105AF, 0x04CE: 0x04CD, 0x2C40: 0x2C10, - 0x13A6: 0xAB76, 0x03FF: 0x037D, 0x24CA: 0x24E4, 0x216E: 0x217E, 0xA690: 0xA691, 0x16E5F: 0x16E7F, - 0x0462: 0x0463, 0x0504: 0x0505, 0x2D1F: 0x10BF, 0x054A: 0x057A, 0x1E73: 0x1E72, 0x1F12: 0x1F1A, - 0x0047: 0x0067, 0x01B0: 0x01AF, 0x04EE: 0x04EF, 0x2C2C: 0x2C5C, 0x2CC9: 0x2CC8, 0x01E2: 0x01E3, - 0x024A: 0x024B, 0x057B: 0x054B, 0x1E01: 0x1E00, 0x2C6D: 0x0251, 0x010D: 0x010C, 0x0441: 0x0421, - 0x1CAF: 0x10EF, 0x1F2D: 0x1F25, 0x0240: 0x2C7F, 0x04F7: 0x04F6, 0x1E28: 0x1E29, 0x1E8F: 0x1E8E, - 0x1D79: 0xA77D, 0xABA4: 0x13D4, 0x10571: 0x10598, 0x16E55: 0x16E75, 0x0499: 0x0498, 0x1EF2: 0x1EF3, - 0xA698: 0xA699, 0x1F7A: 0x1FEA, 0xAB97: 0x13C7, 0x1E939: 0x1E917, 0x00ED: 0x00CD, 0x043A: 0x041A, - 0x1EEF: 0x1EEE, 0x1EF3: 0x1EF2, 0x1F4B: 0x1F43, 0x2C99: 0x2C98, 0xAB74: 0x13A4, 0x1E932: 0x1E910, - 0x0289: 0x0244, 0x052E: 0x052F, 0x0575: 0x0545, 0x2C37: 0x2C07, 0x2C69: 0x2C6A, 0x0271: 0x2C6E, - 0x10574: 0x1059B, 0x00EC: 0x00CC, 0x04A0: 0x04A1, 0x1CB7: 0x10F7, 0x1FB1: 0x1FB9, 0x13A2: 0xAB72, - 0x0432: 0x0412, 0x10AC: 0x2D0C, 0x1F72: 0x1FC8, 0x041F: 0x043F, 0x13EC: 0xABBC, 0xA695: 0xA694, - 0xFF52: 0xFF32, 0x0194: 0x0263, 0x045F: 0x040F, 0x051D: 0x051C, 0x0570: 0x0540, 0x1ED5: 0x1ED4, - 0x16E72: 0x16E52, 0x04ED: 0x04EC, 0x0537: 0x0567, 0x0569: 0x0539, 0x16E69: 0x16E49, 0x00DC: 0x00FC, - 0x0522: 0x0523, 0x1F04: 0x1F0C, 0x1E919: 0x1E93B, 0x04A5: 0x04A4, 0x2D1A: 0x10BA, 0x1042E: 0x10406, - 0x118DA: 0x118BA, 0x04F1: 0x04F0, 0x2C47: 0x2C17, 0x104C3: 0x104EB, 0x13C7: 0xAB97, 0x04CD: 0x04CE, - 0x10B1: 0x2D11, 0x1F57: 0x1F5F, 0x0564: 0x0534, 0x1E42: 0x1E43, 0x2C03: 0x2C33, 0x0163: 0x0162, - 0x0402: 0x0452, 0x0496: 0x0497, 0x105B7: 0x10590, 0x1E904: 0x1E926, 0x03C3: 0x03A3, 0x1F2B: 0x1F23, - 0x24C1: 0x24DB, 0x2CC6: 0x2CC7, 0x104F8: 0x104D0, 0x0245: 0x028C, 0x0512: 0x0513, 0x1F4A: 0x1F42, - 0x13F1: 0x13F9, 0x1CB6: 0x10F6, 0x1E16: 0x1E17, 0x24CB: 0x24E5, 0x2C36: 0x2C06, 0x0128: 0x0129, - 0x018F: 0x0259, 0x0461: 0x0460, 0x104EA: 0x104C2, 0x0511: 0x0510, 0x1E8E: 0x1E8F, 0x021F: 0x021E, - 0x0544: 0x0574, 0x04E2: 0x04E3, 0x1EAE: 0x1EAF, 0x2CCB: 0x2CCA, 0x0527: 0x0526, 0x0579: 0x0549, - 0x2C95: 0x2C94, 0x1F7B: 0x1FEB, 0xA643: 0xA642, 0x118BF: 0x118DF, 0x00C4: 0x00E4, 0x0212: 0x0213, - 0x1E6F: 0x1E6E, 0xA73E: 0xA73F, 0x13DB: 0xABAB, 0x10C96: 0x10CD6, 0x118CA: 0x118AA, 0x004F: 0x006F, - 0x00D9: 0x00F9, 0x040D: 0x045D, 0x2CD4: 0x2CD5, 0x1041E: 0x10446, 0x1E929: 0x1E907, 0x00E3: 0x00C3, - 0x0548: 0x0578, 0x2CB5: 0x2CB4, 0xA74C: 0xA74D, 0x016D: 0x016C, 0x01F7: 0x01BF, 0x1C99: 0x10D9, - 0x1E7A: 0x1E7B, 0x24D7: 0x24BD, 0xA729: 0xA728, 0x104D8: 0x104B0, 0x1E902: 0x1E924, 0x00E8: 0x00C8, - 0x0144: 0x0143, 0x03CE: 0x038F, 0x24C7: 0x24E1, 0x10423: 0x1044B, 0x105AE: 0x10587, 0x017C: 0x017B, - 0x01C7: 0x01C9, 0x01F4: 0x01F5, 0x0045: 0x0065, 0xAB9B: 0x13CB, 0x10C82: 0x10CC2, 0x1E06: 0x1E07, - 0x00EA: 0x00CA, 0x045C: 0x040C, 0x04F9: 0x04F8, 0x10447: 0x1041F, 0x00E4: 0x00C4, 0x0148: 0x0147, - 0x13A9: 0xAB79, 0x03A5: 0x03C5, 0x0468: 0x0469, 0x13F8: 0x13F0, 0x1E2D: 0x1E2C, 0x1F28: 0x1F20, - 0x0121: 0x0120, 0x01A6: 0x0280, 0x0207: 0x0206, 0x118C8: 0x118A8, 0x1E937: 0x1E915, 0x10587: 0x105AE, - 0x053F: 0x056F, 0xA73D: 0xA73C, 0xA746: 0xA747, 0x10C5: 0x2D25, 0xA77B: 0xA77C, 0x0399: 0x03B9, - 0x04BC: 0x04BD, 0x0568: 0x0538, 0x2C73: 0x2C72, 0x1059F: 0x10578, 0x0472: 0x0473, 0x1C9B: 0x10DB, - 0x1F32: 0x1F3A, 0x10CA0: 0x10CE0, 0x01B9: 0x01B8, 0x1E63: 0x1E62, 0x026B: 0x2C62, 0x039D: 0x03BD, - 0x10A6: 0x2D06, 0x1CA4: 0x10E4, 0x2C23: 0x2C53, 0x2CDD: 0x2CDC, 0xA697: 0xA696, 0xFF2F: 0xFF4F, - 0x1044A: 0x10422, 0x0189: 0x0256, 0x10FA: 0x1CBA, 0x2175: 0x2165, 0x104F1: 0x104C9, 0x01E0: 0x01E1, - 0xA799: 0xA798, 0x1043C: 0x10414, 0xA65C: 0xA65D, 0xA68B: 0xA68A, 0xA72A: 0xA72B, 0x1E54: 0x1E55, - 0x1E79: 0x1E78, 0xA646: 0xA647, 0x10C84: 0x10CC4, 0x01E8: 0x01E9, 0x1FE1: 0x1FE9, 0x104C9: 0x104F1, - 0x1E5F: 0x1E5E, 0x01DA: 0x01D9, 0x03D9: 0x03D8, 0x10DB: 0x1C9B, 0x1E18: 0x1E19, 0x1EAD: 0x1EAC, - 0x24DC: 0x24C2, 0xA77C: 0xA77B, 0x104F4: 0x104CC, 0x01A1: 0x01A0, 0x04BB: 0x04BA, 0x1CB8: 0x10F8, - 0x105A0: 0x10579, 0x03C9: 0x03A9, 0x1E26: 0x1E27, 0x1F11: 0x1F19, 0xA72E: 0xA72F, 0x10C8E: 0x10CCE, - 0x00F3: 0x00D3, 0x01AD: 0x01AC, 0x01CA: 0x01CC, 0x1E931: 0x1E90F, 0xA73A: 0xA73B, 0xABB5: 0x13E5, - 0x1C80: 0x0432, 0x1E69: 0x1E68, 0x1E70: 0x1E71, 0x2C12: 0x2C42, 0xA753: 0xA752, 0x10CAB: 0x10CEB, - 0x03E8: 0x03E9, 0x0413: 0x0433, 0x2D1B: 0x10BB, 0x1EBD: 0x1EBC, 0x10589: 0x105B0, 0x00D2: 0x00F2, - 0x04E4: 0x04E5, 0x1C93: 0x10D3, 0x04A2: 0x04A3, 0x050A: 0x050B, 0x10C0: 0x2D20, 0x1EEE: 0x1EEF, - 0x2C72: 0x2C73, 0x0288: 0x01AE, 0x022F: 0x022E, 0x0473: 0x0472, 0x1059E: 0x10577, 0x2C98: 0x2C99, - 0x13D9: 0xABA9, 0x10430: 0x10408, 0x10B0: 0x2D10, 0x1F2E: 0x1F26, 0x1F75: 0x1FCB, 0x10585: 0x105AC, - 0x0451: 0x0401, 0x0435: 0x0415, 0x054B: 0x057B, 0x03EB: 0x03EA, 0x2D18: 0x10B8, 0x10E9: 0x1CA9, - 0x1EB3: 0x1EB2, 0x2C09: 0x2C39, 0x0137: 0x0136, 0x0170: 0x0171, 0x03A4: 0x03C4, 0xABBC: 0x13EC, - 0x1F6C: 0x1F64, 0x16E58: 0x16E78, 0x1E90F: 0x1E931, 0x03BE: 0x039E, 0x10CCE: 0x10C8E, 0x16E73: 0x16E53, - 0x2C7E: 0x023F, 0xAB89: 0x13B9, 0x13C6: 0xAB96, 0xFF3A: 0xFF5A, 0x04AE: 0x04AF, 0x1F4C: 0x1F44, - 0x2C25: 0x2C55, 0x1FD0: 0x1FD8, 0x13DD: 0xABAD, 0x10599: 0x10572, 0x105B5: 0x1058E, 0x011F: 0x011E, - 0x038C: 0x03CC, 0x1E4B: 0x1E4A, 0x2C43: 0x2C13, 0xA79E: 0xA79F, 0xFF4F: 0xFF2F, 0x104DA: 0x104B2, - 0x104E7: 0x104BF, 0x039C: 0x03BC, 0x0442: 0x0422, 0x1E02: 0x1E03, 0x16E60: 0x16E40, 0x16E45: 0x16E65, - 0x105A1: 0x1057A, 0x10CA3: 0x10CE3, 0x1CBD: 0x10FD, 0x1E1D: 0x1E1C, 0xAB9C: 0x13CC, 0x24E8: 0x24CE, - 0xA735: 0xA734, 0x1ECB: 0x1ECA, 0x216D: 0x217D, 0x1E93B: 0x1E919, 0x019C: 0x026F, 0x03D8: 0x03D9, - 0x10A1: 0x2D01, 0x020B: 0x020A, 0xA68D: 0xA68C, 0x104DB: 0x104B3, 0x1CAB: 0x10EB, 0xA73C: 0xA73D, - 0xA75D: 0xA75C, 0x0282: 0xA7C5, 0x104F7: 0x104CF, 0x0166: 0x0167, 0x041D: 0x043D, 0x04A8: 0x04A9, - 0x1F76: 0x1FDA, 0x2C5E: 0x2C2E, 0xA683: 0xA682, 0x16E52: 0x16E72, 0x0101: 0x0100, 0x0436: 0x0416, - 0x1F08: 0x1F00, 0x017A: 0x0179, 0xA64C: 0xA64D, 0xA79B: 0xA79A, 0x1E07: 0x1E06, 0x1EDB: 0x1EDA, - 0x16E56: 0x16E76, 0x00EE: 0x00CE, 0x022D: 0x022C, 0x03C8: 0x03A8, 0x13EB: 0xABBB, 0x10CD7: 0x10C97, - 0x10C9D: 0x10CDD, 0x10CEA: 0x10CAA, 0x00E9: 0x00C9, 0x0445: 0x0425, 0x053B: 0x056B, 0x2C91: 0x2C90, - 0x13AB: 0xAB7B, 0x13E4: 0xABB4, 0xFF4B: 0xFF2B, 0x104B9: 0x104E1, 0x0133: 0x0132, 0x0534: 0x0564, - 0x2C80: 0x2C81, 0x118D3: 0x118B3, 0x13F9: 0x13F1, 0x1F29: 0x1F21, 0x1F30: 0x1F38, 0x2C5A: 0x2C2A, - 0x2CA0: 0x2CA1, 0x00FB: 0x00DB, 0x0469: 0x0468, 0x10C3: 0x2D23, 0x104D2: 0x104FA, 0xA668: 0xA669, - 0xAB9A: 0x13CA, 0xFF21: 0xFF41, 0x105AA: 0x10583, 0x1EBF: 0x1EBE, 0xA72C: 0xA72D, 0x10433: 0x1040B, - 0xA666: 0xA667, 0x104C4: 0x104EC, 0x03AA: 0x03CA, 0x0552: 0x0582, 0x1F07: 0x1F0F, 0x2C9E: 0x2C9F, - 0x13E0: 0xABB0, 0x10CE5: 0x10CA5, 0x10CAF: 0x10CEF, 0x1E901: 0x1E923, 0x007A: 0x005A, 0x0577: 0x0547, - 0x1EE8: 0x1EE9, 0x1EDF: 0x1EDE, 0x00DD: 0x00FD, 0x0409: 0x0459, 0x1EB2: 0x1EB3, 0x10432: 0x1040A, - 0x04C5: 0x04C6, 0x1C98: 0x10D8, 0x1CA3: 0x10E3, 0x10CD8: 0x10C98, 0x118A0: 0x118C0, 0x0062: 0x0042, - 0x1E9B: 0x1E61, 0x1EC5: 0x1EC4, 0x1E85: 0x1E84, 0x015B: 0x015A, 0x04C2: 0x04C1, 0x050D: 0x050C, - 0x1E5A: 0x1E5B, 0x1F10: 0x1F18, 0x24BE: 0x24D8, 0xA757: 0xA756, 0x1E911: 0x1E933, 0x00D1: 0x00F1, - 0x01F6: 0x0195, 0x0417: 0x0437, 0x023F: 0x2C7E, 0x13D0: 0xABA0, 0x10424: 0x1044C, 0x10586: 0x105AD, - 0x0102: 0x0103, 0x0463: 0x0462, 0x1F23: 0x1F2B, 0x24E3: 0x24C9, 0x2CB0: 0x2CB1, 0x1043D: 0x10415, - 0x2CEB: 0x2CEC, 0x0459: 0x0409, 0x04FC: 0x04FD, 0x2C6A: 0x2C69, 0xAB82: 0x13B2, 0x13DE: 0xABAE, - 0x0252: 0x2C70, 0xA73B: 0xA73A, 0xA78D: 0x0265, 0x2D23: 0x10C3, 0x1E7F: 0x1E7E, 0x104BF: 0x104E7, - 0x01F2: 0x01F3, 0x03B5: 0x0395, 0x042B: 0x044B, 0x1F36: 0x1F3E, 0x2C21: 0x2C51, 0xFF5A: 0xFF3A, - 0x0220: 0x019E, 0x0476: 0x0477, 0x1E48: 0x1E49, 0x014C: 0x014D, 0x0405: 0x0455, 0x1EFA: 0x1EFB, - 0x13C3: 0xAB93, 0x0389: 0x03AE, 0x03FB: 0x03FA, 0x1F53: 0x1F5B, 0x0107: 0x0106, 0x1CB9: 0x10F9, - 0x2C20: 0x2C50, 0x00C8: 0x00E8, 0x217D: 0x216D, 0x1059A: 0x10573, 0x13CF: 0xAB9F, 0x0058: 0x0078, - 0x1F5F: 0x1F57, 0x2169: 0x2179, 0xA64E: 0xA64F, 0xA754: 0xA755, 0x039B: 0x03BB, 0x03C5: 0x03A5, - 0x0414: 0x0434, 0x0064: 0x0044, 0x0050: 0x0070, 0x1F5B: 0x1F53, 0xA7BD: 0xA7BC, 0x10416: 0x1043E, - 0x10CCD: 0x10C8D, 0x10CA9: 0x10CE9, 0x00C9: 0x00E9, 0x03F3: 0x037F, 0x03D0: 0x03B2, 0x1040A: 0x10432, - 0x104EE: 0x104C6, 0x056B: 0x053B, 0x2CC0: 0x2CC1, 0xAB9D: 0x13CD, 0x1F6E: 0x1F66, 0x13C1: 0xAB91, - 0xFF59: 0xFF39, 0x042E: 0x044E, 0x0475: 0x0474, 0x1F35: 0x1F3D, 0x1FD9: 0x1FD1, 0x118BB: 0x118DB, - 0x04B1: 0x04B0, 0x10AA: 0x2D0A, 0x10CD: 0x2D2D, 0x1058A: 0x105B1, 0x10C95: 0x10CD5, 0x118AD: 0x118CD, - 0x16E70: 0x16E50, 0x1E907: 0x1E929, 0x0540: 0x0570, 0x1E52: 0x1E53, 0x24C4: 0x24DE, 0x1043F: 0x10417, - 0x1044E: 0x10426, 0xA7C3: 0xA7C2, 0x016F: 0x016E, 0x054C: 0x057C, 0x10EF: 0x1CAF, 0x2C22: 0x2C52, - 0x13D7: 0xABA7, 0x0423: 0x0443, 0x04DD: 0x04DC, 0x1EE5: 0x1EE4, 0x118B9: 0x118D9, 0x16E4D: 0x16E6D, - 0x01E7: 0x01E6, 0x1CAE: 0x10EE, 0x10FD: 0x1CBD, 0xABAB: 0x13DB, 0x011A: 0x011B, 0x01C8: 0x01C9, - 0x04FE: 0x04FF, 0x03EC: 0x03ED, 0xABBB: 0x13EB, 0x1E924: 0x1E902, 0x1E90C: 0x1E92E, 0x03B6: 0x0396, - 0x03F2: 0x03F9, 0x1FE9: 0x1FE1, 0x2C82: 0x2C83, 0x105B0: 0x10589, 0x16E40: 0x16E60, 0x0063: 0x0043, - 0x0292: 0x01B7, 0x1F09: 0x1F01, 0x0415: 0x0435, 0x24B9: 0x24D3, 0xA755: 0xA754, 0x014E: 0x014F, - 0x03C4: 0x03A4, 0x03F7: 0x03F8, 0x1F13: 0x1F1B, 0x24C9: 0x24E3, 0xFF2B: 0xFF4B, 0x118AF: 0x118CF, - 0x00F1: 0x00D1, 0x03B4: 0x0394, 0x1C82: 0x043E, 0x2D20: 0x10C0, 0xA77E: 0xA77F, 0x10435: 0x1040D, - 0x01D2: 0x01D1, 0x03F4: 0x03B8, 0x037C: 0x03FE, 0x040F: 0x045F, 0x0565: 0x0535, 0x1E4F: 0x1E4E, - 0x1ED9: 0x1ED8, 0x2C81: 0x2C80, 0x004D: 0x006D, 0x011B: 0x011A, 0x0280: 0x01A6, 0xABAA: 0x13DA, - 0x13D6: 0xABA6, 0x104C1: 0x104E9, 0x0233: 0x0232, 0x046F: 0x046E, 0x0505: 0x0504, 0xA66C: 0xA66D, - 0x1057C: 0x105A3, 0x118A8: 0x118C8, 0x1E50: 0x1E51, 0x1EAA: 0x1EAB, 0x1FC8: 0x1F72, 0x13B4: 0xAB84, - 0xAB9F: 0x13CF, 0x10449: 0x10421, 0x1057E: 0x105A5, 0x105BC: 0x10595, 0x10F1: 0x1CB1, 0x1EE7: 0x1EE6, - 0xA76B: 0xA76A, 0x16E7E: 0x16E5E, 0x1E90E: 0x1E930, 0x0549: 0x0579, 0x2CE1: 0x2CE0, 0x1042C: 0x10404, - 0xABA8: 0x13D8, 0x10407: 0x1042F, 0x104DE: 0x104B6, 0x0396: 0x03B6, 0x0452: 0x0402, 0x10AD: 0x2D0D, - 0xA688: 0xA689, 0x13EA: 0xABBA, 0x1E930: 0x1E90E, 0x0070: 0x0050, 0x053A: 0x056A, 0x1F03: 0x1F0B, - 0x1E3C: 0x1E3D, 0x1E5D: 0x1E5C, 0x13C8: 0xAB98, 0x0135: 0x0134, 0x016E: 0x016F, 0x0204: 0x0205, - 0x13DA: 0xABAA, 0x10C83: 0x10CC3, 0x118C6: 0x118A6, 0x118AC: 0x118CC, 0x0509: 0x0508, 0x2171: 0x2161, - 0x2CDC: 0x2CDD, 0xA790: 0xA791, 0x10CC1: 0x10C81, 0x04C3: 0x04C4, 0x0516: 0x0517, 0xA781: 0xA780, - 0x1E928: 0x1E906, 0x04CB: 0x04CC, 0x1EBA: 0x1EBB, 0xA7B7: 0xA7B6, 0xA75A: 0xA75B, 0xA7A0: 0xA7A1, - 0x118A4: 0x118C4, 0x041A: 0x043A, 0x1C95: 0x10D5, 0x24B6: 0x24D0, 0x10C9C: 0x10CDC, 0x0054: 0x0074, - 0x0480: 0x0481, 0x0491: 0x0490, 0x1E7C: 0x1E7D, 0x1EC7: 0x1EC6, 0x1EF4: 0x1EF5, 0xA7AD: 0x026C, - 0xAB73: 0x13A3, 0x0175: 0x0174, 0x0376: 0x0377, 0x0458: 0x0408, 0x10C80: 0x10CC0, 0x118C2: 0x118A2, - 0x1E914: 0x1E936, 0x0377: 0x0376, 0x03CC: 0x038C, 0x13E2: 0xABB2, 0x1C9C: 0x10DC, 0x1EFE: 0x1EFF, - 0xA749: 0xA748, 0xA7B2: 0x029D, 0x10448: 0x10420, 0x0157: 0x0156, 0x0523: 0x0522, 0x10B8: 0x2D18, - 0x13B3: 0xAB83, 0xFF54: 0xFF34, 0x104E0: 0x104B8, 0x0178: 0x00FF, 0x0431: 0x0411, 0x2D10: 0x10B0, - 0x1EFC: 0x1EFD, 0x01F5: 0x01F4, 0x03B2: 0x0392, 0x03DF: 0x03DE, 0x03A0: 0x03C0, 0x0573: 0x0543, - 0x1E4A: 0x1E4B, 0xA747: 0xA746, 0xABAF: 0x13DF, 0x0159: 0x0158, 0x0174: 0x0175, 0x01FC: 0x01FD, - 0xFF58: 0xFF38, 0x24D3: 0x24B9, 0xABAD: 0x13DD, 0x10436: 0x1040E, 0x004A: 0x006A, 0x00F5: 0x00D5, - 0x04E6: 0x04E7, 0xA7AC: 0x0261, 0x0209: 0x0208, 0x0438: 0x0418, 0x1E7D: 0x1E7C, 0x1E00: 0x1E01, - 0x10CA6: 0x10CE6, 0x10CE7: 0x10CA7, 0x0184: 0x0185, 0x10BF: 0x2D1F, 0xA7D8: 0xA7D9, 0x0574: 0x0544, - 0xAB75: 0x13A5, 0x13AA: 0xAB7A, 0x13CD: 0xAB9D, 0x104C8: 0x104F0, 0x105A6: 0x1057F, 0x1F3C: 0x1F34, - 0x1F5D: 0x1F55, 0x2CAC: 0x2CAD, 0x13FA: 0x13F2, 0x1F2A: 0x1F22, 0xAB99: 0x13C9, 0x104E9: 0x104C1, - 0x0225: 0x0224, 0x04A4: 0x04A5, 0x04EB: 0x04EA, 0x0567: 0x0537, 0x0539: 0x0569, 0x1EDE: 0x1EDF, - 0x2D0B: 0x10AB, 0x10E2: 0x1CA2, 0x1FFB: 0x1F7D, 0x1058F: 0x105B6, 0x10CAD: 0x10CED, 0x00CC: 0x00EC, - 0x0162: 0x0163, 0x057A: 0x054A, 0x1FB9: 0x1FB1, 0x104E4: 0x104BC, 0x01E5: 0x01E4, 0x04D1: 0x04D0, - 0x1EEC: 0x1EED, 0x10FF: 0x1CBF, 0x1E15: 0x1E14, 0x2163: 0x2173, 0x2C51: 0x2C21, 0xAB80: 0x13B0, - 0x038F: 0x03CE, 0x10D6: 0x1C96, 0x1CB5: 0x10F5, 0xFF2A: 0xFF4A, 0x10C9B: 0x10CDB, 0x1E92B: 0x1E909, - 0x01D0: 0x01CF, 0x057C: 0x054C, 0x104BE: 0x104E6, 0x1EE0: 0x1EE1, 0xA72B: 0xA72A, 0x13B9: 0xAB89, - 0x0222: 0x0223, 0x04AF: 0x04AE, 0x2C7F: 0x0240, 0xA734: 0xA735, 0x0216: 0x0217, 0x03C1: 0x03A1, - 0x1EA9: 0x1EA8, 0xA7D1: 0xA7D0, 0xAB76: 0x13A6, 0x1E905: 0x1E927, 0x2C86: 0x2C87, 0x013F: 0x0140, - 0x24CD: 0x24E7, 0x2C4B: 0x2C1B, 0xA793: 0xA792, 0xA7A8: 0xA7A9, 0x104EF: 0x104C7, 0x10583: 0x105AA, - 0x051F: 0x051E, 0x2D04: 0x10A4, 0x2C4E: 0x2C1E, 0x026F: 0x019C, 0x10F4: 0x1CB4, 0xA686: 0xA687, - 0x045B: 0x040B, 0x1E91: 0x1E90, 0xA66B: 0xA66A, 0x10CDF: 0x10C9F, 0x16E5A: 0x16E7A, 0x024F: 0x024E, - 0x2D0F: 0x10AF, 0x1E80: 0x1E81, 0x13AE: 0xAB7E, 0xFF4E: 0xFF2E, 0x0114: 0x0115, 0x0513: 0x0512, - 0x24B8: 0x24D2, 0x1ECC: 0x1ECD, 0x24DA: 0x24C0, 0x2C10: 0x2C40, 0xA77A: 0xA779, 0x01C5: 0x01C6, - 0x1E30: 0x1E31, 0x1E77: 0x1E76, 0x10C4: 0x2D24, 0x2126: 0x03C9, 0x105AC: 0x10585, 0x012F: 0x012E, - 0x0497: 0x0496, 0xA752: 0xA753, 0x1040C: 0x10434, 0x10CAA: 0x10CEA, 0x023B: 0x023C, 0x1E33: 0x1E32, - 0x2C13: 0x2C43, 0xA79A: 0xA79B, 0x1041D: 0x10445, 0x1F68: 0x1F60, 0xA745: 0xA744, 0x10406: 0x1042E, - 0x10CDC: 0x10C9C, 0x10CB2: 0x10CF2, 0x015E: 0x015F, 0x048F: 0x048E, 0x1EF7: 0x1EF6, 0x16E46: 0x16E66, - 0x13F5: 0x13FD, 0x10D1: 0x1C91, 0x1F25: 0x1F2D, 0xFF50: 0xFF30, 0x043E: 0x041E, 0x0465: 0x0464, - 0x050F: 0x050E, 0x118BE: 0x118DE, 0x10F0: 0x1CB0, 0x2166: 0x2176, 0x10CDB: 0x10C9B, 0xA780: 0xA781, - 0xA791: 0xA790, 0x10C97: 0x10CD7, 0x0066: 0x0046, 0x0203: 0x0202, 0x0551: 0x0581, 0x1CAA: 0x10EA, - 0x1FBA: 0x1F70, 0x2CDE: 0x2CDF, 0x1043E: 0x10416, 0x01E6: 0x01E7, 0x03E5: 0x03E4, 0x0519: 0x0518, - 0x2CCD: 0x2CCC, 0x13AC: 0xAB7C, 0xAB90: 0x13C0, 0x10592: 0x105B9, 0x118D2: 0x118B2, 0x047A: 0x047B, - 0x2C50: 0x2C20, 0x0251: 0x2C6D, 0x10CC5: 0x10C85, 0x053D: 0x056D, 0x16E76: 0x16E56, 0x24E6: 0x24CC, - 0x2CBF: 0x2CBE, 0x0247: 0x0246, 0x042D: 0x044D, 0x04D3: 0x04D2, 0xA769: 0xA768, 0x104B7: 0x104DF, - 0x00D5: 0x00F5, 0x03F1: 0x03C1, 0x1E3A: 0x1E3B, 0x118B3: 0x118D3, 0x03E4: 0x03E5, 0x1FDA: 0x1F76, - 0x2CBE: 0x2CBF, 0x2C48: 0x2C18, 0xA7AE: 0x026A, 0xABB4: 0x13E4, 0x012D: 0x012C, 0x0219: 0x0218, - 0x1EA6: 0x1EA7, 0x1E912: 0x1E934, 0x005A: 0x007A, 0x0524: 0x0525, 0x1ED1: 0x1ED0, 0xAB77: 0x13A7, - 0x004C: 0x006C, 0x1EC3: 0x1EC2, 0x2C85: 0x2C84, 0x044A: 0x042A, 0x04F5: 0x04F4, 0x104CC: 0x104F4, - 0x1E55: 0x1E54, 0x24CF: 0x24E9, 0x2C11: 0x2C41, 0x1E935: 0x1E913, 0x015C: 0x015D, 0x1C97: 0x10D7, - 0x1E31: 0x1E30, 0x1044C: 0x10424, 0x105B9: 0x10592, 0x10595: 0x105BC, 0x10C8A: 0x10CCA, 0x16E7F: 0x16E5F, - 0x0125: 0x0124, 0x03A1: 0x03C1, 0xA7BF: 0xA7BE, 0xA65D: 0xA65C, 0x10CC4: 0x10C84, 0x020C: 0x020D, - 0x1E34: 0x1E35, 0x2C14: 0x2C44, 0x1EB1: 0x1EB0, 0x1F0F: 0x1F07, 0x104CD: 0x104F5, 0x01BD: 0x01BC, - 0x0525: 0x0524, 0x057E: 0x054E, 0x1F00: 0x1F08, 0xA7F5: 0xA7F6, 0x10413: 0x1043B, 0x104C7: 0x104EF, - 0x04DB: 0x04DA, 0x2D2D: 0x10CD, 0x1E47: 0x1E46, 0x10E8: 0x1CA8, 0x13CE: 0xAB9E, 0xFF37: 0xFF57, - 0x1E90B: 0x1E92D, 0x0421: 0x0441, 0x04A6: 0x04A7, 0x2D19: 0x10B9, 0x1F60: 0x1F68, 0x1F79: 0x1FF9, - 0x13C4: 0xAB94, 0x104C5: 0x104ED, 0x16E79: 0x16E59, 0x0208: 0x0209, 0x04FD: 0x04FC, 0x1F27: 0x1F2F, - 0x105AF: 0x10588, 0x10C8D: 0x10CCD, 0x2D24: 0x10C4, 0x1F15: 0x1F1D, 0x24D1: 0x24B7, 0x2C2F: 0x2C5F, - 0x2C88: 0x2C89, 0x10C1: 0x2D21, 0x1F1B: 0x1F13, 0x216A: 0x217A, 0x10446: 0x1041E, 0x01DE: 0x01DF, - 0x24D2: 0x24B8, 0xAB7D: 0x13AD, 0x04B2: 0x04B3, 0x04F6: 0x04F7, 0x24E0: 0x24C6, 0x027D: 0x2C64, - 0x105B1: 0x1058A, 0x00E5: 0x00C5, 0x0117: 0x0116, 0x0449: 0x0429, 0x1E93E: 0x1E91C, 0x1E2B: 0x1E2A, - 0x2CAF: 0x2CAE, 0x1041B: 0x10443, 0x0223: 0x0222, 0x039A: 0x03BA, 0x047F: 0x047E, 0x04E0: 0x04E1, - 0x24DF: 0x24C5, 0xA650: 0xA651, 0xA741: 0xA740, 0x10CD3: 0x10C93, 0x013E: 0x013D, 0x051B: 0x051A, - 0x2C05: 0x2C35, 0x10CA2: 0x10CE2, 0x1E917: 0x1E939, 0x0139: 0x013A, 0x0167: 0x0166, 0xFF38: 0xFF58, - 0x1EEB: 0x1EEA, 0xA739: 0xA738, 0xABB6: 0x13E6, 0x2D25: 0x10C5, 0x1E6A: 0x1E6B, 0x1EA4: 0x1EA5, - 0x10BD: 0x2D1D, 0xA783: 0xA782, 0x16E53: 0x16E73, 0x04B0: 0x04B1, 0x1CA7: 0x10E7, 0x2CD6: 0x2CD7, - 0x0566: 0x0536, 0x24CC: 0x24E6, 0xA652: 0xA653, 0xA7D7: 0xA7D6, 0xABA9: 0x13D9, 0x0051: 0x0071, - 0x015F: 0x015E, 0x0494: 0x0495, 0x16E59: 0x16E79, 0x2D09: 0x10A9, 0x1E38: 0x1E39, 0x1FF9: 0x1F79, - 0x2C18: 0x2C48, 0x2CAD: 0x2CAC, 0x0249: 0x0248, 0x03E2: 0x03E3, 0x047D: 0x047C, 0x2CCA: 0x2CCB, - 0x2C29: 0x2C59, 0x13AD: 0xAB7D, 0xAB85: 0x13B5, 0x13CA: 0xAB9A, 0x10577: 0x1059E, 0x0584: 0x0554, - 0x1CB0: 0x10F0, 0x1E10: 0x1E11, 0x1E91A: 0x1E93C, 0x104E8: 0x104C0, 0x0536: 0x0566, 0x1EC2: 0x1EC3, - 0x13E6: 0xABB6, 0xFF45: 0xFF25, 0x2CC1: 0x2CC0, 0x13A5: 0xAB75, 0xAB8D: 0x13BD, 0x24B7: 0x24D1, - 0xA761: 0xA760, 0x104B2: 0x104DA, 0x104DC: 0x104B4, 0x00C3: 0x00E3, 0x01FA: 0x01FB, 0x041E: 0x043E, - 0x1E3E: 0x1E3F, 0xA74D: 0xA74C, 0x00C2: 0x00E2, 0x016C: 0x016D, 0x0214: 0x0215, 0x2179: 0x2169, - 0xA7B8: 0xA7B9, 0x0386: 0x03AC, 0x10F6: 0x1CB6, 0x1E8C: 0x1E8D, 0x1E23: 0x1E22, 0x1E927: 0x1E905, - 0x0049: 0x0069, 0x00F6: 0x00D6, 0x022B: 0x022A, 0x1F0A: 0x1F02, 0x13E3: 0xABB3, 0x105A9: 0x10582, - 0x0052: 0x0072, 0x0134: 0x0135, 0x0533: 0x0563, 0x1EED: 0x1EEC, 0x16E49: 0x16E69, 0x00EF: 0x00CF, - 0x01E1: 0x01E0, 0x04B4: 0x04B5, 0xAB94: 0x13C4, 0x118D8: 0x118B8, 0x0100: 0x0101, 0x2C54: 0x2C24, - 0x2C27: 0x2C57, 0xA653: 0xA652, 0xAB79: 0x13A9, 0x10576: 0x1059D, 0x04D0: 0x04D1, 0x04F3: 0x04F2, - 0x104B6: 0x104DE, 0x10FE: 0x1CBE, 0x1EB8: 0x1EB9, 0x212A: 0x006B, 0x2C6F: 0x0250, 0xA75B: 0xA75A, - 0x0232: 0x0233, 0x0394: 0x03B4, 0x2D13: 0x10B3, 0x13B0: 0xAB80, 0x118C9: 0x118A9, 0x0477: 0x0476, - 0x04CC: 0x04CB, 0x0266: 0xA7AA, 0x24BD: 0x24D7, 0xAB7F: 0x13AF, 0x1041C: 0x10444, 0x10582: 0x105A9, - 0x016A: 0x016B, 0x01EB: 0x01EA, 0x0572: 0x0542, 0x00C6: 0x00E6, 0x028C: 0x0245, 0x10B9: 0x2D19, - 0x1EE3: 0x1EE2, 0x2172: 0x2162, 0xFF57: 0xFF37, 0x03BB: 0x039B, 0x0425: 0x0445, 0x047E: 0x047F, - 0x2CC7: 0x2CC6, 0xA738: 0xA739, 0x16E5B: 0x16E7B, 0x04AC: 0x04AD, 0x052B: 0x052A, 0x24E5: 0x24CB, - 0x0410: 0x0430, 0x1EA7: 0x1EA6, 0x13BB: 0xAB8B, 0x217A: 0x216A, 0x13D1: 0xABA1, 0xFF33: 0xFF53, - 0x16E47: 0x16E67, 0x0186: 0x0254, 0x1CBF: 0x10FF, 0x1E1F: 0x1E1E, 0xAB78: 0x13A8, 0x104DF: 0x104B7, - 0x105B8: 0x10591, 0x1FB0: 0x1FB8, 0x13BD: 0xAB8D, 0x118AB: 0x118CB, 0x1EC8: 0x1EC9, 0x1F64: 0x1F6C, - 0x217F: 0x216F, 0x2C3A: 0x2C0A, 0x0424: 0x0444, 0x1CBA: 0x10FA, 0x1E1A: 0x1E1B, 0x1EFF: 0x1EFE, - 0x0067: 0x0047, 0x056A: 0x053A, 0x1ED6: 0x1ED7, 0x0581: 0x0551, 0x1E1E: 0x1E1F, 0x10594: 0x105BB, - 0x0105: 0x0104, 0x2C65: 0x023A, 0x0392: 0x03B2, 0x1E922: 0x1E900, 0x00D6: 0x00F6, 0x1E39: 0x1E38, - 0x16E42: 0x16E62, 0x2D0D: 0x10AD, 0x1EF8: 0x1EF9, 0x1F39: 0x1F31, 0xA692: 0xA693, 0xFF55: 0xFF35, - 0x019F: 0x0275, 0x024D: 0x024C, 0x0427: 0x0447, 0xA665: 0xA664, 0x0164: 0x0165, 0x020E: 0x020F, - 0x10AB: 0x2D0B, 0xA77D: 0x1D79, 0xAB98: 0x13C8, 0x10418: 0x10440, 0x10584: 0x105AB, 0x10CE1: 0x10CA1, - 0x03A6: 0x03C6, 0x2C58: 0x2C28, 0xA66A: 0xA66B, 0x1E89: 0x1E88, 0x1EFB: 0x1EFA, 0x2CD1: 0x2CD0, - 0x1E84: 0x1E85, 0xA65B: 0xA65A, 0x118A3: 0x118C3, 0x104B0: 0x104D8, 0x10CCB: 0x10C8B, 0x0075: 0x0055, - 0x03BD: 0x039D, 0xA7D0: 0xA7D1, 0x1F26: 0x1F2E, 0x2C31: 0x2C01, 0x2C55: 0x2C25, 0xAB95: 0x13C5, - 0x10CA5: 0x10CE5, 0x0193: 0x0260, 0x0229: 0x0228, 0x1E11: 0x1E10, 0x1E93A: 0x1E918, 0x012B: 0x012A, - 0x04B6: 0x04B7, 0x24C8: 0x24E2, 0x1F31: 0x1F39, 0x1F55: 0x1F5D, 0x2CA1: 0x2CA0, 0xA680: 0xA681, - 0xA691: 0xA690, 0xFF32: 0xFF52, 0x0263: 0x0194, 0x051C: 0x051D, 0x2164: 0x2174, 0x0553: 0x0583, - 0x10E0: 0x1CA0, 0x1ECE: 0x1ECF, 0x2C00: 0x2C30, 0x0179: 0x017A, 0x0201: 0x0200, 0x049F: 0x049E, - 0x03B1: 0x0391, 0x13BA: 0xAB8A, 0x2167: 0x2177, 0x2CBC: 0x2CBD, 0xA7AB: 0x025C, 0x1041F: 0x10447, - 0x1CA2: 0x10E2, 0x2C9B: 0x2C9A, 0x2CC5: 0x2CC4, 0x025C: 0xA7AB, 0xAB8C: 0x13BC, 0x00D8: 0x00F8, - 0x023D: 0x019A, 0x0246: 0x0247, 0x10C88: 0x10CC8, 0x118C3: 0x118A3, 0x0068: 0x0048, 0x042F: 0x044F, - 0x2174: 0x2164, 0x1E90: 0x1E91, 0x16E66: 0x16E46, 0x013B: 0x013C, 0x050C: 0x050D, 0x051E: 0x051F, - 0x24D6: 0x24BC, 0x10C91: 0x10CD1, 0x118C0: 0x118A0, 0x16E54: 0x16E74, 0x012C: 0x012D, 0x01C9: 0x01C7, - 0x03CA: 0x03AA, 0x046C: 0x046D, 0x10DD: 0x1C9D, 0x2C45: 0x2C15, 0x0218: 0x0219, 0x2CDF: 0x2CDE, - 0x10409: 0x10431, 0xABA1: 0x13D1, 0x0074: 0x0054, 0x00FC: 0x00DC, 0xA7B0: 0x029E, 0x1E14: 0x1E15, - 0x1F6A: 0x1F62, 0x1FEB: 0x1F7B, 0x2C34: 0x2C04, 0x16E44: 0x16E64, 0x023E: 0x2C66, 0x042A: 0x044A, - 0x0580: 0x0550, 0x104CE: 0x104F6, 0x01BC: 0x01BD, 0x037F: 0x03F3, 0xAB70: 0x13A0, 0x0576: 0x0546, - 0x2C9A: 0x2C9B, 0xABA0: 0x13D0, 0x104CF: 0x104F7, 0x028A: 0x01B1, 0x03AF: 0x038A, 0x0508: 0x0509, - 0x10580: 0x105A7, 0x00C1: 0x00E1, 0x01CF: 0x01D0, 0x03B7: 0x0397, 0x014D: 0x014C, 0x1E41: 0x1E40, - 0x2C28: 0x2C58, 0x1C81: 0x0434, 0x1C90: 0x10D0, 0xA7A5: 0xA7A4, 0x105AD: 0x10586, 0x1E941: 0x1E91F, - 0x00F2: 0x00D2, 0x017D: 0x017E, 0x0217: 0x0216, 0x00E1: 0x00C1, 0x10CD2: 0x10C92, 0x16E5C: 0x16E7C, - 0x0515: 0x0514, 0x2D02: 0x10A2, 0x10A4: 0x2D04, 0x10EB: 0x1CAB, 0x10570: 0x10597, 0x016B: 0x016A, - 0x01EA: 0x01EB, 0x0242: 0x0241, 0xA766: 0xA767, 0xABB7: 0x13E7, 0x10CC2: 0x10C82, 0x118B4: 0x118D4, - 0x00DA: 0x00FA, 0x1E6E: 0x1E6F, 0x2C15: 0x2C45, 0x04AD: 0x04AC, 0x13A7: 0xAB77, 0x10D0: 0x1C90, - 0x10F3: 0x1CB3, 0x1F59: 0x1F51, 0x2C2A: 0x2C5A, 0xAB86: 0x13B6, 0x00CB: 0x00EB, 0x0256: 0x0189, - 0x0434: 0x0414, 0x13C9: 0xAB99, 0xFF51: 0xFF31, 0x16E75: 0x16E55, 0x10F8: 0x1CB8, 0xA7B6: 0xA7B7, - 0x10CCA: 0x10C8A, 0x04B8: 0x04B9, 0x1E1B: 0x1E1A, 0x24C6: 0x24E0, 0x2C3B: 0x2C0B, 0x2C8D: 0x2C8C, - 0x014F: 0x014E, 0x01D9: 0x01DA, 0x0213: 0x0212, 0x10CE8: 0x10CA8, 0x2D21: 0x10C1, 0x1C96: 0x10D6, - 0xA759: 0xA758, 0x0147: 0x0148, 0x03FE: 0x037C, 0x0419: 0x0439, 0x1EF9: 0x1EF8, 0x1F38: 0x1F30, - 0x2184: 0x2183, 0xA654: 0xA655, 0xA660: 0xA661, 0x0155: 0x0154, 0x0478: 0x0479, 0x1E8B: 0x1E8A, - 0xAB53: 0xA7B3, 0xFF46: 0xFF26, 0x10414: 0x1043C, 0x01F8: 0x01F9, 0x0241: 0x0242, 0x2D01: 0x10A1, - 0x04E1: 0x04E0, 0x1EDC: 0x1EDD, 0xA722: 0xA723, 0x10C87: 0x10CC7, 0x01B4: 0x01B3, 0x01D5: 0x01D6, - 0x03D6: 0x03C0, 0x2C63: 0x1D7D, 0xA681: 0xA680, 0x13B6: 0xAB86, 0x0103: 0x0102, 0x13F2: 0x13FA, - 0x1F22: 0x1F2A, 0x118DC: 0x118BC, 0x1C83: 0x0441, 0x1EA2: 0x1EA3, 0xAB7C: 0x13AC, 0xA768: 0xA769, - 0x10CD4: 0x10C94, 0x2D0A: 0x10AA, 0x1F45: 0x1F4D, 0x1FFA: 0x1F7C, 0x2CC4: 0x2CC5, 0x10444: 0x1041C, - 0x10C9E: 0x10CDE, 0x2D00: 0x10A0, 0x13FD: 0x13F5, 0x10DC: 0x1C9C, 0x2C41: 0x2C11, 0x10434: 0x1040C, - 0x0116: 0x0117, 0x046D: 0x046C, 0x04C4: 0x04C3, 0x10C9F: 0x10CDF, 0x16E4E: 0x16E6E, 0x1EB6: 0x1EB7, - 0xA7BE: 0xA7BF, 0x118CD: 0x118AD, 0x1E910: 0x1E932, 0x1E942: 0x1E920, 0x0071: 0x0051, 0x03BC: 0x00B5, - 0x017F: 0x0073, 0x2C57: 0x2C27, 0x0275: 0x019F, 0x022E: 0x022F, 0x2C24: 0x2C54, 0x01AF: 0x01B0, - 0x1ED0: 0x1ED1, 0x13D8: 0xABA8, 0x1E17: 0x1E16, 0x2C70: 0x0252, 0xA7C8: 0xA7C7, 0x10C99: 0x10CD9, - 0x0109: 0x0108, 0x045A: 0x040A, 0x10C2: 0x2D22, 0x1CA1: 0x10E1, 0x1E0F: 0x1E0E, 0xA785: 0xA784, - 0xFF42: 0xFF22, 0x01B8: 0x01B9, 0x044F: 0x042F, 0x04D9: 0x04D8, 0x1CB3: 0x10F3, 0x1E13: 0x1E12, - 0x2165: 0x2175, 0x2C33: 0x2C03, 0x104DD: 0x104B5, 0x0191: 0x0192, 0x021B: 0x021A, 0x0180: 0x0243, - 0x053C: 0x056C, 0x2C6B: 0x2C6C, 0xA75F: 0xA75E, 0x10408: 0x10430, 0x010B: 0x010A, 0x01D7: 0x01D8, - 0x03C2: 0x03C3, 0x1057F: 0x105A6, 0x118BC: 0x118DC, 0x018E: 0x01DD, 0x2177: 0x2167, 0x10439: 0x10411, - 0x03A3: 0x03C3, 0x1EB4: 0x1EB5, 0xABA6: 0x13D6, 0x13E7: 0xABB7, 0x1E903: 0x1E925, 0x01DC: 0x01DB, - 0x0372: 0x0373, 0x0398: 0x03B8, 0xAB88: 0x13B8, 0x10438: 0x10410, 0x118AA: 0x118CA, 0x013A: 0x0139, - 0x03FD: 0x037B, 0xA7B3: 0xAB53, 0x2C75: 0x2C76, 0xAB87: 0x13B7, 0x0257: 0x018A, 0x0224: 0x0225, - 0x2C2E: 0x2C5E, 0x03EF: 0x03EE, 0x10417: 0x1043F, 0x10CE9: 0x10CA9, 0x0502: 0x0503, 0x2D15: 0x10B5, - 0x13F4: 0x13FC, 0x1F24: 0x1F2C, 0x0450: 0x0400, 0x0464: 0x0465, 0x04AA: 0x04AB, 0x1FEC: 0x1FE5, - 0x1058E: 0x105B5, 0x0550: 0x0580, 0x10E3: 0x1CA3, 0x1EB9: 0x1EB8, 0x04EA: 0x04EB, 0x054E: 0x057E, - 0x13FB: 0x13F3, 0x1E3F: 0x1E3E, 0x2C1F: 0x2C4F, 0x0046: 0x0066, 0x00F9: 0x00D9, 0x046B: 0x046A, - 0x1E92C: 0x1E90A, 0x2D05: 0x10A5, 0x10AF: 0x2D0F, 0x1F21: 0x1F29, 0x2C4D: 0x2C1D, 0xA682: 0xA683, - 0xFF29: 0xFF49, 0xFF30: 0xFF50, 0x045E: 0x040E, 0x10B4: 0x2D14, 0x10D5: 0x1C95, 0x1040E: 0x10436, - 0x16E7D: 0x16E5D, 0xA74B: 0xA74A, 0xA786: 0xA787, 0x104B1: 0x104D9, 0x16E6C: 0x16E4C, 0x03B8: 0x0398, - 0x04DA: 0x04DB, 0x1E94: 0x1E95, 0x24C0: 0x24DA, 0x2CD8: 0x2CD9, 0x104E5: 0x104BD, 0x104F0: 0x104C8, - 0x105A4: 0x1057D, 0x00C5: 0x00E5, 0x0143: 0x0144, 0x1E62: 0x1E63, 0x118B1: 0x118D1, 0x1F0C: 0x1F04, - 0x2CE3: 0x2CE2, 0xA7A6: 0xA7A7, 0x00B5: 0x03BC, 0x00D4: 0x00F4, 0x037D: 0x03FF, 0x0153: 0x0152, - 0x0554: 0x0584, 0x10405: 0x1042D, 0x0545: 0x0575, 0x2CB8: 0x2CB9, 0x006D: 0x004D, 0x043B: 0x041B, - 0x048D: 0x048C, 0x1E36: 0x1E37, 0x1E4D: 0x1E4C, 0x1F48: 0x1F40, 0x2C16: 0x2C46, 0xA765: 0xA764, - 0x0141: 0x0142, 0x03C0: 0x03A0, 0x2D27: 0x10C7, 0x104D3: 0x104FB, 0x10A7: 0x2D07, 0x1E5E: 0x1E5F, - 0x1E61: 0x1E60, 0x24BA: 0x24D4, 0x2C0D: 0x2C3D, 0xA69B: 0xA69A, 0x01C4: 0x01C6, 0x0416: 0x0436, - 0x10ED: 0x1CAD, 0xA756: 0xA757, 0x118A5: 0x118C5, 0x1E918: 0x1E93A, 0x0543: 0x0573, 0xA645: 0xA644, - 0x104B4: 0x104DC, 0x105A7: 0x10580, 0x16E57: 0x16E77, 0x03DE: 0x03DF, 0x1C9F: 0x10DF, 0x1E22: 0x1E23, - 0x1E75: 0x1E74, 0xA64A: 0xA64B, 0xA726: 0xA727, 0xA7A1: 0xA7A0, 0xABB0: 0x13E0, 0x03BF: 0x039F, - 0x1C85: 0x0442, 0x1E2E: 0x1E2F, 0x118B8: 0x118D8, 0x16E7A: 0x16E5A, 0x2C5B: 0x2C2B, 0x2C8C: 0x2C8D, - 0xA76F: 0xA76E, 0x00FA: 0x00DA, 0x04E9: 0x04E8, 0x056D: 0x053D, 0x048B: 0x048A, 0x1C88: 0xA64B, - 0x1E78: 0x1E79, 0x1E92: 0x1E93, 0x1F7D: 0x1FFB, 0x006B: 0x004B, 0x043D: 0x041D, 0x0446: 0x0426, - 0x10412: 0x1043A, 0x104F3: 0x104CB, 0x1058C: 0x105B3, 0x2C2D: 0x2C5D, 0x2CD3: 0x2CD2, 0xFF49: 0xFF29, - 0x1042B: 0x10403, 0x16E6A: 0x16E4A, 0x04BF: 0x04BE, 0x04D2: 0x04D3, 0x1F41: 0x1F49, 0x10443: 0x1041B, - 0x105AB: 0x10584, 0x1ED3: 0x1ED2, 0x1EF0: 0x1EF1, 0xA669: 0xA668, 0xA75C: 0xA75D, 0xA78B: 0xA78C, - 0x13EF: 0xABBF, 0x118BA: 0x118DA, 0x16E6D: 0x16E4D, 0x040E: 0x045E, 0x041C: 0x043C, 0x1E4E: 0x1E4F, - 0x105A8: 0x10581, 0x118D1: 0x118B1, 0x019A: 0x023D, 0x24DB: 0x24C1, 0x104C6: 0x104EE, 0x04A3: 0x04A2, - 0x217E: 0x216E, 0x2CA2: 0x2CA3, 0xA699: 0xA698, 0x10440: 0x10418, 0x0187: 0x0188, 0x03ED: 0x03EC, - 0x0498: 0x0499, 0x16E62: 0x16E42, 0x1FE5: 0x1FEC, 0xA64F: 0xA64E, 0x10CEC: 0x10CAC, 0x0142: 0x0141, - 0x03BA: 0x039A, 0x04D8: 0x04D9, 0x04E8: 0x04E9, 0x2CCF: 0x2CCE, 0x1F62: 0x1F6A, 0x1043B: 0x10413, - 0x10C8C: 0x10CCC, 0x01FB: 0x01FA, 0x038A: 0x03AF, 0x0422: 0x0442, 0x16E63: 0x16E43, 0x037B: 0x03FD, - 0x04BE: 0x04BF, 0x10C92: 0x10CD2, 0x052F: 0x052E, 0x1F05: 0x1F0D, 0xA72D: 0xA72C, 0x10401: 0x10429, - 0x10C8B: 0x10CCB, 0x01AE: 0x0288, 0x020A: 0x020B, 0x0371: 0x0370, 0x1E27: 0x1E26, 0x1E60: 0x1E61, - 0x24C2: 0x24DC, 0x118A2: 0x118C2, 0x01CE: 0x01CD, 0x020D: 0x020C, 0x04F8: 0x04F9, 0x0044: 0x0064, - 0xA762: 0xA763, 0x10CE3: 0x10CA3, 0x00C0: 0x00E0, 0x24C5: 0x24DF, 0x2C38: 0x2C08, 0xA7C7: 0xA7C8, - 0x0126: 0x0127, 0x1ECA: 0x1ECB, 0x1F1D: 0x1F15, 0x24D5: 0x24BB, 0xA647: 0xA646, 0x00D0: 0x00F0, - 0x0118: 0x0119, 0x1EA1: 0x1EA0, 0x2C17: 0x2C47, 0x10598: 0x10571, 0x01B3: 0x01B4, 0x1C91: 0x10D1, - 0x1E37: 0x1E36, 0x1D7D: 0x2C63, 0x10441: 0x10419, 0x104FA: 0x104D2, 0x00CE: 0x00EE, 0x049D: 0x049C, - 0x1E32: 0x1E33, 0x1CA8: 0x10E8, 0x1FB8: 0x1FB0, 0x10CCF: 0x10C8F, 0x01B1: 0x028A, 0x04AB: 0x04AA, - 0x052C: 0x052D, 0x00DB: 0x00FB, 0x1F33: 0x1F3B, 0x2CA3: 0x2CA2, 0xFF34: 0xFF54, 0x10C9A: 0x10CDA, - 0x10CED: 0x10CAD, 0x046E: 0x046F, 0x0586: 0x0556, 0x2162: 0x2172, 0x0169: 0x0168, 0x1C9D: 0x10DD, - 0x16E71: 0x16E51, 0x01E3: 0x01E2, 0x042C: 0x044C, 0x04C9: 0x04CA, 0x1C92: 0x10D2, 0x1E2F: 0x1E2E, - 0x1E88: 0x1E89, 0x1F3B: 0x1F33, 0x2CAB: 0x2CAA, 0x00F0: 0x00D0, 0x00D3: 0x00F3, 0x047B: 0x047A, - 0xA7BC: 0xA7BD, 0x104C0: 0x104E8, 0x118DE: 0x118BE, 0x10597: 0x10570, 0x0259: 0x018F, 0x1EE2: 0x1EE3, - 0x2173: 0x2163, 0x2D03: 0x10A3, 0x1E86: 0x1E87, 0xA794: 0xA7C4, 0x1E909: 0x1E92B, 0x0243: 0x0180, - 0x040B: 0x045B, 0x04D7: 0x04D6, 0x214E: 0x2132, 0xA784: 0xA785, 0x13AF: 0xAB7F, 0x01D8: 0x01D7, - 0x04B9: 0x04B8, 0x1FD1: 0x1FD9, 0x1F18: 0x1F10, 0x1FCA: 0x1F74, 0x2C3D: 0x2C0D, 0x2C46: 0x2C16, - 0x2C5C: 0x2C2C, 0x0111: 0x0110, 0x1E93: 0x1E92, 0x1EA8: 0x1EA9, 0x2C8B: 0x2C8A, 0x13A0: 0xAB70, - 0x104ED: 0x104C5, 0xA751: 0xA750, 0xA76E: 0xA76F, 0xABBA: 0x13EA, 0x16E67: 0x16E47, 0x1E933: 0x1E911, - 0x0411: 0x0431, 0x1E66: 0x1E67, 0xA640: 0xA641, 0x1E916: 0x1E938, 0x04BA: 0x04BB, 0x1E95: 0x1E94, - 0x2C42: 0x2C12, 0x2CB9: 0x2CB8, 0x16E74: 0x16E54, 0x0443: 0x0423, 0x10AE: 0x2D0E, 0x1E03: 0x1E02, - 0x2C06: 0x2C36, 0x2C92: 0x2C93, 0xA7C0: 0xA7C1, 0x104C2: 0x104EA, 0x0493: 0x0492, 0x10E6: 0x1CA6, - 0x1FBB: 0x1F71, 0x044D: 0x042D, 0x0585: 0x0555, 0x1E0D: 0x1E0C, 0x2C61: 0x2C60, 0xAB84: 0x13B4, - 0x0254: 0x0186, 0x0260: 0x0193, 0x0227: 0x0226, 0xAB9E: 0x13CE, 0x1040F: 0x10437, 0x104EB: 0x104C3, - 0xA656: 0xA657, 0xA7C5: 0x0282, 0x0404: 0x0454, 0x0562: 0x0532, 0x1E44: 0x1E45, 0x0119: 0x0118, - 0x0447: 0x0427, 0x1F40: 0x1F48, 0x1E05: 0x1E04, 0x2C6C: 0x2C6B, 0xA728: 0xA729, 0x13A4: 0xAB74, - 0xFF44: 0xFF24, 0x010C: 0x010D, 0x011E: 0x011F, 0x04FA: 0x04FB, 0x10400: 0x10428, 0x1EB7: 0x1EB6, - 0xA7BA: 0xA7BB, 0x1E925: 0x1E903, 0x1F77: 0x1FDB, 0x104BC: 0x104E4, 0x0226: 0x0227, 0x0437: 0x0417, - 0x0470: 0x0471, 0x1F01: 0x1F09, 0x2C68: 0x2C67, 0xA65A: 0xA65B, 0xA7C9: 0xA7CA, 0x118C5: 0x118A5, - 0x0108: 0x0109, 0x0176: 0x0177, 0x1ED2: 0x1ED3, 0x0400: 0x0450, 0x1E40: 0x1E41, 0x1FDB: 0x1F77, - 0x2C9F: 0x2C9E, 0x10C89: 0x10CC9, 0x01A9: 0x0283, 0x0228: 0x0229, 0x03CD: 0x038E, 0x1E93C: 0x1E91A, - 0x1058D: 0x105B4, 0x10CF0: 0x10CB0, 0x118B7: 0x118D7, 0x0529: 0x0528, 0x2C84: 0x2C85, 0xA743: 0xA742, - 0x1EF6: 0x1EF7, 0x015A: 0x015B, 0x01A0: 0x01A1, 0x1E49: 0x1E48, 0x1E82: 0x1E83, 0x049B: 0x049A, - 0x10BC: 0x2D1C, 0x2D1D: 0x10BD, 0x021D: 0x021C, 0x2C83: 0x2C82, 0xA65E: 0xA65F, 0xA661: 0xA660, - 0xA744: 0xA745, 0x0129: 0x0128, 0x0177: 0x0176, 0x01CC: 0x01CA, 0xFF28: 0xFF48, 0x10575: 0x1059C, - 0x1E91B: 0x1E93D, 0x018C: 0x018B, 0x10A0: 0x2D00, 0x2CC3: 0x2CC2, 0x1EA0: 0x1EA1, 0xA724: 0xA725, - 0x13A8: 0xAB78, 0xFF48: 0xFF28, 0x01B2: 0x028B, 0x01DF: 0x01DE, 0x03F5: 0x03B5, 0x13F3: 0x13FB, - 0x1ED8: 0x1ED9, 0x2C62: 0x026B, 0x118DD: 0x118BD, 0x0196: 0x0269, 0x0395: 0x03B5, 0x03CB: 0x03AB, - 0x1E87: 0x1E86, 0x118B6: 0x118D6, 0x03E1: 0x03E0, 0x04D6: 0x04D7, 0x04FF: 0x04FE, 0x1F34: 0x1F3C, - 0x2CA4: 0x2CA5, 0xA658: 0xA659, 0x1D8E: 0xA7C6, 0xFF2E: 0xFF4E, 0x010A: 0x010B, 0x0474: 0x0475, - 0x10D7: 0x1C97, 0x1EE9: 0x1EE8, 0x0528: 0x0529, 0x10B3: 0x2D13, 0x1CAC: 0x10EC, 0x104CA: 0x104F2, - 0x105B4: 0x1058D, 0x118A1: 0x118C1, 0x01B6: 0x01B5, 0x1F6B: 0x1F63, 0x1FEA: 0x1F7A, 0x10572: 0x10599, - 0x0408: 0x0458, 0x1F4D: 0x1F45, 0x2CA6: 0x2CA7, 0xA76D: 0xA76C, 0xA7C4: 0xA794, 0x0156: 0x0157, - 0x056F: 0x053F, 0x1E45: 0x1E44, 0x1059D: 0x10576, 0x018A: 0x0257, 0x10F9: 0x1CB9, 0x2176: 0x2166, - 0x2C39: 0x2C09, 0x2C67: 0x2C68, 0xFF26: 0xFF46, 0x10CCC: 0x10C8C, 0x118D4: 0x118B4, 0x01DB: 0x01DC, - 0x10DA: 0x1C9A, 0x1E19: 0x1E18, 0x2CD5: 0x2CD4, 0x10C85: 0x10CC5, 0x03EE: 0x03EF, 0x0517: 0x0516, - 0x2CB4: 0x2CB5, 0x2170: 0x2160, 0x10402: 0x1042A, 0xA727: 0xA726, 0xA760: 0xA761, 0xA779: 0xA77A, - 0x01C6: 0x01C4, 0x1E2A: 0x1E2B, 0x24D9: 0x24BF, 0x2178: 0x2168, 0xA742: 0xA743, 0xA7B9: 0xA7B8, - 0x104EC: 0x104C4, 0x10CAE: 0x10CEE, 0x00CD: 0x00ED, 0x049E: 0x049F, 0x1ECF: 0x1ECE, 0x118DB: 0x118BB, - 0x118BD: 0x118DD, 0x13CB: 0xAB9B, 0xABB2: 0x13E2, 0x10428: 0x10400, 0x10A3: 0x2D03, 0x1E0E: 0x1E0F, - 0x1E1C: 0x1E1D, 0x24D8: 0x24BE, 0x2C3C: 0x2C0C, 0x00E7: 0x00C7, 0x0115: 0x0114, 0x044E: 0x042E, - 0x10CAC: 0x10CEC, 0x2C5D: 0x2C2D, 0xA792: 0xA793, 0x10CE0: 0x10CA0, 0x1F51: 0x1F59, 0x2CA5: 0x2CA4, - 0x1042F: 0x10407, 0x0158: 0x0159, 0x023A: 0x2C65, 0x10B7: 0x2D17, 0x0048: 0x0068, 0x01E4: 0x01E5, - 0x104E2: 0x104BA, 0xA733: 0xA732, 0x03B9: 0x0345, 0x049C: 0x049D, 0x10BB: 0x2D1B, 0x10579: 0x105A0, - 0x10C94: 0x10CD4, 0x04DE: 0x04DF, 0x1E8A: 0x1E8B, 0xA787: 0xA786, 0x0556: 0x0586, 0x2C0F: 0x2C3F, - 0xA662: 0xA663, 0xAB7A: 0x13AA, 0x16E6E: 0x16E4E, 0x0061: 0x0041, 0x0481: 0x0480, 0x0490: 0x0491, - 0x1E926: 0x1E904, 0x1044B: 0x10423, 0x10427: 0x1044F, 0x105A3: 0x1057C, 0x10CA1: 0x10CE1, 0x01EC: 0x01ED, - 0x1F63: 0x1F6B, 0x1043A: 0x10412, 0x1FBE: 0x03B9, 0x2CDA: 0x2CDB, 0x13DC: 0xABAC, 0xFF2C: 0xFF4C, - 0x104B5: 0x104DD, 0x10404: 0x1042C, 0x0507: 0x0506, 0x1EE6: 0x1EE7, 0x13C2: 0xAB92, 0x1EBC: 0x1EBD, - 0xA72F: 0xA72E, 0xABB3: 0x13E3, 0x104F9: 0x104D1, 0x1E91D: 0x1E93F, 0x01B5: 0x01B6, 0x01D4: 0x01D3, - 0x052D: 0x052C, 0xA7C1: 0xA7C0, 0x16E65: 0x16E45, 0x01A7: 0x01A8, 0x0206: 0x0207, 0xA64D: 0xA64C, - 0x1C9A: 0x10DA, 0x104E6: 0x104BE, 0x1E938: 0x1E916, 0x1E72: 0x1E73, 0x1EA3: 0x1EA2, 0x2CEE: 0x2CED, - 0xABAC: 0x13DC, 0x01D6: 0x01D5, 0x01FF: 0x01FE, 0x03D5: 0x03C6, 0x1C86: 0x044A, 0x1E08: 0x1E09, - 0x1E76: 0x1E77, 0x1F0D: 0x1F05, 0x24DE: 0x24C4, 0x01BF: 0x01F7, 0x03C7: 0x03A7, 0x0448: 0x0428, - 0xA649: 0xA648, 0xA725: 0xA724, 0x1E920: 0x1E942, 0xA7C2: 0xA7C3, 0x13EE: 0xABBE, 0x053E: 0x056E, - 0x2C90: 0x2C91, 0xA663: 0xA662, 0x1E3B: 0x1E3A, 0x1E8D: 0x1E8C, 0x1F2F: 0x1F27, 0x2C1B: 0x2C4B, - 0x0181: 0x0253, 0x0190: 0x025B, 0x2D12: 0x10B2, 0x1E64: 0x1E65, 0x1ECD: 0x1ECC, 0x1F1A: 0x1F12, - 0x216B: 0x217B, 0xA7A7: 0xA7A6, 0x00CF: 0x00EF, 0x0215: 0x0214, 0x0542: 0x0572, 0x13D5: 0xABA5, - 0xFF53: 0xFF33, 0x0506: 0x0507, 0x0578: 0x0548, 0x2C5F: 0x2C2F, 0x00FE: 0x00DE, 0xA723: 0xA722, - 0xABBF: 0x13EF, 0x2161: 0x2171, 0x2C53: 0x2C23, 0xA68E: 0xA68F, 0xA694: 0xA695, 0xAB93: 0x13C3, - 0x01CB: 0x01CC, 0x0195: 0x01F6, 0x0500: 0x0501, 0x10CD0: 0x10C90, 0x2CEC: 0x2CEB, 0xA7B4: 0xA7B5, - 0xABAE: 0x13DE, 0x10425: 0x1044D, 0x0069: 0x0049, 0x0122: 0x0123, 0x04FB: 0x04FA, 0x2C0E: 0x2C3E, - 0x2C1C: 0x2C4C, 0x16E4C: 0x16E6C, 0x0151: 0x0150, 0x10EE: 0x1CAE, 0x1EC0: 0x1EC1, 0x10581: 0x105A8, - 0x10CE4: 0x10CA4, 0x2CC2: 0x2CC3, 0x01E9: 0x01E8, 0x03EA: 0x03EB, 0x1CA5: 0x10E5, 0x10591: 0x105B8, - 0x10C93: 0x10CD3, 0x118C1: 0x118A1, 0x0152: 0x0153, 0x0495: 0x0494, 0xA65F: 0xA65E, 0x1E57: 0x1E56, - 0x212B: 0x00E5, 0xABB1: 0x13E1, 0x01FE: 0x01FF, 0x04C8: 0x04C7, 0x1E24: 0x1E25, 0x052A: 0x052B, - 0x1E923: 0x1E901, 0x0079: 0x0059, 0x0132: 0x0133, 0x020F: 0x020E, 0xABA2: 0x13D2, 0x1E92D: 0x1E90B, - 0x012E: 0x012F, 0xA659: 0xA658, 0xA7CA: 0xA7C9, 0x1EC6: 0x1EC7, 0x0053: 0x0073, 0x012A: 0x012B, - 0x0532: 0x0562, 0x1E934: 0x1E912, 0x0124: 0x0125, 0xA7F6: 0xA7F5, 0xABBD: 0x13ED, 0x0455: 0x0405, - 0x10DE: 0x1C9E, 0x1F71: 0x1FBB, 0xFF27: 0xFF47, 0x104F5: 0x104CD, 0x0106: 0x0107, 0x0192: 0x0191, - 0x2C66: 0x023E, 0x10CEE: 0x10CAE, 0x1E59: 0x1E58, 0x1E74: 0x1E75, 0x217B: 0x216B, 0x10CC7: 0x10C87, - 0x10CF2: 0x10CB2, 0x014A: 0x014B, 0x1C84: 0x0442, 0x1C9E: 0x10DE, 0x040A: 0x045A, 0x1EF5: 0x1EF4, - 0xA7A2: 0xA7A3, 0x10CD1: 0x10C91, 0x03D1: 0x03B8, 0x0547: 0x0577, 0x10A8: 0x2D08, 0x1F78: 0x1FF8, - 0x2CBB: 0x2CBA, 0xA667: 0xA666, 0x10CA4: 0x10CE4, 0x118B0: 0x118D0, 0x0171: 0x0170, 0x03AE: 0x0389, - 0x1F06: 0x1F0E, 0x0440: 0x0420, 0x24E9: 0x24CF, 0x2CCE: 0x2CCF, 0xA685: 0xA684, 0x10419: 0x10441, - 0x10CDA: 0x10C9A, 0x019E: 0x0220, 0x0583: 0x0553, 0x10D2: 0x1C92, 0x2C87: 0x2C86, 0x13B8: 0xAB88, - 0x104D1: 0x104F9, 0x0173: 0x0172, 0x01A2: 0x01A3, 0x1EB0: 0x1EB1, 0x1E58: 0x1E59, 0xA7BB: 0xA7BA, - 0xFF4A: 0xFF2A, 0x047C: 0x047D, 0x04C7: 0x04C8, 0x04F4: 0x04F5, 0x16E61: 0x16E41, 0x046A: 0x046B, - 0x2C59: 0x2C29, 0x10CC3: 0x10C83, 0x0520: 0x0521, 0xA7D6: 0xA7D7, 0xAB71: 0x13A1, 0x13E9: 0xABB9, - 0x006A: 0x004A, 0x00EB: 0x00CB, 0x048A: 0x048B, 0x1E43: 0x1E42, 0x2C02: 0x2C32, 0x2C96: 0x2C97, - 0x104E3: 0x104BB, 0x10CC9: 0x10C89, 0x0077: 0x0057, 0x024B: 0x024A, 0x0403: 0x0453, 0x1F42: 0x1F4A, - 0x105A5: 0x1057E, 0x03E6: 0x03E7, 0x051A: 0x051B, 0x1CA9: 0x10E9, 0x2C6E: 0x0271, 0x0250: 0x2C6F, - 0xAB91: 0x13C1, 0x010E: 0x010F, 0x011C: 0x011D, 0x2C35: 0x2C05, 0x1EAF: 0x1EAE, 0x2C2B: 0x2C5B, - 0x104CB: 0x104F3, 0x10CB0: 0x10CF0, 0x16E4F: 0x16E6F, 0x00CA: 0x00EA, 0x01F3: 0x01F1, 0x2D22: 0x10C2, - 0x13E8: 0xABB8, 0x118CB: 0x118AB, 0x118AE: 0x118CE, 0x0397: 0x03B7, 0x0538: 0x0568, 0xA68A: 0xA68B, - 0x1041A: 0x10442, 0x10CD9: 0x10C99, 0x16E68: 0x16E48, 0x0140: 0x013F, 0x1F19: 0x1F11, 0x24C3: 0x24DD, - 0x16E5D: 0x16E7D, 0x0057: 0x0077, 0x0373: 0x0372, 0x2CED: 0x2CEE, 0x0055: 0x0075, 0x0202: 0x0203, - 0x10C98: 0x10CD8, 0x04C0: 0x04CF, 0x10A2: 0x2D02, 0x1F7C: 0x1FFA, 0x1040B: 0x10433, 0x10C81: 0x10CC1, - 0x0244: 0x0289, 0x045D: 0x040D, 0x043C: 0x041C, 0xA64B: 0x1C88, 0x1CB2: 0x10F2, 0x1E12: 0x1E13, - 0x1F73: 0x1FC9, 0x2C32: 0x2C02, 0x039E: 0x03BE, 0x0433: 0x0413, 0x10C7: 0x2D27, 0xA79C: 0xA79D, - 0x13B1: 0xAB81, 0x16E48: 0x16E68, 0x0541: 0x0571, 0x24CE: 0x24E8, 0x006C: 0x004C, 0x03D7: 0x03CF, - 0x048C: 0x048D, 0x0514: 0x0515, 0x10A5: 0x2D05, 0x216C: 0x217C, 0x2CB7: 0x2CB6, 0x1E92A: 0x1E908, - 0x00F8: 0x00D8, 0x0113: 0x0112, 0x019D: 0x0272, 0x10429: 0x10401, 0x10CA8: 0x10CE8, 0x118D0: 0x118B0, - 0x04C6: 0x04C5, 0xA79F: 0xA79E, 0x026C: 0xA7AD, 0x1C87: 0x0463, 0x1E29: 0x1E28, 0xA66D: 0xA66C, - 0x10573: 0x1059A, 0x1E915: 0x1E937, 0x0043: 0x0063, 0x0211: 0x0210, 0x03C6: 0x03A6, 0x1EE1: 0x1EE0, - 0x24BB: 0x24D5, 0xA69A: 0xA69B, 0x118DF: 0x118BF, 0x01ED: 0x01EC, 0x04DC: 0x04DD, 0x10F7: 0x1CB7, - 0x0188: 0x0187, 0xA7B5: 0xA7B4, 0x2C9D: 0x2C9C, 0x10431: 0x10409, 0x104FB: 0x104D3, 0x10CD6: 0x10C96, - 0x118C7: 0x118A7, 0x01B7: 0x0292, 0x03CF: 0x03D7, 0x0412: 0x0432, 0x16E7B: 0x16E5B, 0x10CC6: 0x10C86, - 0x118D7: 0x118B7, 0x017B: 0x017C, 0x03E0: 0x03E1, 0x2CB1: 0x2CB0, 0x0428: 0x0448, 0x10E1: 0x1CA1, - 0x1E6D: 0x1E6C, 0x1EC4: 0x1EC5, 0x2C01: 0x2C31, 0x006F: 0x004F, 0x0161: 0x0160, 0x0200: 0x0201, - 0x118C4: 0x118A4, 0x2D14: 0x10B4, 0x2132: 0x214E, 0x2C4C: 0x2C1C, 0x2C56: 0x2C26, 0xAB96: 0x13C6, - 0x022A: 0x022B, 0x0393: 0x03B3, 0x03A8: 0x03C8, 0x1040D: 0x10435, 0x10C90: 0x10CD0, 0x13BE: 0xAB8E, - 0xAB8F: 0x13BF, 0x104F6: 0x104CE, 0x0391: 0x03B1, 0x0582: 0x0552, 0x10D3: 0x1C93, 0x2CBA: 0x2CBB, - 0x13BC: 0xAB8C, 0x10CDD: 0x10C9D, 0x1E0B: 0x1E0A, 0x1ED7: 0x1ED6, 0x13E5: 0xABB5, 0x044B: 0x042B, - 0x0535: 0x0565, 0x056E: 0x053E, 0x1044F: 0x10427, 0x10590: 0x105B7, 0x1F3A: 0x1F32, 0x2C64: 0x027D, - 0x2CAA: 0x2CAB, 0xAB81: 0x13B1, 0xFF4C: 0xFF2C, 0x0104: 0x0105, 0x039F: 0x03BF, 0x0503: 0x0502, - 0xFF56: 0xFF36, 0x022C: 0x022D, 0x24E4: 0x24CA, 0x2C4A: 0x2C1A, 0x1FE0: 0x1FE8, 0xA73F: 0xA73E, - 0x13ED: 0xABBD, 0x1E92F: 0x1E90D, 0x004E: 0x006E, 0x04E7: 0x04E6, 0x0546: 0x0576, 0x1F6D: 0x1F65, - 0x2CD2: 0x2CD3, 0x1042A: 0x10402, 0x10437: 0x1040F, 0x04F0: 0x04F1, 0x2D07: 0x10A7, 0x1E68: 0x1E69, - 0x2CC8: 0x2CC9, 0xA737: 0xA736, 0x04EF: 0x04EE, 0x24D0: 0x24B6, 0x2C1A: 0x2C4A, 0x03AB: 0x03CB, - 0x10A9: 0x2D09, 0x104D9: 0x104B1, 0x10445: 0x1041D, 0x1059C: 0x10575, 0x118B2: 0x118D2, 0x01D3: 0x01D4, - 0x03AC: 0x0386, 0x1E21: 0x1E20, 0x1F02: 0x1F0A, 0x2C89: 0x2C88, 0xAB7E: 0x13AE, 0x1E908: 0x1E92A, - 0x1E940: 0x1E91E, 0x0123: 0x0122, 0x01DD: 0x018E, 0x04EC: 0x04ED, 0x0056: 0x0076, 0x0561: 0x0531, - 0x00E6: 0x00C6, 0x1E0A: 0x1E0B, 0x01F9: 0x01F8, 0x0210: 0x0211, 0x0345: 0x03B9, 0x03FA: 0x03FB, - 0x1E943: 0x1E921, 0x013D: 0x013E, 0x0146: 0x0145, 0x018B: 0x018C, 0x1EC9: 0x1EC8, 0xA657: 0xA656, - 0x017E: 0x017D, 0x10D8: 0x1C98, 0x1E2C: 0x1E2D, 0x021E: 0x021F, 0xA7A9: 0xA7A8, 0x16E4A: 0x16E6A, - 0x0076: 0x0056, 0x2C97: 0x2C96, 0x0287: 0xA7B1, 0x24BC: 0x24D6, 0xA74A: 0xA74B, 0x104F2: 0x104CA, - 0x16E5E: 0x16E7E, 0x0073: 0x0053, 0x0268: 0x0197, 0x0407: 0x0457, 0x2C76: 0x2C75, 0x104B8: 0x104E0, - 0x0168: 0x0169, 0x1F61: 0x1F69, 0x2C08: 0x2C38, 0x0439: 0x0419, 0x0420: 0x0440, 0x0467: 0x0466, - 0x1EA5: 0x1EA4, 0x118B5: 0x118D5, 0x01AC: 0x01AD, 0x021A: 0x021B, 0x03F0: 0x03BA, 0x1EE4: 0x1EE5, - 0x13B7: 0xAB87, 0xFF23: 0xFF43, 0x10410: 0x10438, 0x0272: 0x019D, 0x04BD: 0x04BC, 0x1EAB: 0x1EAA, - 0x16E41: 0x16E61, 0x1E93D: 0x1E91B, 0x24BF: 0x24D9, 0xA798: 0xA799, 0xA7A3: 0xA7A2, 0xA648: 0xA649, - 0x04DF: 0x04DE, 0x1E09: 0x1E08, 0x2CB3: 0x2CB2, 0x0199: 0x0198, 0x1F3F: 0x1F37, 0xA687: 0xA686, - 0x057D: 0x054D, 0xA77F: 0xA77E, 0x104BD: 0x104E5, 0xA664: 0xA665, 0x1E91F: 0x1E941, 0x0165: 0x0164, - 0x10E5: 0x1CA5, 0x1E6C: 0x1E6D, 0x10E7: 0x1CA7, 0x1EF1: 0x1EF0, 0x2C07: 0x2C37, 0x2CDB: 0x2CDA, - 0x0072: 0x0052, 0x0120: 0x0121, 0x01FD: 0x01FC, 0xA767: 0xA766, 0x00DE: 0x00FE, 0x03B3: 0x0393, - 0x1F14: 0x1F1C, 0x2D1C: 0x10BC, 0x2C44: 0x2C14, 0xABB8: 0x13E8, 0x105B6: 0x1058F, 0x16E78: 0x16E58, - 0x024E: 0x024F, 0x04C1: 0x04C2, 0x2D0E: 0x10AE, 0x01EE: 0x01EF, 0x24E2: 0x24C8, 0x1044D: 0x10425, - 0x118CF: 0x118AF, 0x006E: 0x004E, 0x048E: 0x048F, 0x1EDA: 0x1EDB, 0x16E50: 0x16E70, 0x1F3D: 0x1F35, - 0x13CC: 0xAB9C, 0x10420: 0x10448, 0x2C30: 0x2C00, 0x2CCC: 0x2CCD, 0xFF4D: 0xFF2D, 0xFF36: 0xFF56, - 0x0183: 0x0182, 0x0231: 0x0230, 0x04A7: 0x04A6, 0xA7D9: 0xA7D8, 0xABA7: 0x13D7, 0x0065: 0x0045, - 0x054D: 0x057D, 0xA74F: 0xA74E, 0x1E04: 0x1E05, 0xA782: 0xA783, 0x023C: 0x023B, 0x03F8: 0x03F7, - 0x0444: 0x0424, 0x1E4C: 0x1E4D, 0x1E56: 0x1E57, 0xA644: 0xA645, 0xA75E: 0xA75F, 0x0145: 0x0146, - 0x03F9: 0x03F2, 0x040C: 0x045C, 0x2C0C: 0x2C3C, 0x2C1E: 0x2C4E, 0xA736: 0xA737, 0xABB9: 0x13E9, - 0x10578: 0x1059F, 0x054F: 0x057F, 0x10EC: 0x1CAC, 0x1E65: 0x1E64, 0x10CD5: 0x10C95, 0x10B2: 0x2D12, - 0x10DF: 0x1C9F, 0x1E5B: 0x1E5A, 0x2160: 0x2170, 0xA684: 0xA685, 0x0253: 0x0181, 0x0185: 0x0184, - 0x0501: 0x0500, 0xAB83: 0x13B3, 0x16E51: 0x16E71, 0x1FD8: 0x1FD0, 0x01D1: 0x01D2, 0x04E5: 0x04E4, - 0x1EDD: 0x1EDC, 0xA740: 0xA741, 0x1E93F: 0x1E91D, 0x0205: 0x0204, 0x03A7: 0x03C7, 0xA651: 0xA650, - 0x10CF1: 0x10CB1, 0x118A9: 0x118C9, 0x1E90A: 0x1E92C, 0x04D5: 0x04D4, 0x1FE8: 0x1FE0, 0x1059B: 0x10574, - 0xA693: 0xA692, 0x0261: 0xA7AC, 0xAB8E: 0x13BE, 0x13BF: 0xAB8F, 0x13D2: 0xABA2, 0x04A9: 0x04A8, - 0x2D16: 0x10B6, 0x2C60: 0x2C61, 0x2C8E: 0x2C8F, 0x2C94: 0x2C95, 0x029E: 0xA7B0, 0x13E1: 0xABB1, - 0x118D6: 0x118B6, 0x0531: 0x0561, 0x0555: 0x0585, 0x2183: 0x2184, 0x1F0B: 0x1F03, 0x2CB6: 0x2CB7, - 0x2CF2: 0x2CF3, 0x1CAD: 0x10ED, 0xA696: 0xA697, 0xA78C: 0xA78B, 0x10422: 0x1044A, 0x010F: 0x010E, - 0x038E: 0x03CD, 0x041B: 0x043B, 0x2D11: 0x10B1, 0x10B5: 0x2D15, 0x10D4: 0x1C94, 0x1F37: 0x1F3F, - 0x1F69: 0x1F61, 0x0182: 0x0183, 0x0430: 0x0410, 0x0429: 0x0449, 0x1F70: 0x1FBA, 0x2CA7: 0x2CA6, - 0xA68F: 0xA68E, 0x2C0A: 0x2C3A, 0x01A4: 0x01A5, 0x0370: 0x0371, 0x10EA: 0x1CAA, 0xA732: 0xA733, - 0xAB8B: 0x13BB, 0x10403: 0x1042B, 0x16E64: 0x16E44, 0x025B: 0x0190, 0x1E53: 0x1E52, 0x2C9C: 0x2C9D, - 0xA748: 0xA749, 0x026A: 0xA7AE, 0xFF24: 0xFF44, 0x1F3E: 0x1F36, 0x1F65: 0x1F6D, 0x2CAE: 0x2CAF, - 0x00E0: 0x00C0, 0xA764: 0xA765, 0xA7AA: 0x0266, 0x1E913: 0x1E935, 0x1E936: 0x1E914, 0x0042: 0x0062, - 0xA641: 0xA640, 0xA750: 0xA751, 0x1057D: 0x105A4, 0x105B3: 0x1058C, 0x10CB1: 0x10CF1, 0x014B: 0x014A, - 0x10F5: 0x1CB5, 0x2C3F: 0x2C0F, 0x13B5: 0xAB85, 0xAB92: 0x13C2, 0x13D4: 0xABA4, 0x0453: 0x0403, - 0x2C52: 0x2C22, 0xA79D: 0xA79C, 0x104D0: 0x104F8, 0x10CDE: 0x10C9E, 0x118CE: 0x118AE, 0x0112: 0x0113, - 0x04B7: 0x04B6, 0x1CA0: 0x10E0, 0x13C0: 0xAB90, 0xFF25: 0xFF45, 0x104B3: 0x104DB, 0x03DB: 0x03DA, - 0x0457: 0x0407, 0x10D9: 0x1C99, + 0x1CBF: 0x10FF, 0x1E27: 0x1E26, 0xA7D7: 0xA7D6, 0xAB7E: 0x13AE, 0xABBA: 0x13EA, 0x1E936: 0x1E914, + 0x0246: 0x0247, 0x04F9: 0x04F8, 0x10585: 0x105AC, 0x012B: 0x012A, 0x1F37: 0x1F3F, 0x1E7A: 0x1E7B, + 0x2CAB: 0x2CAA, 0xFF49: 0xFF29, 0x104C4: 0x104EC, 0x00C6: 0x00E6, 0x056A: 0x053A, 0xA7A7: 0xA7A6, + 0x019C: 0x026F, 0x03F5: 0x03B5, 0x1EF2: 0x1EF3, 0x13BA: 0xAB8A, 0xFF2E: 0xFF4E, 0x10577: 0x1059E, + 0x118A6: 0x118C6, 0x050B: 0x050A, 0x0518: 0x0519, 0x1E3A: 0x1E3B, 0xA74C: 0xA74D, 0xFF2D: 0xFF4D, + 0x013B: 0x013C, 0x01E2: 0x01E3, 0x03A7: 0x03C7, 0x104C1: 0x104E9, 0x104F4: 0x104CC, 0x0159: 0x0158, + 0x023E: 0x2C66, 0x04E0: 0x04E1, 0x1F4B: 0x1F43, 0x2CCB: 0x2CCA, 0x10421: 0x10449, 0x104CD: 0x104F5, + 0x0121: 0x0120, 0x0226: 0x0227, 0x1EEE: 0x1EEF, 0x1F31: 0x1F39, 0x10C90: 0x10CD0, 0x0076: 0x0056, + 0x00F0: 0x00D0, 0x1EF4: 0x1EF5, 0x1EF5: 0x1EF4, 0x03B2: 0x0392, 0x2D0F: 0x10AF, 0x10AB: 0x2D0B, + 0x2C8C: 0x2C8D, 0xA640: 0xA641, 0x1E92D: 0x1E90B, 0x00F1: 0x00D1, 0x0475: 0x0474, 0x1E81: 0x1E80, + 0x24C5: 0x24DF, 0x24E6: 0x24CC, 0x2CE2: 0x2CE3, 0xFF2B: 0xFF4B, 0x03C8: 0x03A8, 0x2D20: 0x10C0, + 0x1F3A: 0x1F32, 0x24E1: 0x24C7, 0x2C9E: 0x2C9F, 0xA76F: 0xA76E, 0x13E0: 0xABB0, 0x1E93B: 0x1E919, + 0x01BF: 0x01F7, 0x1E77: 0x1E76, 0x2D08: 0x10A8, 0x1C85: 0x0442, 0x1E21: 0x1E20, 0x1E6B: 0x1E6A, + 0x1E75: 0x1E74, 0xFF43: 0xFF23, 0x01D6: 0x01D5, 0x056B: 0x053B, 0x01EC: 0x01ED, 0xA687: 0xA686, + 0x104E2: 0x104BA, 0x105AB: 0x10584, 0x0104: 0x0105, 0x0175: 0x0174, 0xFF4F: 0xFF2F, 0x16E46: 0x16E66, + 0x0462: 0x0463, 0x2126: 0x03C9, 0x10C0: 0x2D20, 0x1F57: 0x1F5F, 0x10CD0: 0x10C90, 0x1E915: 0x1E937, + 0x006F: 0x004F, 0x0391: 0x03B1, 0x044E: 0x042E, 0x2173: 0x2163, 0x015F: 0x015E, 0x03DE: 0x03DF, + 0x13EC: 0xABBC, 0xFF42: 0xFF22, 0x2C3A: 0x2C0A, 0x2C8B: 0x2C8A, 0x1FBA: 0x1F70, 0x2CB2: 0x2CB3, + 0xA65F: 0xA65E, 0x1043C: 0x10414, 0x10CDE: 0x10C9E, 0x0152: 0x0153, 0x04BE: 0x04BF, 0xA659: 0xA658, + 0x10423: 0x1044B, 0x0449: 0x0429, 0x1EB8: 0x1EB9, 0x10C3: 0x2D23, 0x1E3F: 0x1E3E, 0x1EAB: 0x1EAA, + 0xA646: 0xA647, 0xAB8A: 0x13BA, 0xFF51: 0xFF31, 0x0244: 0x0289, 0x10AE: 0x2D0E, 0x118B7: 0x118D7, + 0x1059E: 0x10577, 0x1E921: 0x1E943, 0x10438: 0x10410, 0x1059D: 0x10576, 0xABA5: 0x13D5, 0x10426: 0x1044E, + 0x10C9B: 0x10CDB, 0x0135: 0x0134, 0x01E5: 0x01E4, 0x0467: 0x0466, 0x1C84: 0x0442, 0xA7C7: 0xA7C8, + 0x13C2: 0xAB92, 0x0075: 0x0055, 0x0151: 0x0150, 0xA73E: 0xA73F, 0x13D2: 0xABA2, 0x00FD: 0x00DD, + 0x0493: 0x0492, 0x1EAD: 0x1EAC, 0x2C04: 0x2C34, 0x01AE: 0x0288, 0x1E4C: 0x1E4D, 0x1F2C: 0x1F24, + 0x24C4: 0x24DE, 0x13B4: 0xAB84, 0x104DD: 0x104B5, 0x1E940: 0x1E91E, 0x0196: 0x0269, 0x0269: 0x0196, + 0x1CB0: 0x10F0, 0x1EC8: 0x1EC9, 0xA66A: 0xA66B, 0xA699: 0xA698, 0xA74A: 0xA74B, 0xAB8E: 0x13BE, + 0x021D: 0x021C, 0x044D: 0x042D, 0xAB9D: 0x13CD, 0x16E66: 0x16E46, 0xA724: 0xA725, 0x118BF: 0x118DF, + 0x020E: 0x020F, 0x2C45: 0x2C15, 0x0406: 0x0456, 0x0497: 0x0496, 0x1EB6: 0x1EB7, 0x0109: 0x0108, + 0x037C: 0x03FE, 0x1E35: 0x1E34, 0x1E51: 0x1E50, 0x1E7C: 0x1E7D, 0x1F26: 0x1F2E, 0x2CCC: 0x2CCD, + 0xA7AC: 0x0261, 0x021A: 0x021B, 0x0425: 0x0445, 0x1C9B: 0x10DB, 0xA665: 0xA664, 0x1040C: 0x10434, + 0x0506: 0x0507, 0x10BE: 0x2D1E, 0x04DA: 0x04DB, 0x24D6: 0x24BC, 0xA738: 0xA739, 0x01C5: 0x01C6, + 0x0440: 0x0420, 0x1FBE: 0x03B9, 0x2C6C: 0x2C6B, 0xA791: 0xA790, 0x10446: 0x1041E, 0x0166: 0x0167, + 0x0554: 0x0584, 0x1F4A: 0x1F42, 0x1F68: 0x1F60, 0xFF4C: 0xFF2C, 0x10CC0: 0x10C80, 0x16E55: 0x16E75, + 0x1E88: 0x1E89, 0x1EE6: 0x1EE7, 0xA696: 0xA697, 0x105AD: 0x10586, 0x105B1: 0x1058A, 0x118CC: 0x118AC, + 0x16E76: 0x16E56, 0x1C93: 0x10D3, 0x1FEA: 0x1F7A, 0x10EB: 0x1CAB, 0x1EFD: 0x1EFC, 0xA697: 0xA696, + 0x04C8: 0x04C7, 0x13FD: 0x13F5, 0xA752: 0xA753, 0x1E90B: 0x1E92D, 0x1EFB: 0x1EFA, 0xA743: 0xA742, + 0x03E7: 0x03E6, 0x0407: 0x0457, 0x050F: 0x050E, 0x1F7A: 0x1FEA, 0xABBC: 0x13EC, 0x0046: 0x0066, + 0x00D0: 0x00F0, 0x0141: 0x0142, 0x0195: 0x01F6, 0x2D11: 0x10B1, 0x1CB5: 0x10F5, 0x1E54: 0x1E55, + 0x1EDD: 0x1EDC, 0x0042: 0x0062, 0x0056: 0x0076, 0x10CA9: 0x10CE9, 0x24D0: 0x24B6, 0x24E7: 0x24CD, + 0x1F0F: 0x1F07, 0x1F49: 0x1F41, 0x1E86: 0x1E87, 0x10C93: 0x10CD3, 0x04F6: 0x04F7, 0x1E42: 0x1E43, + 0xA72C: 0xA72D, 0x10592: 0x105B9, 0x01C4: 0x01C6, 0x03A1: 0x03C1, 0x1EB7: 0x1EB6, 0x2170: 0x2160, + 0xA74D: 0xA74C, 0x13A0: 0xAB70, 0xAB85: 0x13B5, 0xAB8C: 0x13BC, 0x0054: 0x0074, 0x1E57: 0x1E56, + 0x1F24: 0x1F2C, 0x1F74: 0x1FCA, 0x2C9F: 0x2C9E, 0x10CEE: 0x10CAE, 0x1F00: 0x1F08, 0x1F1D: 0x1F15, + 0xAB74: 0x13A4, 0x0047: 0x0067, 0x04E9: 0x04E8, 0x2C5A: 0x2C2A, 0x029D: 0xA7B2, 0xABBD: 0x13ED, + 0x004B: 0x006B, 0x040E: 0x045E, 0x03B6: 0x0396, 0x040B: 0x045B, 0x0522: 0x0523, 0xA72B: 0xA72A, + 0x0078: 0x0058, 0x0232: 0x0233, 0x04FE: 0x04FF, 0x0553: 0x0583, 0x104DA: 0x104B2, 0x104C2: 0x104EA, + 0x00CA: 0x00EA, 0x03BE: 0x039E, 0x1F4D: 0x1F45, 0x2C3D: 0x2C0D, 0xA7C1: 0xA7C0, 0xABB1: 0x13E1, + 0x118CA: 0x118AA, 0x1E92F: 0x1E90D, 0x040F: 0x045F, 0x1F2B: 0x1F23, 0x1EED: 0x1EEC, 0x1E913: 0x1E935, + 0x04AB: 0x04AA, 0x10C1: 0x2D21, 0x0514: 0x0515, 0xA784: 0xA785, 0x013E: 0x013D, 0x04E8: 0x04E9, + 0xFF4A: 0xFF2A, 0x10CC8: 0x10C88, 0x0441: 0x0421, 0x1CAE: 0x10EE, 0x1FCB: 0x1F75, 0x2C43: 0x2C13, + 0xA7AE: 0x026A, 0x10CCA: 0x10C8A, 0x0448: 0x0428, 0x1FBB: 0x1F71, 0x050E: 0x050F, 0x10A1: 0x2D01, + 0x1F3B: 0x1F33, 0x2CE1: 0x2CE0, 0x1E904: 0x1E926, 0x021B: 0x021A, 0x046A: 0x046B, 0x0579: 0x0549, + 0x054F: 0x057F, 0x1E01: 0x1E00, 0x24C6: 0x24E0, 0xFF27: 0xFF47, 0x1057F: 0x105A6, 0x01F9: 0x01F8, + 0x0566: 0x0536, 0x1F0C: 0x1F04, 0x2C37: 0x2C07, 0x2CC2: 0x2CC3, 0x118A2: 0x118C2, 0x01CE: 0x01CD, + 0x1F27: 0x1F2F, 0x10DC: 0x1C9C, 0x2CA8: 0x2CA9, 0x13B1: 0xAB81, 0xAB83: 0x13B3, 0x0168: 0x0169, + 0x04D3: 0x04D2, 0x0507: 0x0506, 0x1CB8: 0x10F8, 0x2C29: 0x2C59, 0x2CBD: 0x2CBC, 0xA669: 0xA668, + 0x10CA5: 0x10CE5, 0x0439: 0x0419, 0x046E: 0x046F, 0x10C8B: 0x10CCB, 0x118C2: 0x118A2, 0x1E34: 0x1E35, + 0x13B7: 0xAB87, 0x1E56: 0x1E57, 0xA785: 0xA784, 0x104C6: 0x104EE, 0x00FE: 0x00DE, 0x1E7F: 0x1E7E, + 0x0408: 0x0458, 0x1F2E: 0x1F26, 0x2C00: 0x2C30, 0x2CA6: 0x2CA7, 0xA68C: 0xA68D, 0xAB96: 0x13C6, + 0x00ED: 0x00CD, 0x023B: 0x023C, 0xABBB: 0x13EB, 0xABAA: 0x13DA, 0xABB4: 0x13E4, 0xABA4: 0x13D4, + 0x01C7: 0x01C9, 0x1F25: 0x1F2D, 0x0526: 0x0527, 0x1F64: 0x1F6C, 0xA77E: 0xA77F, 0x10573: 0x1059A, + 0x01EF: 0x01EE, 0x03CE: 0x038F, 0x2CA0: 0x2CA1, 0x2CC8: 0x2CC9, 0x10447: 0x1041F, 0x118D7: 0x118B7, + 0x01B4: 0x01B3, 0x2C1A: 0x2C4A, 0x053C: 0x056C, 0x104CA: 0x104F2, 0x1058D: 0x105B4, 0x118AD: 0x118CD, + 0x03BC: 0x00B5, 0x04B8: 0x04B9, 0xA723: 0xA722, 0x011E: 0x011F, 0x1ED9: 0x1ED8, 0x01CA: 0x01CC, + 0x01E0: 0x01E1, 0x0545: 0x0575, 0x13AB: 0xAB7B, 0x1057A: 0x105A1, 0x00E1: 0x00C1, 0x00DB: 0x00FB, + 0x10C4: 0x2D24, 0xA681: 0xA680, 0x13C3: 0xAB93, 0x10C84: 0x10CC4, 0x00E7: 0x00C7, 0x039C: 0x03BC, + 0x1E2D: 0x1E2C, 0x1F28: 0x1F20, 0xA660: 0xA661, 0x00E2: 0x00C2, 0x01A4: 0x01A5, 0x1C96: 0x10D6, + 0x1E05: 0x1E04, 0x2C25: 0x2C55, 0x2CAC: 0x2CAD, 0xA685: 0xA684, 0xA748: 0xA749, 0x0207: 0x0206, + 0x10CD: 0x2D2D, 0x13A6: 0xAB76, 0xABA1: 0x13D1, 0xA779: 0xA77A, 0xA7BB: 0xA7BA, 0x1F09: 0x1F01, + 0x1F77: 0x1FDB, 0x2C59: 0x2C29, 0x10CDF: 0x10C9F, 0x0231: 0x0230, 0x054D: 0x057D, 0x0571: 0x0541, + 0x0555: 0x0585, 0x1FFA: 0x1F7C, 0xAB73: 0x13A3, 0xAB88: 0x13B8, 0x13E3: 0xABB3, 0x0194: 0x0263, + 0x0419: 0x0439, 0x104C0: 0x104E8, 0x1CB3: 0x10F3, 0x2C61: 0x2C60, 0x1040F: 0x10437, 0x105B0: 0x10589, + 0x16E64: 0x16E44, 0x0256: 0x0189, 0x1CB1: 0x10F1, 0x047F: 0x047E, 0x052A: 0x052B, 0x1F2A: 0x1F22, + 0x24BF: 0x24D9, 0xA7A2: 0xA7A3, 0xA7C2: 0xA7C3, 0x0233: 0x0232, 0x03DA: 0x03DB, 0x13CF: 0xAB9F, + 0x10CA7: 0x10CE7, 0x01E3: 0x01E2, 0x023C: 0x023B, 0x03C4: 0x03A4, 0x2CAA: 0x2CAB, 0xFF22: 0xFF42, + 0x010E: 0x010F, 0x0139: 0x013A, 0x1F33: 0x1F3B, 0x2CEE: 0x2CED, 0x10412: 0x1043A, 0x1041A: 0x10442, + 0x00DC: 0x00FC, 0x04C9: 0x04CA, 0x04DC: 0x04DD, 0xA76B: 0xA76A, 0xA77B: 0xA77C, 0x017A: 0x0179, + 0x043A: 0x041A, 0x043B: 0x041B, 0x056C: 0x053C, 0x0154: 0x0155, 0x0289: 0x0244, 0x01F3: 0x01F1, + 0x03BB: 0x039B, 0xA729: 0xA728, 0x118A7: 0x118C7, 0x118B2: 0x118D2, 0x10B6: 0x2D16, 0x1E41: 0x1E40, + 0x0516: 0x0517, 0x2D07: 0x10A7, 0xA7A4: 0xA7A5, 0x0132: 0x0133, 0x0216: 0x0217, 0x020F: 0x020E, + 0xA680: 0xA681, 0xA7D1: 0xA7D0, 0x13AD: 0xAB7D, 0x16E77: 0x16E57, 0x1E922: 0x1E900, 0x1E13: 0x1E12, + 0x1EA9: 0x1EA8, 0x10CA8: 0x10CE8, 0x0192: 0x0191, 0x10CDD: 0x10C9D, 0x0527: 0x0526, 0x2172: 0x2162, + 0xA79C: 0xA79D, 0xAB87: 0x13B7, 0x104F3: 0x104CB, 0x0111: 0x0110, 0x03ED: 0x03EC, 0x03D1: 0x03B8, + 0x043E: 0x041E, 0x0426: 0x0446, 0x2CE0: 0x2CE1, 0xA78C: 0xA78B, 0x13DA: 0xABAA, 0x0064: 0x0044, + 0x03A3: 0x03C3, 0x16E5D: 0x16E7D, 0x10419: 0x10441, 0x10442: 0x1041A, 0x2C8D: 0x2C8C, 0xA793: 0xA792, + 0xAB90: 0x13C0, 0x118D9: 0x118B9, 0x0110: 0x0111, 0x01B5: 0x01B6, 0x04FA: 0x04FB, 0x104EA: 0x104C2, + 0x042E: 0x044E, 0x04BB: 0x04BA, 0x054A: 0x057A, 0x1E26: 0x1E27, 0x0252: 0x2C70, 0xA756: 0xA757, + 0x0268: 0x0197, 0x03F4: 0x03B8, 0xABAC: 0x13DC, 0x10CAD: 0x10CED, 0x0377: 0x0376, 0x10EF: 0x1CAF, + 0x2C4F: 0x2C1F, 0x1E934: 0x1E912, 0x1E93C: 0x1E91A, 0x0263: 0x0194, 0x01DC: 0x01DB, 0x13BC: 0xAB8C, + 0x13C8: 0xAB98, 0x1044E: 0x10426, 0x006A: 0x004A, 0x24C9: 0x24E3, 0x1C82: 0x043E, 0x1EEF: 0x1EEE, + 0x2C67: 0x2C68, 0x104CB: 0x104F3, 0x118C5: 0x118A5, 0x0292: 0x01B7, 0x0531: 0x0561, 0x0245: 0x028C, + 0x0550: 0x0580, 0x1EBB: 0x1EBA, 0x2C41: 0x2C11, 0xA72F: 0xA72E, 0x1D79: 0xA77D, 0x0136: 0x0137, + 0x022C: 0x022D, 0x0428: 0x0448, 0x1F2D: 0x1F25, 0x1FE9: 0x1FE1, 0xA645: 0xA644, 0x0220: 0x019E, + 0x038A: 0x03AF, 0x04EB: 0x04EA, 0x13F5: 0x13FD, 0x2C94: 0x2C95, 0x16E4E: 0x16E6E, 0x01F5: 0x01F4, + 0x04C0: 0x04CF, 0x1E900: 0x1E922, 0x118A8: 0x118C8, 0x16E63: 0x16E43, 0x04D1: 0x04D0, 0x2C96: 0x2C97, + 0x104F9: 0x104D1, 0x10CAF: 0x10CEF, 0x004F: 0x006F, 0x04B5: 0x04B4, 0xFF2A: 0xFF4A, 0x104DF: 0x104B7, + 0x1EF6: 0x1EF7, 0xA761: 0xA760, 0x0544: 0x0574, 0x2CA1: 0x2CA0, 0x13A4: 0xAB74, 0x10437: 0x1040F, + 0x014A: 0x014B, 0x04ED: 0x04EC, 0x1FF9: 0x1F79, 0x13D1: 0xABA1, 0x03A9: 0x03C9, 0x1E8A: 0x1E8B, + 0x13FB: 0x13F3, 0x0211: 0x0210, 0x04A4: 0x04A5, 0x1E8F: 0x1E8E, 0x1FE5: 0x1FEC, 0xA694: 0xA695, + 0x10430: 0x10408, 0x118C4: 0x118A4, 0x018A: 0x0257, 0x1E19: 0x1E18, 0x0432: 0x0412, 0x049E: 0x049F, + 0x1E37: 0x1E36, 0x2C38: 0x2C08, 0x2CF3: 0x2CF2, 0xA657: 0xA656, 0x03BA: 0x039A, 0x03FF: 0x037D, + 0x1043D: 0x10415, 0x10CA2: 0x10CE2, 0xA73F: 0xA73E, 0x13C4: 0xAB94, 0x1FD8: 0x1FD0, 0x03DD: 0x03DC, + 0x10F3: 0x1CB3, 0x1E14: 0x1E15, 0x2C2B: 0x2C5B, 0xFF35: 0xFF55, 0x10428: 0x10400, 0x0283: 0x01A9, + 0x0515: 0x0514, 0x1E4D: 0x1E4C, 0x1EE7: 0x1EE6, 0xA735: 0xA734, 0x13BE: 0xAB8E, 0x0170: 0x0171, + 0x0400: 0x0450, 0x10407: 0x1042F, 0x1058C: 0x105B3, 0x10CE7: 0x10CA7, 0x10AF: 0x2D0F, 0x2169: 0x2179, + 0x0500: 0x0501, 0x10A0: 0x2D00, 0x2D21: 0x10C1, 0x118B9: 0x118D9, 0x1E92B: 0x1E909, 0x0044: 0x0064, + 0x03CB: 0x03AB, 0x01AC: 0x01AD, 0x0412: 0x0432, 0x04C6: 0x04C5, 0x10B2: 0x2D12, 0x2CB4: 0x2CB5, + 0xABA0: 0x13D0, 0x0055: 0x0075, 0x00D9: 0x00F9, 0x1EDB: 0x1EDA, 0x0494: 0x0495, 0x1F07: 0x1F0F, + 0x1FE8: 0x1FE0, 0xA64E: 0xA64F, 0x1042E: 0x10406, 0x01A5: 0x01A4, 0x03FD: 0x037B, 0x03EA: 0x03EB, + 0x007A: 0x005A, 0x028C: 0x0245, 0x1E7E: 0x1E7F, 0x1FB9: 0x1FB1, 0xFF4D: 0xFF2D, 0x10CF1: 0x10CB1, + 0x037F: 0x03F3, 0x1E1D: 0x1E1C, 0x057A: 0x054A, 0x0584: 0x0554, 0x10E5: 0x1CA5, 0x10448: 0x10420, + 0x0247: 0x0246, 0x045A: 0x040A, 0x1EDA: 0x1EDB, 0x10594: 0x105BB, 0x0480: 0x0481, 0x04EA: 0x04EB, + 0x1E0A: 0x1E0B, 0x057F: 0x054F, 0x2D03: 0x10A3, 0x0068: 0x0048, 0x2164: 0x2174, 0x2C75: 0x2C76, + 0x2C82: 0x2C83, 0xA734: 0xA735, 0x03B1: 0x0391, 0x2C47: 0x2C17, 0x2D18: 0x10B8, 0x13F4: 0x13FC, + 0x1C88: 0xA64B, 0x1F42: 0x1F4A, 0x2C12: 0x2C42, 0x2CE3: 0x2CE2, 0x03F8: 0x03F7, 0x04A9: 0x04A8, + 0xABB8: 0x13E8, 0x1E93A: 0x1E918, 0x0140: 0x013F, 0x2D27: 0x10C7, 0x019A: 0x023D, 0x24DC: 0x24C2, + 0x2C8F: 0x2C8E, 0xA726: 0xA727, 0x011C: 0x011D, 0x022B: 0x022A, 0xA766: 0xA767, 0x012A: 0x012B, + 0x2C57: 0x2C27, 0x1CA6: 0x10E6, 0x1E50: 0x1E51, 0x2163: 0x2173, 0x2C99: 0x2C98, 0xA7B7: 0xA7B6, + 0x0137: 0x0136, 0x01A3: 0x01A2, 0x0565: 0x0535, 0x2C46: 0x2C16, 0xA7BA: 0xA7BB, 0x118CB: 0x118AB, + 0x006D: 0x004D, 0x0438: 0x0418, 0x2CC5: 0x2CC4, 0xFF31: 0xFF51, 0x00EB: 0x00CB, 0x13F0: 0x13F8, + 0x0520: 0x0521, 0xA794: 0xA7C4, 0x1059B: 0x10574, 0x016A: 0x016B, 0x0420: 0x0440, 0x24D4: 0x24BA, + 0x10CC7: 0x10C87, 0x1E918: 0x1E93A, 0x03AB: 0x03CB, 0x10DB: 0x1C9B, 0x10F2: 0x1CB2, 0xA7AB: 0x025C, + 0x1059C: 0x10575, 0x0053: 0x0073, 0x01FC: 0x01FD, 0x10E3: 0x1CA3, 0x1F3F: 0x1F37, 0xA75A: 0xA75B, + 0xABAF: 0x13DF, 0x13EF: 0xABBF, 0x0143: 0x0144, 0x0466: 0x0467, 0x03A4: 0x03C4, 0x1CA3: 0x10E3, + 0x1F69: 0x1F61, 0xA7C3: 0xA7C2, 0x13E8: 0xABB8, 0x1E926: 0x1E904, 0x03A5: 0x03C5, 0x0456: 0x0406, + 0xA7A1: 0xA7A0, 0x13B6: 0xAB86, 0x13E5: 0xABB5, 0x10CED: 0x10CAD, 0x16E45: 0x16E65, 0x1E938: 0x1E916, + 0x1F41: 0x1F49, 0x1F45: 0x1F4D, 0x1EE9: 0x1EE8, 0x01ED: 0x01EC, 0x03AE: 0x0389, 0x0586: 0x0556, + 0x1EF8: 0x1EF9, 0x24DA: 0x24C0, 0xAB92: 0x13C2, 0x0502: 0x0503, 0x056D: 0x053D, 0xA79F: 0xA79E, + 0x217D: 0x216D, 0x2CBE: 0x2CBF, 0x1F79: 0x1FF9, 0x1040D: 0x10435, 0x118AC: 0x118CC, 0x00FA: 0x00DA, + 0x10C5: 0x2D25, 0x0402: 0x0452, 0xA782: 0xA783, 0x1042B: 0x10403, 0x118A0: 0x118C0, 0x00FF: 0x0178, + 0x0249: 0x0248, 0x16E41: 0x16E61, 0x0208: 0x0209, 0x105B5: 0x1058E, 0x2176: 0x2166, 0x24C3: 0x24DD, + 0x2C30: 0x2C00, 0xA796: 0xA797, 0xFF39: 0xFF59, 0x00E0: 0x00C0, 0x1E6C: 0x1E6D, 0x0476: 0x0477, + 0x04CA: 0x04C9, 0x1EE3: 0x1EE2, 0x2CA3: 0x2CA2, 0xA68D: 0xA68C, 0x10403: 0x1042B, 0x0069: 0x0049, + 0x037B: 0x03FD, 0x10C8F: 0x10CCF, 0x03E1: 0x03E0, 0x051D: 0x051C, 0x1EB4: 0x1EB5, 0xA7B0: 0x029E, + 0x10429: 0x10401, 0x10CCD: 0x10C8D, 0x0045: 0x0065, 0x015D: 0x015C, 0x10CE1: 0x10CA1, 0x0070: 0x0050, + 0x01D2: 0x01D1, 0x16E7F: 0x16E5F, 0x04B6: 0x04B7, 0x054B: 0x057B, 0x24BE: 0x24D8, 0x2CD4: 0x2CD5, + 0xAB79: 0x13A9, 0x10434: 0x1040C, 0x0193: 0x0260, 0x1E76: 0x1E77, 0x1E89: 0x1E88, 0x2C10: 0x2C40, + 0xA7CA: 0xA7C9, 0x13A8: 0xAB78, 0x10595: 0x105BC, 0x0445: 0x0425, 0x04D2: 0x04D3, 0x2C9D: 0x2C9C, + 0xA648: 0xA649, 0xFF25: 0xFF45, 0x10405: 0x1042D, 0x1040A: 0x10432, 0x052F: 0x052E, 0x1EBD: 0x1EBC, + 0x1EA1: 0x1EA0, 0x2C22: 0x2C52, 0x0266: 0xA7AA, 0x10CEF: 0x10CAF, 0x118DA: 0x118BA, 0x00CD: 0x00ED, + 0x0469: 0x0468, 0x10418: 0x10440, 0x10B5: 0x2D15, 0x2C0C: 0x2C3C, 0x1E52: 0x1E53, 0xA74F: 0xA74E, + 0x10597: 0x10570, 0x118A9: 0x118C9, 0x013F: 0x0140, 0x0512: 0x0513, 0x2CD5: 0x2CD4, 0xA7A8: 0xA7A9, + 0x13BF: 0xAB8F, 0x03B8: 0x0398, 0x1ED3: 0x1ED2, 0x0490: 0x0491, 0x2D2D: 0x10CD, 0x0275: 0x019F, + 0x03F1: 0x03C1, 0x24B8: 0x24D2, 0xFF41: 0xFF21, 0x022A: 0x022B, 0x2D12: 0x10B2, 0x24C1: 0x24DB, + 0x04DD: 0x04DC, 0x1E62: 0x1E63, 0x1ECA: 0x1ECB, 0xA75D: 0xA75C, 0x13DE: 0xABAE, 0x10570: 0x10597, + 0x10CD7: 0x10C97, 0x16E53: 0x16E73, 0x00C3: 0x00E3, 0x10B0: 0x2D10, 0x104D3: 0x104FB, 0x10CA1: 0x10CE1, + 0x1E11: 0x1E10, 0x1F04: 0x1F0C, 0x1F59: 0x1F51, 0xA7A6: 0xA7A7, 0x104F8: 0x104D0, 0x10588: 0x105AF, + 0x01A2: 0x01A3, 0x1E0F: 0x1E0E, 0x1E18: 0x1E19, 0x1E65: 0x1E64, 0x1F70: 0x1FBA, 0x00F8: 0x00D8, + 0x012F: 0x012E, 0x10A9: 0x2D09, 0x2D14: 0x10B4, 0x2C93: 0x2C92, 0x04F8: 0x04F9, 0x0529: 0x0528, + 0x1F48: 0x1F40, 0xA728: 0xA729, 0x10584: 0x105AB, 0x1E90D: 0x1E92F, 0x1C86: 0x044A, 0x1EC4: 0x1EC5, + 0x10CC9: 0x10C89, 0x04E6: 0x04E7, 0x1EB1: 0x1EB0, 0xAB72: 0x13A2, 0x1040E: 0x10436, 0x00C5: 0x00E5, + 0x0197: 0x0268, 0x04BA: 0x04BB, 0xFF56: 0xFF36, 0x16E6A: 0x16E4A, 0x0173: 0x0172, 0x0182: 0x0183, + 0x03E3: 0x03E2, 0x0504: 0x0505, 0x1E7B: 0x1E7A, 0x2C08: 0x2C38, 0xA649: 0xA648, 0x00E6: 0x00C6, + 0x01DB: 0x01DC, 0x10C7: 0x2D27, 0x2C55: 0x2C25, 0x2CD3: 0x2CD2, 0xA73B: 0xA73A, 0xAB7F: 0x13AF, + 0x1E916: 0x1E938, 0x04BD: 0x04BC, 0x04E3: 0x04E2, 0x0556: 0x0586, 0x1E1C: 0x1E1D, 0x1F40: 0x1F48, + 0x2CD9: 0x2CD8, 0x104BD: 0x104E5, 0x10CAC: 0x10CEC, 0x024D: 0x024C, 0x0417: 0x0437, 0x1EA0: 0x1EA1, + 0x10408: 0x10430, 0x16E5A: 0x16E7A, 0x0398: 0x03B8, 0x1E2B: 0x1E2A, 0x00E5: 0x00C5, 0x03CD: 0x038E, + 0x1E39: 0x1E38, 0x2C28: 0x2C58, 0x2CA7: 0x2CA6, 0x13E7: 0xABB7, 0xFF58: 0xFF38, 0x10CE4: 0x10CA4, + 0x0156: 0x0157, 0x0492: 0x0493, 0x2167: 0x2177, 0x2C8A: 0x2C8B, 0xA68B: 0xA68A, 0xAB9F: 0x13CF, + 0x10B1: 0x2D11, 0x1E6E: 0x1E6F, 0x1E74: 0x1E75, 0x212B: 0x00E5, 0x24E9: 0x24CF, 0x0172: 0x0173, + 0x04B9: 0x04B8, 0xFF54: 0xFF34, 0x1ED5: 0x1ED4, 0xA7B8: 0xA7B9, 0x13DC: 0xABAC, 0x10582: 0x105A9, + 0x0174: 0x0175, 0x0477: 0x0476, 0x1C9D: 0x10DD, 0x1E02: 0x1E03, 0x2C6F: 0x0250, 0xAB99: 0x13C9, + 0x16E73: 0x16E53, 0x041F: 0x043F, 0x04EC: 0x04ED, 0x03B4: 0x0394, 0xA666: 0xA667, 0x021C: 0x021D, + 0x0465: 0x0464, 0x0577: 0x0547, 0x10D8: 0x1C98, 0x24DF: 0x24C5, 0x0100: 0x0101, 0x0119: 0x0118, + 0x04FC: 0x04FD, 0x10A6: 0x2D06, 0x1E10: 0x1E11, 0x2C1E: 0x2C4E, 0x023F: 0x2C7E, 0x118A3: 0x118C3, + 0x0210: 0x0211, 0x0213: 0x0212, 0x1FD9: 0x1FD1, 0xA68E: 0xA68F, 0x1E932: 0x1E910, 0x00DD: 0x00FD, + 0x0198: 0x0199, 0x0404: 0x0454, 0x10D0: 0x1C90, 0x1CB2: 0x10F2, 0xAB86: 0x13B6, 0x10C94: 0x10CD4, + 0x00D6: 0x00F6, 0x01F2: 0x01F3, 0x1E903: 0x1E925, 0x2CD8: 0x2CD9, 0x16E42: 0x16E62, 0x0437: 0x0417, + 0x1EEB: 0x1EEA, 0x1F11: 0x1F19, 0x1F78: 0x1FF8, 0x2C14: 0x2C44, 0xA7F5: 0xA7F6, 0x03F2: 0x03F9, + 0x0403: 0x0453, 0x13B9: 0xAB89, 0xA7A9: 0xA7A8, 0x050D: 0x050C, 0xA790: 0xA791, 0x040D: 0x045D, + 0x2C62: 0x026B, 0xA663: 0xA662, 0xABA2: 0x13D2, 0x104BC: 0x104E4, 0x038E: 0x03CD, 0x039B: 0x03BB, + 0x1E72: 0x1E73, 0x2CC9: 0x2CC8, 0x0230: 0x0231, 0x0430: 0x0410, 0x1E59: 0x1E58, 0x1E90: 0x1E91, + 0x24C0: 0x24DA, 0x2C1F: 0x2C4F, 0x0062: 0x0042, 0x01BD: 0x01BC, 0x2C63: 0x1D7D, 0x2CBC: 0x2CBD, + 0x104F5: 0x104CD, 0x10C9F: 0x10CDF, 0x04A0: 0x04A1, 0x1CA7: 0x10E7, 0x045B: 0x040B, 0x1F7C: 0x1FFA, + 0x2C19: 0x2C49, 0xA745: 0xA744, 0x13D7: 0xABA7, 0x105B4: 0x1058D, 0x01D9: 0x01DA, 0x01EB: 0x01EA, + 0x10CEA: 0x10CAA, 0x1E15: 0x1E14, 0x1ED7: 0x1ED6, 0x1EF9: 0x1EF8, 0x24D9: 0x24BF, 0xABAD: 0x13DD, + 0x13DD: 0xABAD, 0x00C9: 0x00E9, 0x0538: 0x0568, 0x118D0: 0x118B0, 0x0580: 0x0550, 0x2D10: 0x10B0, + 0x13F3: 0x13FB, 0x2C09: 0x2C39, 0x2C58: 0x2C28, 0x0189: 0x0256, 0x046F: 0x046E, 0x042C: 0x044C, + 0x057B: 0x054B, 0x0251: 0x2C6D, 0x018F: 0x0259, 0x0191: 0x0192, 0x105AC: 0x10585, 0x10C81: 0x10CC1, + 0x16E40: 0x16E60, 0x16E4C: 0x16E6C, 0x2CCF: 0x2CCE, 0x1040B: 0x10433, 0x057E: 0x054E, 0x1EE8: 0x1EE9, + 0x104FA: 0x104D2, 0x0395: 0x03B5, 0x03E4: 0x03E5, 0x00EF: 0x00CF, 0x0112: 0x0113, 0x03F3: 0x037F, + 0x0568: 0x0538, 0x1CB4: 0x10F4, 0x1E44: 0x1E45, 0x004E: 0x006E, 0x00B5: 0x03BC, 0x1E91F: 0x1E941, + 0x1F6F: 0x1F67, 0x16E48: 0x16E68, 0x1EEA: 0x1EEB, 0x1F6A: 0x1F62, 0xA79B: 0xA79A, 0x10CAB: 0x10CEB, + 0x1E943: 0x1E921, 0x0551: 0x0581, 0x1ED1: 0x1ED0, 0x041E: 0x043E, 0x0501: 0x0500, 0x1C97: 0x10D7, + 0x1EB0: 0x1EB1, 0x0287: 0xA7B1, 0x01E8: 0x01E9, 0x0397: 0x03B7, 0x1E83: 0x1E82, 0x104B8: 0x104E0, + 0x0072: 0x0052, 0x2D17: 0x10B7, 0x0372: 0x0373, 0x047C: 0x047D, 0x1F3E: 0x1F36, 0x2160: 0x2170, + 0xFF55: 0xFF35, 0x00DE: 0x00FE, 0x0185: 0x0184, 0xA755: 0xA754, 0x13A2: 0xAB72, 0x13AA: 0xAB7A, + 0xAB9A: 0x13CA, 0xABB9: 0x13E9, 0x1EC5: 0x1EC4, 0x2C5F: 0x2C2F, 0x0206: 0x0207, 0xAB97: 0x13C7, + 0xFF37: 0xFF57, 0x105B6: 0x1058F, 0x0118: 0x0119, 0x01FB: 0x01FA, 0x1043E: 0x10416, 0x00C1: 0x00E1, + 0x24D5: 0x24BB, 0x2C4C: 0x2C1C, 0x2C1D: 0x2C4D, 0xA683: 0xA682, 0xFF57: 0xFF37, 0x03E2: 0x03E3, + 0x1F5D: 0x1F55, 0x0282: 0xA7C5, 0x10A2: 0x2D02, 0x1E3C: 0x1E3D, 0x0242: 0x0241, 0x10C9A: 0x10CDA, + 0x004D: 0x006D, 0x0227: 0x0226, 0x10AD: 0x2D0D, 0x10579: 0x105A0, 0x01D8: 0x01D7, 0x0214: 0x0215, + 0x2CB1: 0x2CB0, 0x016D: 0x016C, 0x1CBE: 0x10FE, 0x0582: 0x0552, 0xA664: 0xA665, 0xA72A: 0xA72B, + 0x0373: 0x0372, 0x03AA: 0x03CA, 0x10DA: 0x1C9A, 0x2C91: 0x2C90, 0xA77A: 0xA779, 0x118C9: 0x118A9, + 0x01A1: 0x01A0, 0x04CF: 0x04C0, 0x2C6B: 0x2C6C, 0xAB53: 0xA7B3, 0x1042D: 0x10405, 0x10CDC: 0x10C9C, + 0x00DA: 0x00FA, 0x04A6: 0x04A7, 0x1E03: 0x1E02, 0x1EFA: 0x1EFB, 0xA768: 0xA769, 0x13A1: 0xAB71, + 0x118A5: 0x118C5, 0x020A: 0x020B, 0x0243: 0x0180, 0x1E2F: 0x1E2E, 0x1E36: 0x1E37, 0x2CA9: 0x2CA8, + 0x13A9: 0xAB79, 0x10C80: 0x10CC0, 0x0217: 0x0216, 0x1CAF: 0x10EF, 0x1FEB: 0x1F7B, 0xAB76: 0x13A6, + 0x105A8: 0x10581, 0x0043: 0x0063, 0x10BF: 0x2D1F, 0x16E79: 0x16E59, 0x10F7: 0x1CB7, 0x1F10: 0x1F18, + 0x2179: 0x2169, 0xAB93: 0x13C3, 0xABA3: 0x13D3, 0x104B4: 0x104DC, 0x0478: 0x0479, 0x2D1A: 0x10BA, + 0x1043A: 0x10412, 0x1EA3: 0x1EA2, 0x1F51: 0x1F59, 0x0458: 0x0408, 0x045C: 0x040C, 0x24CB: 0x24E5, + 0x2C70: 0x0252, 0x2CDA: 0x2CDB, 0xA691: 0xA690, 0x0048: 0x0068, 0x0134: 0x0135, 0x16E68: 0x16E48, + 0xFF36: 0xFF56, 0x10401: 0x10429, 0x1E38: 0x1E39, 0x1F65: 0x1F6D, 0x2C26: 0x2C56, 0x10CB2: 0x10CF2, + 0x049C: 0x049D, 0x1E16: 0x1E17, 0x2177: 0x2167, 0x13B5: 0xAB85, 0x017D: 0x017E, 0x03DF: 0x03DE, + 0x03C0: 0x03A0, 0x03E6: 0x03E7, 0x2D13: 0x10B3, 0x10D5: 0x1C95, 0x10F4: 0x1CB4, 0x2C68: 0x2C67, + 0x00C8: 0x00E8, 0x0272: 0x019D, 0x1044C: 0x10424, 0x104B2: 0x104DA, 0x1E901: 0x1E923, 0xA68A: 0xA68B, + 0xA7B6: 0xA7B7, 0x04E1: 0x04E0, 0x10F8: 0x1CB8, 0x1EE4: 0x1EE5, 0x104C3: 0x104EB, 0x006E: 0x004E, + 0x03D8: 0x03D9, 0xA7C0: 0xA7C1, 0x13A5: 0xAB75, 0x13B2: 0xAB82, 0x118D4: 0x118B4, 0x0401: 0x0451, + 0x1F6E: 0x1F66, 0x03E8: 0x03E9, 0x0491: 0x0490, 0x0583: 0x0553, 0x2C36: 0x2C06, 0x2C9B: 0x2C9A, + 0xAB82: 0x13B2, 0x0370: 0x0371, 0x0386: 0x03AC, 0xFF33: 0xFF53, 0x1EB2: 0x1EB3, 0xA7C6: 0x1D8E, + 0x13CC: 0xAB9C, 0x03C1: 0x03A1, 0x03E0: 0x03E1, 0xA7B3: 0xAB53, 0xA7C4: 0xA794, 0x104EC: 0x104C4, + 0x10B8: 0x2D18, 0x1FF8: 0x1F78, 0x2C8E: 0x2C8F, 0xFF46: 0xFF26, 0x10CDB: 0x10C9B, 0x0200: 0x0201, + 0x2C3F: 0x2C0F, 0x03FA: 0x03FB, 0x0509: 0x0508, 0x051B: 0x051A, 0x2CB5: 0x2CB4, 0xA787: 0xA786, + 0x1043B: 0x10413, 0x00CB: 0x00EB, 0x03B9: 0x0345, 0x1ED4: 0x1ED5, 0x2C6A: 0x2C69, 0x1D8E: 0xA7C6, + 0x104EE: 0x104C6, 0x118C6: 0x118A6, 0x00C4: 0x00E4, 0x0128: 0x0129, 0x1E2A: 0x1E2B, 0x24BA: 0x24D4, + 0x2CEC: 0x2CEB, 0x10587: 0x105AE, 0x118CF: 0x118AF, 0x00D3: 0x00F3, 0x03C2: 0x03C3, 0x24CA: 0x24E4, + 0x1042C: 0x10404, 0x10CD4: 0x10C94, 0x03FE: 0x037C, 0x04AC: 0x04AD, 0x10431: 0x10409, 0x028A: 0x01B1, + 0x1E25: 0x1E24, 0x16E54: 0x16E74, 0x0153: 0x0152, 0x0280: 0x01A6, 0x0508: 0x0509, 0x1CA5: 0x10E5, + 0x214E: 0x2132, 0x13DF: 0xABAF, 0x10433: 0x1040B, 0x104D8: 0x104B0, 0x0158: 0x0159, 0x01DA: 0x01D9, + 0x10CAE: 0x10CEE, 0x1E91B: 0x1E93D, 0x2CA2: 0x2CA3, 0xFF5A: 0xFF3A, 0x01FD: 0x01FC, 0x24D8: 0x24BE, + 0x104E5: 0x104BD, 0x042F: 0x044F, 0x1C83: 0x0441, 0x1E53: 0x1E52, 0x1F43: 0x1F4B, 0x118AF: 0x118CF, + 0x00F3: 0x00D3, 0x10DE: 0x1C9E, 0x1E8E: 0x1E8F, 0x24CC: 0x24E6, 0x0116: 0x0117, 0x2C72: 0x2C73, + 0x1E1A: 0x1E1B, 0xA66C: 0xA66D, 0x010B: 0x010A, 0x0257: 0x018A, 0x10BC: 0x2D1C, 0xA7BC: 0xA7BD, + 0x16E7E: 0x16E5E, 0x015C: 0x015D, 0x0517: 0x0516, 0x10CC3: 0x10C83, 0x015B: 0x015A, 0x104C7: 0x104EF, + 0x024A: 0x024B, 0x1E87: 0x1E86, 0x1E70: 0x1E71, 0x1EDF: 0x1EDE, 0x1F29: 0x1F21, 0x2CB3: 0x2CB2, + 0x16E59: 0x16E79, 0x0108: 0x0109, 0x050C: 0x050D, 0x03F9: 0x03F2, 0x049F: 0x049E, 0x0525: 0x0524, + 0x1F15: 0x1F1D, 0x2168: 0x2178, 0x216B: 0x217B, 0x0077: 0x0057, 0x00F2: 0x00D2, 0x10C9C: 0x10CDC, + 0x2C06: 0x2C36, 0x10441: 0x10419, 0x054C: 0x057C, 0x2D05: 0x10A5, 0x1E31: 0x1E30, 0x1EE5: 0x1EE4, + 0x1041B: 0x10443, 0x16E4F: 0x16E6F, 0x0101: 0x0100, 0x016E: 0x016F, 0x04F0: 0x04F1, 0xA65B: 0xA65A, + 0x0106: 0x0107, 0x03EF: 0x03EE, 0x0570: 0x0540, 0x0552: 0x0582, 0x1EE0: 0x1EE1, 0x0254: 0x0186, + 0x03D0: 0x03B2, 0x051F: 0x051E, 0x0576: 0x0546, 0x1E69: 0x1E68, 0x1EAA: 0x1EAB, 0xA760: 0xA761, + 0x16E65: 0x16E45, 0x0120: 0x0121, 0x04EF: 0x04EE, 0x1E0E: 0x1E0F, 0x2C3B: 0x2C0B, 0x0126: 0x0127, + 0x047A: 0x047B, 0x10F0: 0x1CB0, 0x24E2: 0x24C8, 0xA76A: 0xA76B, 0x104D2: 0x104FA, 0x10CD1: 0x10C91, + 0x01A6: 0x0280, 0x0549: 0x0579, 0x2CB9: 0x2CB8, 0x0434: 0x0414, 0x041B: 0x043B, 0xA651: 0xA650, + 0x13C1: 0xAB91, 0x13C7: 0xAB97, 0x00FC: 0x00DC, 0x0129: 0x0128, 0x2C0E: 0x2C3E, 0x16E5F: 0x16E7F, + 0x01EA: 0x01EB, 0x1EC1: 0x1EC0, 0x16E50: 0x16E70, 0x056F: 0x053F, 0x13FC: 0x13F4, 0x1F20: 0x1F28, + 0x118AE: 0x118CE, 0x0229: 0x0228, 0x047B: 0x047A, 0xA792: 0xA793, 0x01FF: 0x01FE, 0x020B: 0x020A, + 0x04C5: 0x04C6, 0x04CB: 0x04CC, 0x13DB: 0xABAB, 0x10425: 0x1044D, 0x10CE9: 0x10CA9, 0x16E5E: 0x16E7E, + 0x0178: 0x00FF, 0x0415: 0x0435, 0x04CD: 0x04CE, 0x04D4: 0x04D5, 0x10444: 0x1041C, 0x1058A: 0x105B1, + 0x16E60: 0x16E40, 0x16E58: 0x16E78, 0x011A: 0x011B, 0x018B: 0x018C, 0x1E91A: 0x1E93C, 0x0180: 0x0243, + 0x2C9C: 0x2C9D, 0x1E17: 0x1E16, 0x1F60: 0x1F68, 0xAB89: 0x13B9, 0x01B0: 0x01AF, 0x024C: 0x024D, + 0x24D3: 0x24B9, 0x10CCF: 0x10C8F, 0x2D15: 0x10B5, 0x1F5F: 0x1F57, 0x1044A: 0x10422, 0x1E92E: 0x1E90C, + 0x011F: 0x011E, 0x038F: 0x03CE, 0x045F: 0x040F, 0x10B3: 0x2D13, 0x2CC6: 0x2CC7, 0x2CDB: 0x2CDA, + 0x105AA: 0x10583, 0x0065: 0x0045, 0x00E4: 0x00C4, 0x10CE0: 0x10CA0, 0x1E931: 0x1E90F, 0x1E937: 0x1E915, + 0x1F05: 0x1F0D, 0x1041F: 0x10447, 0x2175: 0x2165, 0x041D: 0x043D, 0x042B: 0x044B, 0x2D00: 0x10A0, + 0xA78D: 0x0265, 0x03CC: 0x038C, 0x051C: 0x051D, 0x10E8: 0x1CA8, 0x10EA: 0x1CAA, 0x1E28: 0x1E29, + 0x1F55: 0x1F5D, 0x2178: 0x2168, 0x1057C: 0x105A3, 0x00F9: 0x00D9, 0x0471: 0x0470, 0x1E906: 0x1E928, + 0x118D6: 0x118B6, 0x16E69: 0x16E49, 0x1EF3: 0x1EF2, 0x2C3E: 0x2C0E, 0x2C50: 0x2C20, 0x2C2C: 0x2C5C, + 0x2CDF: 0x2CDE, 0xA662: 0xA663, 0x017B: 0x017C, 0x10EE: 0x1CAE, 0x1E93E: 0x1E91C, 0xA727: 0xA726, + 0x104CC: 0x104F4, 0x118BB: 0x118DB, 0x1E923: 0x1E901, 0x01FA: 0x01FB, 0x2C85: 0x2C84, 0x2C98: 0x2C99, + 0x10432: 0x1040A, 0x1E935: 0x1E913, 0x00F5: 0x00D5, 0x24E8: 0x24CE, 0x1F6D: 0x1F65, 0x2CD1: 0x2CD0, + 0x0547: 0x0577, 0x0581: 0x0551, 0xA79A: 0xA79B, 0x10427: 0x1044F, 0x10CD8: 0x10C98, 0x0574: 0x0544, + 0x216F: 0x217F, 0x04B3: 0x04B2, 0xA739: 0xA738, 0x16E7A: 0x16E5A, 0x03DB: 0x03DA, 0x04A5: 0x04A4, + 0x1E60: 0x1E61, 0x24DD: 0x24C3, 0x105A0: 0x10579, 0x118CE: 0x118AE, 0x049A: 0x049B, 0x1CAC: 0x10EC, + 0x1F6B: 0x1F63, 0x2C92: 0x2C93, 0xA661: 0xA660, 0x004A: 0x006A, 0x1F02: 0x1F0A, 0x04A8: 0x04A9, + 0x2C0F: 0x2C3F, 0x10CB1: 0x10CF1, 0x1E907: 0x1E929, 0x0253: 0x0181, 0x041A: 0x043A, 0x1E914: 0x1E936, + 0x1CB7: 0x10F7, 0x1FC8: 0x1F72, 0x052B: 0x052A, 0x1F62: 0x1F6A, 0x104BA: 0x104E2, 0x00D4: 0x00F4, + 0x04A2: 0x04A3, 0x1E20: 0x1E21, 0x1E929: 0x1E907, 0x0429: 0x0449, 0x054E: 0x057E, 0x049B: 0x049A, + 0x04D8: 0x04D9, 0x1E08: 0x1E09, 0x1057E: 0x105A5, 0x10C91: 0x10CD1, 0x0396: 0x03B6, 0x0474: 0x0475, + 0x0201: 0x0200, 0x2C39: 0x2C09, 0x2CD6: 0x2CD7, 0xA644: 0xA645, 0xA7AD: 0x026C, 0xFF2F: 0xFF4F, + 0x011B: 0x011A, 0x01F4: 0x01F5, 0x10C83: 0x10CC3, 0x2C54: 0x2C24, 0x13A3: 0xAB73, 0xFF44: 0xFF24, + 0x1FD1: 0x1FD9, 0x24E4: 0x24CA, 0x2C44: 0x2C14, 0x13B3: 0xAB83, 0xFF26: 0xFF46, 0x03FB: 0x03FA, + 0x10DF: 0x1C9F, 0xA647: 0xA646, 0x10CCB: 0x10C8B, 0x1E92A: 0x1E908, 0x01DE: 0x01DF, 0x1E0D: 0x1E0C, + 0x10CC6: 0x10C86, 0x10CA4: 0x10CE4, 0x1F7D: 0x1FFB, 0xA747: 0xA746, 0x1EAF: 0x1EAE, 0x1F63: 0x1F6B, + 0x2C32: 0x2C02, 0x01B7: 0x0292, 0x10B4: 0x2D14, 0x24C2: 0x24DC, 0x2C0A: 0x2C3A, 0x10586: 0x105AD, + 0x16E72: 0x16E52, 0x0260: 0x0193, 0x0413: 0x0433, 0x0393: 0x03B3, 0x04C3: 0x04C4, 0x2D04: 0x10A4, + 0x2D0B: 0x10AB, 0xA7F6: 0xA7F5, 0x10409: 0x10431, 0x0051: 0x0071, 0x00E3: 0x00C3, 0x16E78: 0x16E58, + 0x10C92: 0x10CD2, 0x1E920: 0x1E942, 0xA722: 0xA723, 0x0218: 0x0219, 0x1EBC: 0x1EBD, 0x24CF: 0x24E9, + 0xA76E: 0xA76F, 0x10CE6: 0x10CA6, 0x04FD: 0x04FC, 0x1ECF: 0x1ECE, 0x1C9A: 0x10DA, 0x1EBF: 0x1EBE, + 0xA7D6: 0xA7D7, 0xAB94: 0x13C4, 0x104D9: 0x104B1, 0x118BE: 0x118DE, 0x0041: 0x0061, 0x0513: 0x0512, + 0x0414: 0x0434, 0x0481: 0x0480, 0x04A1: 0x04A0, 0x1F38: 0x1F30, 0x2C76: 0x2C75, 0xA7A0: 0xA7A1, + 0x014C: 0x014D, 0x0186: 0x0254, 0x13EB: 0xABBB, 0x04B1: 0x04B0, 0x2C2F: 0x2C5F, 0x04D7: 0x04D6, + 0x1F3D: 0x1F35, 0xA7C9: 0xA7CA, 0xAB70: 0x13A0, 0x16E51: 0x16E71, 0x1E941: 0x1E91F, 0x01B3: 0x01B4, + 0x03F0: 0x03BA, 0x1FE1: 0x1FE9, 0x105A5: 0x1057E, 0x10CC1: 0x10C81, 0x10C88: 0x10CC8, 0x1E910: 0x1E932, + 0x046C: 0x046D, 0x0573: 0x0543, 0x1E61: 0x1E60, 0x1F53: 0x1F5B, 0x10406: 0x1042E, 0x0114: 0x0115, + 0x057C: 0x054C, 0x2C33: 0x2C03, 0x2C83: 0x2C82, 0x118C7: 0x118A7, 0x2C65: 0x023A, 0x04F3: 0x04F2, + 0x01A7: 0x01A8, 0x01B2: 0x028B, 0x0145: 0x0146, 0x0169: 0x0168, 0x2CDD: 0x2CDC, 0x1E927: 0x1E905, + 0x0259: 0x018F, 0x1E79: 0x1E78, 0x24E3: 0x24C9, 0x13D5: 0xABA5, 0x2CC7: 0x2CC6, 0x10C96: 0x10CD6, + 0x1E1B: 0x1E1A, 0x24C7: 0x24E1, 0x1E6D: 0x1E6C, 0x024F: 0x024E, 0x0523: 0x0522, 0x0410: 0x0430, + 0x04F2: 0x04F3, 0x10AA: 0x2D0A, 0xA762: 0xA763, 0x13E6: 0xABB6, 0x0179: 0x017A, 0x018E: 0x01DD, + 0x1EC2: 0x1EC3, 0x2C3C: 0x2C0C, 0x2CCA: 0x2CCB, 0x13D9: 0xABA9, 0x10CE5: 0x10CA5, 0x0503: 0x0502, + 0x0535: 0x0565, 0x0567: 0x0537, 0x2C0D: 0x2C3D, 0x2CCE: 0x2CCF, 0xA64C: 0xA64D, 0xA767: 0xA766, + 0x10C86: 0x10CC6, 0x00CC: 0x00EC, 0x0495: 0x0494, 0xA642: 0xA643, 0x10591: 0x105B8, 0x10C8A: 0x10CCA, + 0x16E62: 0x16E42, 0x019F: 0x0275, 0x10E1: 0x1CA1, 0x03E9: 0x03E8, 0x2C01: 0x2C31, 0x104C9: 0x104F1, + 0x016B: 0x016A, 0x03CA: 0x03AA, 0x03B3: 0x0393, 0x052E: 0x052F, 0x0563: 0x0533, 0x10BA: 0x2D1A, + 0x1C91: 0x10D1, 0x10FA: 0x1CBA, 0x0188: 0x0187, 0x01F1: 0x01F3, 0x2C07: 0x2C37, 0x13EE: 0xABBE, + 0x16E74: 0x16E54, 0x1E8D: 0x1E8C, 0x1F03: 0x1F0B, 0x0421: 0x0441, 0x0460: 0x0461, 0x1F44: 0x1F4C, + 0xA746: 0xA747, 0xA769: 0xA768, 0x01CB: 0x01CC, 0x01D4: 0x01D3, 0x01B6: 0x01B5, 0x13E9: 0xABB9, + 0x2C23: 0x2C53, 0x10C95: 0x10CD5, 0x03B7: 0x0397, 0x03BD: 0x039D, 0x1F32: 0x1F3A, 0x2C4B: 0x2C1B, + 0xA733: 0xA732, 0xABB7: 0x13E7, 0x10575: 0x1059C, 0x10CD2: 0x10C92, 0x0066: 0x0046, 0x2D1B: 0x10BB, + 0x10CF2: 0x10CB2, 0x1E7D: 0x1E7C, 0x1ECE: 0x1ECF, 0x1F1A: 0x1F12, 0xA654: 0xA655, 0x10E4: 0x1CA4, + 0x10F9: 0x1CB9, 0xA741: 0xA740, 0x104E9: 0x104C1, 0x0167: 0x0166, 0x039D: 0x03BD, 0xABAE: 0x13DE, + 0x04D0: 0x04D1, 0x1F5B: 0x1F53, 0x104E3: 0x104BB, 0x1E93D: 0x1E91B, 0x015E: 0x015F, 0x01D7: 0x01D8, + 0x10578: 0x1059F, 0x1057D: 0x105A4, 0x10D2: 0x1C92, 0x2C40: 0x2C10, 0x2CC0: 0x2CC1, 0x039A: 0x03BA, + 0x04B2: 0x04B3, 0x043C: 0x041C, 0x1CA9: 0x10E9, 0x1F73: 0x1FC9, 0xAB80: 0x13B0, 0x105AF: 0x10588, + 0x0199: 0x0198, 0x0454: 0x0404, 0x2CB8: 0x2CB9, 0xA684: 0xA685, 0x13E2: 0xABB2, 0x118D5: 0x118B5, + 0x04DB: 0x04DA, 0x2C17: 0x2C47, 0x1E09: 0x1E08, 0x1E67: 0x1E66, 0xA77D: 0x1D79, 0x026A: 0xA7AE, + 0x13A7: 0xAB77, 0x016F: 0x016E, 0x10FD: 0x1CBD, 0x0528: 0x0529, 0x1CAD: 0x10ED, 0x1E22: 0x1E23, + 0xA698: 0xA699, 0x104E8: 0x104C0, 0x0394: 0x03B4, 0x047E: 0x047F, 0x053A: 0x056A, 0x10411: 0x10439, + 0x0479: 0x0478, 0x04C2: 0x04C1, 0x0521: 0x0520, 0x0533: 0x0563, 0x13EA: 0xABBA, 0x104E4: 0x104BC, + 0x118C3: 0x118A3, 0x012E: 0x012F, 0x0148: 0x0147, 0x1EB3: 0x1EB2, 0x1F21: 0x1F29, 0x1F23: 0x1F2B, + 0xA73D: 0xA73C, 0x13D0: 0xABA0, 0x1044F: 0x10427, 0x023D: 0x019A, 0x10A4: 0x2D04, 0x1E90C: 0x1E92E, + 0x1044B: 0x10423, 0x0537: 0x0567, 0x1F18: 0x1F10, 0x2184: 0x2183, 0xA650: 0xA651, 0xA781: 0xA780, + 0x10581: 0x105A8, 0x1E905: 0x1E927, 0x0146: 0x0145, 0x1EBA: 0x1EBB, 0x014B: 0x014A, 0x0184: 0x0185, + 0x04FF: 0x04FE, 0x1E84: 0x1E85, 0x1FDB: 0x1F77, 0xA65E: 0xA65F, 0x006C: 0x004C, 0x012D: 0x012C, + 0xA69A: 0xA69B, 0x16E6F: 0x16E4F, 0x104E0: 0x104B8, 0x105B3: 0x1058C, 0x2D0E: 0x10AE, 0x1E07: 0x1E06, + 0x1F76: 0x1FDA, 0x24DE: 0x24C4, 0xA653: 0xA652, 0xA786: 0xA787, 0xAB78: 0x13A8, 0x1E92C: 0x1E90A, + 0x0181: 0x0253, 0x048F: 0x048E, 0x1EAE: 0x1EAF, 0x1FB0: 0x1FB8, 0x217A: 0x216A, 0x2C87: 0x2C86, + 0x13CB: 0xAB9B, 0x104DE: 0x104B6, 0x0162: 0x0163, 0x1CB6: 0x10F6, 0x10C8D: 0x10CCD, 0x2C2A: 0x2C5A, + 0xABAB: 0x13DB, 0x10572: 0x10599, 0x0498: 0x0499, 0x1FFB: 0x1F7D, 0x2183: 0x2184, 0x024B: 0x024A, + 0x2D0D: 0x10AD, 0xFF23: 0xFF43, 0x1E90A: 0x1E92C, 0x2C18: 0x2C48, 0x2CD7: 0x2CD6, 0x1E85: 0x1E84, + 0x216A: 0x217A, 0x0271: 0x2C6E, 0x2CAF: 0x2CAE, 0x020C: 0x020D, 0x023A: 0x2C65, 0x2C6E: 0x0271, + 0xA7B1: 0x0287, 0x011D: 0x011C, 0x2C2E: 0x2C5E, 0x24E5: 0x24CB, 0xA780: 0xA781, 0x0057: 0x0077, + 0x1F61: 0x1F69, 0x03EC: 0x03ED, 0x1E93: 0x1E92, 0x0250: 0x2C6F, 0xA7D9: 0xA7D8, 0x1E909: 0x1E92B, + 0x00F4: 0x00D4, 0x01D0: 0x01CF, 0x2C4A: 0x2C1A, 0x13B8: 0xAB88, 0x0157: 0x0156, 0x2C03: 0x2C33, + 0x1EA5: 0x1EA4, 0x1C9C: 0x10DC, 0x1EA4: 0x1EA5, 0x10E7: 0x1CA7, 0x1E94: 0x1E95, 0x1F30: 0x1F38, + 0x2C49: 0x2C19, 0xA65C: 0xA65D, 0xA75E: 0xA75F, 0x005A: 0x007A, 0x04A3: 0x04A2, 0x118D3: 0x118B3, + 0x24BB: 0x24D5, 0x2CAD: 0x2CAC, 0xA68F: 0xA68E, 0xA764: 0xA765, 0x10583: 0x105AA, 0x0107: 0x0106, + 0x04AF: 0x04AE, 0x2CDC: 0x2CDD, 0xA7B4: 0xA7B5, 0x10CDA: 0x10C9A, 0x04E4: 0x04E5, 0x2C53: 0x2C23, + 0x01D5: 0x01D6, 0x2D02: 0x10A2, 0x2D24: 0x10C4, 0x1CA1: 0x10E1, 0x1E95: 0x1E94, 0x216C: 0x217C, + 0x00C0: 0x00E0, 0x028B: 0x01B2, 0xA7AA: 0x0266, 0x118B4: 0x118D4, 0x0427: 0x0447, 0x1E33: 0x1E32, + 0xA66B: 0xA66A, 0xA7C8: 0xA7C7, 0xAB7B: 0x13AB, 0x104F1: 0x104C9, 0x0103: 0x0102, 0x01F8: 0x01F9, + 0x1E5B: 0x1E5A, 0x1F3C: 0x1F34, 0xAB7A: 0x13AA, 0x10443: 0x1041B, 0x0063: 0x0043, 0x01E7: 0x01E6, + 0xA737: 0xA736, 0xAB75: 0x13A5, 0x10CA6: 0x10CE6, 0x118A1: 0x118C1, 0x1E2E: 0x1E2F, 0x2CB6: 0x2CB7, + 0x03D9: 0x03D8, 0xA753: 0xA752, 0x0113: 0x0112, 0x018C: 0x018B, 0x053E: 0x056E, 0x056E: 0x053E, + 0x1C9F: 0x10DF, 0x2C15: 0x2C45, 0xA744: 0xA745, 0x10CCC: 0x10C8C, 0x0125: 0x0124, 0x0433: 0x0413, + 0x105A4: 0x1057D, 0x1C80: 0x0432, 0x13ED: 0xABBD, 0x04DE: 0x04DF, 0x1CAA: 0x10EA, 0x13CD: 0xAB9D, + 0x10402: 0x1042A, 0x10574: 0x1059B, 0x105B9: 0x10592, 0x0224: 0x0225, 0x045E: 0x040E, 0x1C98: 0x10D8, + 0x104BF: 0x104E7, 0xA64F: 0xA64E, 0x10422: 0x1044A, 0x0575: 0x0545, 0x10BD: 0x2D1D, 0xA7B2: 0x029D, + 0x104F6: 0x104CE, 0x0461: 0x0460, 0x0470: 0x0471, 0x2CAE: 0x2CAF, 0xA759: 0xA758, 0x016C: 0x016D, + 0x0202: 0x0203, 0x13AF: 0xAB7F, 0x2C1B: 0x2C4B, 0xA732: 0xA733, 0x2D01: 0x10A1, 0x10F6: 0x1CB6, + 0x16E57: 0x16E77, 0x025B: 0x0190, 0x0534: 0x0564, 0xA690: 0xA691, 0x217B: 0x216B, 0xA643: 0xA642, + 0x0241: 0x0242, 0x1C90: 0x10D0, 0x2162: 0x2172, 0x24DB: 0x24C1, 0xA725: 0xA724, 0x104ED: 0x104C5, + 0x0067: 0x0047, 0x022D: 0x022C, 0x10C99: 0x10CD9, 0x118B0: 0x118D0, 0x2D0C: 0x10AC, 0x10ED: 0x1CAD, + 0x2C20: 0x2C50, 0xA667: 0xA666, 0x10436: 0x1040E, 0x10C8E: 0x10CCE, 0x03C5: 0x03A5, 0x04AA: 0x04AB, + 0x16E6D: 0x16E4D, 0x1F39: 0x1F31, 0x1E924: 0x1E902, 0xAB8D: 0x13BD, 0x13E4: 0xABB4, 0x0457: 0x0407, + 0x1E68: 0x1E69, 0x2CDE: 0x2CDF, 0x104B6: 0x104DE, 0x105A9: 0x10582, 0x0183: 0x0182, 0x0190: 0x025B, + 0xA74E: 0xA74F, 0xABB2: 0x13E2, 0x1EAC: 0x1EAD, 0xA652: 0xA653, 0xFF4B: 0xFF2B, 0x1059F: 0x10578, + 0x16E56: 0x16E76, 0x01A8: 0x01A7, 0x040A: 0x045A, 0x1058F: 0x105B6, 0x2C35: 0x2C05, 0x104F0: 0x104C8, + 0x04B7: 0x04B6, 0x0524: 0x0525, 0x0561: 0x0531, 0x057D: 0x054D, 0x1E49: 0x1E48, 0x1FCA: 0x1F74, + 0x01AD: 0x01AC, 0x0455: 0x0405, 0x10CAA: 0x10CEA, 0x10CB0: 0x10CF0, 0x1E93F: 0x1E91D, 0x24CE: 0x24E8, + 0xA75C: 0xA75D, 0x0228: 0x0229, 0x13C5: 0xAB95, 0x13D8: 0xABA8, 0x01E9: 0x01E8, 0x0203: 0x0202, + 0x0519: 0x0518, 0x052C: 0x052D, 0x13F9: 0x13F1, 0x1EFF: 0x1EFE, 0xFF53: 0xFF33, 0x10439: 0x10411, + 0x0079: 0x0059, 0x0446: 0x0426, 0x10CC5: 0x10C85, 0x118B3: 0x118D3, 0x1EC9: 0x1EC8, 0x104CE: 0x104F6, + 0x105A6: 0x1057F, 0x013D: 0x013E, 0x1E40: 0x1E41, 0x10CEC: 0x10CAC, 0x118B1: 0x118D1, 0x03D5: 0x03C6, + 0xABA9: 0x13D9, 0x051E: 0x051F, 0x053B: 0x056B, 0x24BC: 0x24D6, 0x13AC: 0xAB7C, 0xAB9B: 0x13CB, + 0x1043F: 0x10417, 0x03F7: 0x03F8, 0x0451: 0x0401, 0x10E2: 0x1CA2, 0x2CA5: 0x2CA4, 0xAB9C: 0x13CC, + 0x118DD: 0x118BD, 0x16E49: 0x16E69, 0x0212: 0x0213, 0x04E2: 0x04E3, 0x2C60: 0x2C61, 0x2C6D: 0x0251, + 0x2CCD: 0x2CCC, 0xA7D8: 0xA7D9, 0xABB6: 0x13E6, 0xFF34: 0xFF54, 0x0050: 0x0070, 0x0219: 0x0218, + 0x10CD3: 0x10C93, 0x118DB: 0x118BB, 0x2C56: 0x2C26, 0x104B9: 0x104E1, 0x01B9: 0x01B8, 0x051A: 0x051B, + 0x01B1: 0x028A, 0x03B5: 0x0395, 0x0585: 0x0555, 0x2D1D: 0x10BD, 0x118A4: 0x118C4, 0x16E44: 0x16E64, + 0x010F: 0x010E, 0x0165: 0x0164, 0x16E47: 0x16E67, 0x1E91C: 0x1E93E, 0x216E: 0x217E, 0xA749: 0xA748, + 0xA751: 0xA750, 0x01BC: 0x01BD, 0x2C27: 0x2C57, 0x1E4F: 0x1E4E, 0xA656: 0xA657, 0xA77F: 0xA77E, + 0x13F1: 0x13F9, 0x1CB9: 0x10F9, 0x04D5: 0x04D4, 0x13D6: 0xABA6, 0x105BC: 0x10595, 0x118D8: 0x118B8, + 0x118DE: 0x118BE, 0x004C: 0x006C, 0x048C: 0x048D, 0x1F14: 0x1F1C, 0x03C3: 0x03A3, 0x03EB: 0x03EA, + 0x24D1: 0x24B7, 0x027D: 0x2C64, 0xA79E: 0xA79F, 0xA7D0: 0xA7D1, 0xAB95: 0x13C5, 0x16E52: 0x16E72, + 0x040C: 0x045C, 0x10E0: 0x1CA0, 0x1E90E: 0x1E930, 0x037D: 0x03FF, 0x2C02: 0x2C32, 0x10C98: 0x10CD8, + 0x0155: 0x0154, 0x01C6: 0x01C4, 0x118DF: 0x118BF, 0x00D8: 0x00F8, 0xAB84: 0x13B4, 0x10C9E: 0x10CDE, + 0x118BC: 0x118DC, 0x16E70: 0x16E50, 0x1CA2: 0x10E2, 0x2CD2: 0x2CD3, 0x0265: 0xA78D, 0x026F: 0x019C, + 0x2C52: 0x2C22, 0x2D16: 0x10B6, 0x2C9A: 0x2C9B, 0x1042F: 0x10407, 0x0102: 0x0103, 0x0124: 0x0125, + 0x1E29: 0x1E28, 0x1E5A: 0x1E5B, 0x1E6A: 0x1E6B, 0x0539: 0x0569, 0x10FF: 0x1CBF, 0x10413: 0x1043B, + 0x1E925: 0x1E903, 0x00EE: 0x00CE, 0x1E8C: 0x1E8D, 0x1E46: 0x1E47, 0x217C: 0x216C, 0x24CD: 0x24E7, + 0xFF52: 0xFF32, 0x10424: 0x1044C, 0x053F: 0x056F, 0x1E32: 0x1E33, 0x1FDA: 0x1F76, 0x2171: 0x2161, + 0x2D25: 0x10C5, 0x1CA0: 0x10E0, 0x2C4E: 0x2C1E, 0x2C80: 0x2C81, 0xABA6: 0x13D6, 0x04B4: 0x04B5, + 0x0542: 0x0572, 0x03A6: 0x03C6, 0x0436: 0x0416, 0x2C31: 0x2C01, 0xA73A: 0xA73B, 0x104DC: 0x104B4, + 0x00F6: 0x00D6, 0x01F7: 0x01BF, 0x1F6C: 0x1F64, 0xABB5: 0x13E5, 0x10404: 0x1042C, 0x1E3D: 0x1E3C, + 0x1E4A: 0x1E4B, 0x16E75: 0x16E55, 0x1C99: 0x10D9, 0x1CBD: 0x10FD, 0x212A: 0x006B, 0x2C7F: 0x0240, + 0x00D1: 0x00F1, 0x021E: 0x021F, 0x10CA3: 0x10CE3, 0x04AE: 0x04AF, 0xA78B: 0xA78C, 0x1E0C: 0x1E0D, + 0x2C51: 0x2C21, 0x10CC4: 0x10C84, 0x0123: 0x0122, 0x04F5: 0x04F4, 0x105A1: 0x1057A, 0x1CAB: 0x10EB, + 0x104B5: 0x104DD, 0x1E4E: 0x1E4F, 0x1EC6: 0x1EC7, 0xA7B9: 0xA7B8, 0x0160: 0x0161, 0x0392: 0x03B2, + 0x052D: 0x052C, 0x0543: 0x0573, 0x10445: 0x1041D, 0x0171: 0x0170, 0x03C9: 0x03A9, 0x0389: 0x03AE, + 0x13FA: 0x13F2, 0x1E45: 0x1E44, 0x1F1B: 0x1F13, 0x2CED: 0x2CEE, 0xA686: 0xA687, 0x015A: 0x015B, + 0x0376: 0x0377, 0x10414: 0x1043C, 0xAB8F: 0x13BF, 0x0536: 0x0566, 0x24B7: 0x24D1, 0x216D: 0x217D, + 0xABBF: 0x13EF, 0x1F36: 0x1F3E, 0x0569: 0x0539, 0x2D06: 0x10A6, 0xFF47: 0xFF27, 0x16E7C: 0x16E5C, + 0x0442: 0x0422, 0x2C42: 0x2C12, 0x24B6: 0x24D0, 0x2C5D: 0x2C2D, 0xA799: 0xA798, 0x1E930: 0x1E90E, + 0x01C8: 0x01C9, 0x01CC: 0x01CA, 0x0371: 0x0370, 0x1F0B: 0x1F03, 0x2C05: 0x2C35, 0x2C95: 0x2C94, + 0xA641: 0xA640, 0x105A3: 0x1057C, 0x0049: 0x0069, 0x0115: 0x0114, 0x10416: 0x1043E, 0x10CE8: 0x10CA8, + 0x118D1: 0x118B1, 0x16E4B: 0x16E6B, 0x16E4D: 0x16E6D, 0x1EA2: 0x1EA3, 0x1F66: 0x1F6E, 0xAB7D: 0x13AD, + 0x01FE: 0x01FF, 0x048D: 0x048C, 0x044A: 0x042A, 0xA655: 0xA654, 0x10590: 0x105B7, 0x0163: 0x0162, + 0x017E: 0x017D, 0xFF21: 0xFF41, 0x10CC2: 0x10C82, 0x01E6: 0x01E7, 0x10D7: 0x1C97, 0x04C7: 0x04C8, + 0x2D1E: 0x10BE, 0x1ED6: 0x1ED7, 0x2C97: 0x2C96, 0x2CB0: 0x2CB1, 0x13BD: 0xAB8D, 0x0150: 0x0151, + 0x01DD: 0x018E, 0xABA8: 0x13D8, 0x16E43: 0x16E63, 0x0422: 0x0442, 0x04FB: 0x04FA, 0x1ECD: 0x1ECC, + 0x2C84: 0x2C85, 0xA692: 0xA693, 0x16E71: 0x16E51, 0x00FB: 0x00DB, 0x03BF: 0x039F, 0x1E8B: 0x1E8A, + 0x1EE2: 0x1EE3, 0x2CA4: 0x2CA5, 0xA79D: 0xA79C, 0xABBE: 0x13EE, 0x10CA0: 0x10CE0, 0x01E1: 0x01E0, + 0x0345: 0x03B9, 0x118AB: 0x118CB, 0x1E928: 0x1E906, 0x2C69: 0x2C6A, 0xA76C: 0xA76D, 0x044C: 0x042C, + 0x1F34: 0x1F3C, 0x1C87: 0x0463, 0x1EEC: 0x1EED, 0x2C13: 0x2C43, 0xA689: 0xA688, 0x013C: 0x013B, + 0x03AD: 0x0388, 0x1ED2: 0x1ED3, 0x1EDC: 0x1EDD, 0x0071: 0x0051, 0x0450: 0x0400, 0xFF29: 0xFF49, + 0x10440: 0x10418, 0x104E7: 0x104BF, 0x1059A: 0x10573, 0x0496: 0x0497, 0x2C73: 0x2C72, 0x104D0: 0x104F8, + 0x16E6B: 0x16E4B, 0x017C: 0x017B, 0x2C0B: 0x2C3B, 0x118DC: 0x118BC, 0x0562: 0x0532, 0x1E5F: 0x1E5E, + 0x03D6: 0x03C0, 0x03DC: 0x03DD, 0x0452: 0x0402, 0x043F: 0x041F, 0x1E3E: 0x1E3F, 0x1E55: 0x1E54, + 0x01EE: 0x01EF, 0x03CF: 0x03D7, 0xAB7C: 0x13AC, 0x118D2: 0x118B2, 0x10E9: 0x1CA9, 0xA695: 0xA694, + 0x038C: 0x03CC, 0x2D1F: 0x10BF, 0x1C92: 0x10D2, 0x1E06: 0x1E07, 0x24C8: 0x24E2, 0xA668: 0xA669, + 0xA69B: 0xA69A, 0x04C4: 0x04C3, 0x0572: 0x0542, 0x2C90: 0x2C91, 0xA736: 0xA737, 0x10410: 0x10438, + 0x13F2: 0x13FA, 0x1E5C: 0x1E5D, 0x1ED0: 0x1ED1, 0x1F12: 0x1F1A, 0x1F71: 0x1FBB, 0x2CBB: 0x2CBA, + 0x1042A: 0x10402, 0x105B7: 0x10590, 0x00C2: 0x00E2, 0x1E91: 0x1E90, 0x1E908: 0x1E92A, 0x1F22: 0x1F2A, + 0xA693: 0xA692, 0x0546: 0x0576, 0x0548: 0x0578, 0x04A7: 0x04A6, 0x2C86: 0x2C87, 0x2CD0: 0x2CD1, + 0x0133: 0x0132, 0x01DF: 0x01DE, 0xA76D: 0xA76C, 0x10C97: 0x10CD7, 0x1E912: 0x1E934, 0x1E58: 0x1E59, + 0xA72E: 0xA72F, 0x10EC: 0x1CAC, 0x1E12: 0x1E13, 0x1F75: 0x1FCB, 0xABB3: 0x13E3, 0x1E911: 0x1E933, + 0x01E4: 0x01E5, 0x0472: 0x0473, 0x1F35: 0x1F3D, 0x2166: 0x2176, 0xA798: 0xA799, 0x104E6: 0x104BE, + 0x104F7: 0x104CF, 0x0564: 0x0534, 0x1C95: 0x10D5, 0x03C6: 0x03A6, 0x0405: 0x0455, 0x04C1: 0x04C2, + 0x1E3B: 0x1E3A, 0x025C: 0xA7AB, 0x00CE: 0x00EE, 0x0288: 0x01AE, 0x1EFC: 0x1EFD, 0x1F1C: 0x1F14, + 0x10571: 0x10598, 0x03C7: 0x03A7, 0x048E: 0x048F, 0x10D4: 0x1C94, 0x1E23: 0x1E22, 0x1F08: 0x1F00, + 0x00C7: 0x00E7, 0x01AF: 0x01B0, 0x039E: 0x03BE, 0x10B9: 0x2D19, 0x1E78: 0x1E79, 0x1E942: 0x1E920, + 0x0058: 0x0078, 0x00E9: 0x00C9, 0x16E5B: 0x16E7B, 0x0261: 0xA7AC, 0x104C8: 0x104F0, 0x0541: 0x0571, + 0x10A7: 0x2D07, 0x1E30: 0x1E31, 0x1FC9: 0x1F73, 0x2C34: 0x2C04, 0x2C89: 0x2C88, 0x019D: 0x0272, + 0x022F: 0x022E, 0x10420: 0x10448, 0x045D: 0x040D, 0x04CE: 0x04CD, 0x04D9: 0x04D8, 0xA73C: 0xA73D, + 0x10598: 0x10571, 0x00EA: 0x00CA, 0x01A0: 0x01A1, 0x04BF: 0x04BE, 0x1E939: 0x1E917, 0x0161: 0x0160, + 0x03A8: 0x03C8, 0x049D: 0x049C, 0x2CB7: 0x2CB6, 0x2CEB: 0x2CEC, 0x01CF: 0x01D0, 0x0473: 0x0472, + 0x2161: 0x2171, 0x1EF7: 0x1EF6, 0x10C85: 0x10CC5, 0x01F6: 0x0195, 0x1CA4: 0x10E4, 0x04E7: 0x04E6, + 0x1EDE: 0x1EDF, 0x1F72: 0x1FC8, 0x029E: 0xA7B0, 0xFF38: 0xFF58, 0x118BD: 0x118DD, 0x0052: 0x0072, + 0x04BC: 0x04BD, 0x0204: 0x0205, 0x0409: 0x0459, 0x10A3: 0x2D03, 0x1041C: 0x10444, 0x0176: 0x0177, + 0x0187: 0x0188, 0x014E: 0x014F, 0x1F06: 0x1F0E, 0x2C5E: 0x2C2E, 0xFF45: 0xFF25, 0x0059: 0x0079, + 0x010A: 0x010B, 0x1EF0: 0x1EF1, 0x2C64: 0x027D, 0xAB91: 0x13C1, 0xFF59: 0xFF39, 0x104D1: 0x104F9, + 0x00E8: 0x00C8, 0x048B: 0x048A, 0x2C1C: 0x2C4C, 0x13E1: 0xABB1, 0xFF28: 0xFF48, 0x104EF: 0x104C7, + 0x0468: 0x0469, 0x1F0E: 0x1F06, 0x04F4: 0x04F5, 0x1FEC: 0x1FE5, 0xA7BF: 0xA7BE, 0x1E90F: 0x1E931, + 0x01A9: 0x0283, 0x0388: 0x03AD, 0x1ED8: 0x1ED9, 0x1FB1: 0x1FB9, 0x2174: 0x2164, 0xA77C: 0xA77B, + 0x1041D: 0x10445, 0x01C9: 0x01C7, 0x10AC: 0x2D0C, 0x1FE0: 0x1FE8, 0xA7BD: 0xA7BC, 0x0418: 0x0438, + 0x0447: 0x0427, 0x0510: 0x0511, 0x10A8: 0x2D08, 0x1ECB: 0x1ECA, 0x026B: 0x2C62, 0x0074: 0x0054, + 0x0222: 0x0223, 0x10599: 0x10572, 0x16E6C: 0x16E4C, 0x1D7D: 0x2C63, 0x13CE: 0xAB9E, 0x2D09: 0x10A9, + 0x1EC0: 0x1EC1, 0x0073: 0x0053, 0x0416: 0x0436, 0x053D: 0x056D, 0x16E7B: 0x16E5B, 0x1E2C: 0x1E2D, + 0x16E6E: 0x16E4E, 0x0424: 0x0444, 0x04EE: 0x04EF, 0x1E80: 0x1E81, 0x1E91E: 0x1E940, 0x017F: 0x0073, + 0x0209: 0x0208, 0x1E82: 0x1E83, 0xA783: 0xA782, 0x118CD: 0x118AD, 0x0464: 0x0465, 0x10E6: 0x1CA6, + 0x01B8: 0x01B9, 0x1E00: 0x1E01, 0x1E71: 0x1E70, 0x00D5: 0x00F5, 0x012C: 0x012D, 0x1CBA: 0x10FA, + 0x1EFE: 0x1EFF, 0x2CBA: 0x2CBB, 0x026C: 0xA7AD, 0x13BB: 0xAB8B, 0x105B8: 0x10591, 0x0505: 0x0504, + 0x1C94: 0x10D4, 0x118C0: 0x118A0, 0x16E61: 0x16E41, 0x0453: 0x0403, 0x2CC1: 0x2CC0, 0x16E67: 0x16E47, + 0x00EC: 0x00CC, 0x0122: 0x0123, 0xA763: 0xA762, 0xAB8B: 0x13BB, 0x104EB: 0x104C3, 0x105BB: 0x10594, + 0x10CEB: 0x10CAB, 0x1E91D: 0x1E93F, 0x013A: 0x0139, 0x217F: 0x216F, 0x104FB: 0x104D3, 0x010D: 0x010C, + 0xA72D: 0xA72C, 0x2D1C: 0x10BC, 0x1FB8: 0x1FB0, 0x2165: 0x2175, 0x2C21: 0x2C51, 0xA765: 0xA764, + 0x1E917: 0x1E939, 0x010C: 0x010D, 0x0164: 0x0165, 0x1FD0: 0x1FD8, 0x24BD: 0x24D7, 0x10580: 0x105A7, + 0x03AC: 0x0386, 0x0499: 0x0498, 0x2CC4: 0x2CC5, 0xAB9E: 0x13CE, 0x104DB: 0x104B3, 0x0399: 0x03B9, + 0x1E04: 0x1E05, 0x1E73: 0x1E72, 0x1EB9: 0x1EB8, 0x10C82: 0x10CC2, 0x1E43: 0x1E42, 0x1E66: 0x1E67, + 0x104B3: 0x104DB, 0x104B7: 0x104DF, 0x10C89: 0x10CC9, 0x1F13: 0x1F1B, 0x1F7B: 0x1FEB, 0x041C: 0x043C, + 0xA64B: 0x1C88, 0xA7BE: 0xA7BF, 0xFF4E: 0xFF2E, 0x10576: 0x1059D, 0x10589: 0x105B0, 0x006B: 0x004B, + 0x0223: 0x0222, 0x10D3: 0x1C93, 0x1F19: 0x1F11, 0x13C6: 0xAB96, 0x014D: 0x014C, 0x0431: 0x0411, + 0x2C24: 0x2C54, 0xA7C5: 0x0282, 0x022E: 0x022F, 0x2C48: 0x2C18, 0xAB77: 0x13A7, 0x0248: 0x0249, + 0xA758: 0xA759, 0x047D: 0x047C, 0x0540: 0x0570, 0x2D19: 0x10B9, 0x2C81: 0x2C80, 0xA688: 0xA689, + 0xFF2C: 0xFF4C, 0x01D1: 0x01D2, 0x0444: 0x0424, 0x105AE: 0x10587, 0x13C9: 0xAB99, 0x10CE2: 0x10CA2, + 0x118AA: 0x118CA, 0x042A: 0x044A, 0x13F8: 0x13F0, 0xA742: 0xA743, 0xFF24: 0xFF44, 0x10449: 0x10421, + 0x0423: 0x0443, 0x1E5D: 0x1E5C, 0xA7B5: 0xA7B4, 0x104E1: 0x104B9, 0x0061: 0x0041, 0x1EC3: 0x1EC2, + 0x13CA: 0xAB9A, 0xFF50: 0xFF30, 0x104B1: 0x104D9, 0x118C8: 0x118A8, 0x0532: 0x0562, 0x2C4D: 0x2C1D, + 0x1EA6: 0x1EA7, 0x2CF2: 0x2CF3, 0x10417: 0x1043F, 0x03E5: 0x03E4, 0x0578: 0x0548, 0x042D: 0x044D, + 0x1E92: 0x1E93, 0x10415: 0x1043D, 0x00D2: 0x00F2, 0x0147: 0x0148, 0x1F01: 0x1F09, 0xFF30: 0xFF50, + 0x10CF0: 0x10CB0, 0x04F1: 0x04F0, 0x1EE1: 0x1EE0, 0x1C9E: 0x10DE, 0x2C2D: 0x2C5D, 0x13D3: 0xABA3, + 0x118B8: 0x118D8, 0x16E4A: 0x16E6A, 0x046B: 0x046A, 0x10D1: 0x1C91, 0x1F0D: 0x1F05, 0xFF32: 0xFF52, + 0x10F1: 0x1CB1, 0x1F0A: 0x1F02, 0x1E24: 0x1E25, 0xA740: 0xA741, 0x13D4: 0xABA4, 0x10CD6: 0x10C96, + 0x0144: 0x0143, 0x04AD: 0x04AC, 0x1E64: 0x1E65, 0x1F4C: 0x1F44, 0xA66D: 0xA66C, 0xA7A5: 0xA7A4, + 0x13AE: 0xAB7E, 0xAB81: 0x13B1, 0x04E5: 0x04E4, 0x050A: 0x050B, 0x1E919: 0x1E93B, 0x10CD9: 0x10C99, + 0x16E5C: 0x16E7C, 0x2C5B: 0x2C2B, 0x2C7E: 0x023F, 0xA750: 0xA751, 0x0459: 0x0409, 0x1E63: 0x1E62, + 0x2C5C: 0x2C2C, 0xA75B: 0xA75A, 0xABB0: 0x13E0, 0x0177: 0x0176, 0x1E9B: 0x1E61, 0x118B6: 0x118D6, + 0x10C2: 0x2D22, 0xA757: 0xA756, 0xA65A: 0xA65B, 0xAB71: 0x13A1, 0x10CD5: 0x10C95, 0x020D: 0x020C, + 0x2D23: 0x10C3, 0x1E1F: 0x1E1E, 0x1E6F: 0x1E6E, 0x0240: 0x2C7F, 0x2CC3: 0x2CC2, 0xA74B: 0xA74A, + 0x024E: 0x024F, 0x1CA8: 0x10E8, 0x10B7: 0x2D17, 0x13C0: 0xAB90, 0x10C87: 0x10CC7, 0x118B5: 0x118D5, + 0x1E902: 0x1E924, 0x0105: 0x0104, 0x021F: 0x021E, 0x1EA7: 0x1EA6, 0xFF48: 0xFF28, 0x104B0: 0x104D8, + 0x1058E: 0x105B5, 0x1E933: 0x1E911, 0x046D: 0x046C, 0x1E0B: 0x1E0A, 0x10D6: 0x1C96, 0x1E1E: 0x1E1F, + 0x1F2F: 0x1F27, 0x104BE: 0x104E6, 0x10CE3: 0x10CA3, 0x0127: 0x0126, 0x03D7: 0x03CF, 0x24B9: 0x24D3, + 0x2C11: 0x2C41, 0xA7A3: 0xA7A2, 0x105A7: 0x10580, 0x00CF: 0x00EF, 0x1ECC: 0x1ECD, 0x10F5: 0x1CB5, + 0x1E4B: 0x1E4A, 0xA64D: 0xA64C, 0x1041E: 0x10446, 0x104BB: 0x104E3, 0x104CF: 0x104F7, 0x0117: 0x0116, + 0x04DF: 0x04DE, 0x118C1: 0x118A1, 0x0443: 0x0423, 0x1E5E: 0x1E5F, 0x2CBF: 0x2CBE, 0x16E7D: 0x16E5D, + 0x01CD: 0x01CE, 0x2C66: 0x023E, 0x2C16: 0x2C46, 0x1044D: 0x10425, 0x043D: 0x041D, 0x217E: 0x216E, + 0x03AF: 0x038A, 0x048A: 0x048B, 0x2D0A: 0x10AA, 0x1EA8: 0x1EA9, 0x24D7: 0x24BD, 0x24E0: 0x24C6, + 0x01D3: 0x01D4, 0x0225: 0x0224, 0x10C9D: 0x10CDD, 0x2C88: 0x2C89, 0x10C8C: 0x10CCC, 0x2132: 0x214E, + 0x0205: 0x0204, 0x10A5: 0x2D05, 0x044F: 0x042F, 0x10FE: 0x1CBE, 0xA65D: 0xA65C, 0xA682: 0xA683, + 0xA75F: 0xA75E, 0x10435: 0x1040D, 0x0411: 0x0431, 0x0435: 0x0415, 0x104C5: 0x104ED, 0x1E47: 0x1E46, + 0x118BA: 0x118DA, 0x019E: 0x0220, 0x044B: 0x042B, 0x1E48: 0x1E49, 0x1EB5: 0x1EB4, 0x0142: 0x0141, + 0x0463: 0x0462, 0x13B0: 0xAB80, 0xAB98: 0x13C8, 0x03EE: 0x03EF, 0x04D6: 0x04D7, 0x1EBE: 0x1EBF, + 0x10400: 0x10428, 0x039F: 0x03BF, 0x0511: 0x0510, 0xA658: 0xA659, 0x10CCE: 0x10C8E, 0x04CC: 0x04CB, + 0x2D22: 0x10C2, 0x1C81: 0x0434, 0x1EF1: 0x1EF0, 0x1F67: 0x1F6F, 0xA64A: 0xA64B, 0xA797: 0xA796, + 0x0215: 0x0214, 0x04B0: 0x04B1, 0x24D2: 0x24B8, 0xA754: 0xA755, 0xABA7: 0x13D7, 0x104F2: 0x104CA, + 0x04F7: 0x04F6, 0x10BB: 0x2D1B, 0x10D9: 0x1C99, 0x10DD: 0x1C9D, 0x1EC7: 0x1EC6, 0xFF3A: 0xFF5A, + 0x014F: 0x014E, 0x03A0: 0x03C0, } diff --git a/core_matcher.go b/core_matcher.go index bada0e0..52b1086 100644 --- a/core_matcher.go +++ b/core_matcher.go @@ -149,7 +149,13 @@ func (m *coreMatcher) deletePatterns(_ X) error { // This is a leftover from previous times, is only used by tests, but it's used by a *lot* // and it's a convenient API for testing. func (m *coreMatcher) matchesForJSONEvent(event []byte) ([]X, error) { - fields, _ := newJSONFlattener().Flatten(event, m.getSegmentsTreeTracker()) + return m.matchesForJSONWithFlattener(event, newJSONFlattener()) +} + +// if your test is a benchmark, call newJSONFlattener and pass it to this routine, matchesForJSONWithFlattener +// because newJSONFlattener() is fairly heavyweight and you want it out of the benchmark loop +func (m *coreMatcher) matchesForJSONWithFlattener(event []byte, f Flattener) ([]X, error) { + fields, _ := f.Flatten(event, m.getSegmentsTreeTracker()) return m.matchesForFields(fields) } diff --git a/flatten_json.go b/flatten_json.go index 9780d14..0c6ba88 100644 --- a/flatten_json.go +++ b/flatten_json.go @@ -214,7 +214,7 @@ func (fj *flattenJSON) readObject(pathNode SegmentsTreeTracker) error { } var val []byte - isQNumber := false + isNumber := false switch ch { case '"': if fj.skipping > 0 || !memberIsUsed { @@ -233,7 +233,10 @@ func (fj *flattenJSON) readObject(pathNode SegmentsTreeTracker) error { val, err = fj.readLiteral(nullBytes) isLeaf = true case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, isQNumber, err = fj.readNumber() + val, err = fj.readNumber() + if err == nil { + isNumber = true + } isLeaf = true case '[': if !pathNode.IsSegmentUsed(memberName) { @@ -296,7 +299,7 @@ func (fj *flattenJSON) readObject(pathNode SegmentsTreeTracker) error { } if val != nil { if memberIsUsed { - fj.storeObjectMemberField(pathNode.PathForSegment(memberName), arrayTrail, val, isQNumber) + fj.storeObjectMemberField(pathNode.PathForSegment(memberName), arrayTrail, val, isNumber) fieldsCount-- } } @@ -340,7 +343,7 @@ func (fj *flattenJSON) readArray(pathName []byte, pathNode SegmentsTreeTracker) for { ch := fj.ch() var val []byte // resets on each loop - isQNumber := false + isNumber := false switch state { case fjInArrayState: // bypass space before element value. A bit klunky but allows for immense simplification @@ -365,7 +368,10 @@ func (fj *flattenJSON) readArray(pathName []byte, pathNode SegmentsTreeTracker) val, err = fj.readLiteral(nullBytes) isLeaf = true case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - val, isQNumber, err = fj.readNumber() + val, err = fj.readNumber() + if err == nil { + isNumber = true + } isLeaf = true case '{': if fj.skipping == 0 { @@ -398,7 +404,7 @@ func (fj *flattenJSON) readArray(pathName []byte, pathNode SegmentsTreeTracker) if val != nil { if fj.skipping == 0 { fj.stepOneArrayElement() - fj.storeArrayElementField(pathName, val, isQNumber) + fj.storeArrayElementField(pathName, val, isNumber) } } state = fjAfterValueState @@ -427,13 +433,10 @@ func (fj *flattenJSON) readArray(pathName []byte, pathNode SegmentsTreeTracker) * these higher-level funcs are going to advance the pointer after each invocation */ -func (fj *flattenJSON) readNumber() ([]byte, bool, error) { +func (fj *flattenJSON) readNumber() ([]byte, error) { // points at the first character in the number numStart := fj.eventIndex state := fjNumberStartState - isQNumber := false - fracStart := 0 - expStart := 0 for { ch := fj.ch() switch state { @@ -450,38 +453,33 @@ func (fj *flattenJSON) readNumber() ([]byte, bool, error) { // no-op case '.': state = fjNumberFracState - fracStart = fj.eventIndex + 1 case 'e', 'E': state = fjNumberAfterEState - expStart = fj.eventIndex + 1 case ',', ']', '}', ' ', '\t', '\n', '\r': fj.eventIndex-- - return fj.event[numStart : fj.eventIndex+1], true, nil + return fj.event[numStart : fj.eventIndex+1], nil default: - return nil, false, fj.error(fmt.Sprintf("illegal char '%c' in number", ch)) + return nil, fj.error(fmt.Sprintf("illegal char '%c' in number", ch)) } case fjNumberFracState: switch ch { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': // no-op case ',', ']', '}', ' ', '\t', '\n', '\r': - fractionalDigits := (expStart - 1) - fracStart - isQNumber = fractionalDigits <= MaxFractionalDigits fj.eventIndex-- bytes := fj.event[numStart : fj.eventIndex+1] - return bytes, isQNumber, nil + return bytes, nil case 'e', 'E': state = fjNumberAfterEState - expStart = fj.eventIndex + 1 default: - return nil, false, fj.error(fmt.Sprintf("illegal char '%c' in number", ch)) + return nil, fj.error(fmt.Sprintf("illegal char '%c' in number", ch)) } case fjNumberAfterEState: switch ch { case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': // no-op default: - return nil, false, fj.error(fmt.Sprintf("illegal char '%c' after 'e' in number", ch)) + return nil, fj.error(fmt.Sprintf("illegal char '%c' after 'e' in number", ch)) } state = fjNumberExpState @@ -490,27 +488,14 @@ func (fj *flattenJSON) readNumber() ([]byte, bool, error) { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': // no-op case ',', ']', '}', ' ', '\t', '\n', '\r': - fractionalDigits := 0 - if fracStart != 0 { - fractionalDigits = (expStart - 1) - fracStart - if fractionalDigits > MaxFractionalDigits { - if expStart != 0 { - exp, err := strconv.ParseInt(string(fj.event[expStart:fj.eventIndex]), 10, 32) - if err == nil { - fractionalDigits -= int(exp) - } - } - } - } - isQNumber = fractionalDigits <= MaxFractionalDigits fj.eventIndex-- - return fj.event[numStart : fj.eventIndex+1], isQNumber, nil + return fj.event[numStart : fj.eventIndex+1], nil default: - return nil, false, fj.error(fmt.Sprintf("illegal char '%c' in exponent", ch)) + return nil, fj.error(fmt.Sprintf("illegal char '%c' in exponent", ch)) } } if fj.step() != nil { - return nil, false, fj.error("event truncated in number") + return nil, fj.error("event truncated in number") } } } @@ -811,6 +796,8 @@ func (fj *flattenJSON) readHexUTF16(from int) ([]byte, int, error) { if hexDigitCount == 4 { hexString := string(fj.event[from-3 : from+1]) r, _ := strconv.ParseUint(hexString, 16, 16) + // parsing 4 hex digits can't overflow a uint16 + //nolint:gosec codepoints = append(codepoints, uint16(r)) state = fjStartEscapeState } @@ -831,14 +818,14 @@ func (fj *flattenJSON) readHexUTF16(from int) ([]byte, int, error) { // its own snapshot of the array-trail data, because it'll be different for each array element // NOTE: The profiler says this is the most expensive function in the whole matchesForJSONEvent universe, presumably // because of the necessity to construct a new arrayTrail for each element. -func (fj *flattenJSON) storeArrayElementField(path []byte, val []byte, isQNumber bool) { - f := Field{Path: path, ArrayTrail: make([]ArrayPos, len(fj.arrayTrail)), Val: val, IsQNumber: isQNumber} +func (fj *flattenJSON) storeArrayElementField(path []byte, val []byte, isNumber bool) { + f := Field{Path: path, ArrayTrail: make([]ArrayPos, len(fj.arrayTrail)), Val: val, IsNumber: isNumber} copy(f.ArrayTrail, fj.arrayTrail) fj.fields = append(fj.fields, f) } -func (fj *flattenJSON) storeObjectMemberField(path []byte, arrayTrail []ArrayPos, val []byte, isQNumber bool) { - fj.fields = append(fj.fields, Field{Path: path, ArrayTrail: arrayTrail, Val: val, IsQNumber: isQNumber}) +func (fj *flattenJSON) storeObjectMemberField(path []byte, arrayTrail []ArrayPos, val []byte, isNumber bool) { + fj.fields = append(fj.fields, Field{Path: path, ArrayTrail: arrayTrail, Val: val, IsNumber: isNumber}) } func (fj *flattenJSON) enterArray() { diff --git a/flattener.go b/flattener.go index 8490498..999ef00 100644 --- a/flattener.go +++ b/flattener.go @@ -58,5 +58,5 @@ type Field struct { Path []byte Val []byte ArrayTrail []ArrayPos - IsQNumber bool + IsNumber bool } diff --git a/numbers.go b/numbers.go index 2439af9..8b9d524 100644 --- a/numbers.go +++ b/numbers.go @@ -1,121 +1,54 @@ package quamina import ( - "encoding/binary" "errors" + "fmt" "strconv" ) // You can't easily build automata to compare numbers based on either the decimal notation found -// in text data or the internal floating-point bits. Therefore, for a restricted subset of numbers, -// we define a 7-byte (14 hex digit) representation that facilitates building automata to support -// equality and ordering comparison. -// -// The representation supports 10**15 numbers. The first three are: -// decimal: -5_000_000_000, -4_999_999_999.99999, -4_999_999_999.99998, ... -// 14-byte: 00000000000000, 00000000000009, 00000000000014 -// and the last three are -// decimal: .., 4_999_999_999.99998, 4_999_999_999.99999, 5_000_000_000 -// 14-byte: 2386F26FC0FFEC, 2386F26FC0FFF6, 2386F26FC10000 -// -// In English: all numbers that are between negative and positive 5 billion inclusive, with up to five -// digits after the decimal point. -// These numbers have fifteen decimal digits of precision, which is what double floats can offer. -// They include most numbers that are used in practice, including prices, occurrence counts, size -// measurements, and so on. -// Examples of numbers that do NOT meet these criteria include AWS account numbers, some telephone -// numbers, and cryptographic keys/signatures. For these, treatment as strings seems to produce -// satisfactory results for equality testing. +// in text data or the internal floating-point bits. Therefore, we map floating-point numbers +// (which is what JSON numbers basically are) to comparable slices of 7-bit bytes which preserve the +// numbers' ordering. Versions of Quamina up to 1.3 used a home-grown format which used 14 hex digits +// to represent a subset of numbers. This has now been replaced by Arne Hormann's "numbits" +// construct, see numbits.go. It uses up to 10 base128 bytes to represent the entire range of float64 numbers. +// Both this file and numbits.go are very short, but I'm keeping them separated because someone might +// figure out a still-better serialization of numbers and then this part wouldn't have to change. // In Quamina these are called "Q numbers". -// How It's Done + // There is considerable effort to track, at the NFA level, which NFAs are built to match field values -// that are Q numbers; see vmFields.hasQNumbers. Similarly, the JSONFlattener, since it has to +// that are Q numbers; see vmFields.hasNumbers. Similarly, the JSONFlattener, since it has to // look at all the digits in a number in order to parse it, can keep track of whether it can be made // a Q number. The key benefit of this is in valueMatcher.transitionOn, which incurs the cost of // making a Q number only if it is known that the valueMatcher's NFA can benefit from it and // that the number in the incoming event can in fact be made a Q number. -const ( - TenE6 = 1e6 - FiveBillion = 5e9 - Hexes = "0123456789ABCDEF" - MaxFractionalDigits = 5 -) - type qNumber []byte // qNumFromBytes works out whether a string representing a number falls within the // limits imposed for Q numbers. It is heavily optimized and relies on the form // of the number already having been validated, e.g. by flattenJSON(). func qNumFromBytes(bytes []byte) (qNumber, error) { - // shortcut: The shorest number with more than 5 fractional digits is like 0.123456 - if len(bytes) < 8 { - numeric, err := strconv.ParseFloat(string(bytes), 64) - if err != nil { - return nil, errors.New("not a float") // should never happen, json parser upstream - } - return qNumFromFloat(numeric) - } - // compute number of fractional digits. The loop below relies on the fact that anything between '.' and either - // 'e' or the end of the string must be a digit, as must anything between 'e' and the end of the string. - //. NOTE: This will be fooled by "35.000000" - fracStart := 0 - expStart := 0 - index := 0 - var utf8Byte byte - fractionalDigits := 0 -ForEachByte: - for index, utf8Byte = range bytes { - switch utf8Byte { - case '.': - fracStart = index + 1 - case 'e', 'E': - expStart = index + 1 - break ForEachByte - } - } - if fracStart != 0 { - fractionalDigits = index - fracStart - } - // if too many fractional digits, perhaps the exponent will push the '.' to the right - if fractionalDigits > MaxFractionalDigits { - if expStart != 0 { - exp, err := strconv.ParseInt(string(bytes[expStart:]), 10, 32) - if err == nil { - fractionalDigits -= int(exp) - } - } - } - if fractionalDigits > MaxFractionalDigits { - return nil, errors.New("more than 5 fractional digits") - } - numeric, err := strconv.ParseFloat(string(bytes), 64) if err != nil { - return nil, errors.New("not a float") // shouldn't happen, upstream parser should prvent + return nil, errors.New("not a float") // should never happen, json parser upstream } - return qNumFromFloat(numeric) + return qNumFromFloat(numeric), nil } -func qNumFromFloat(f float64) (qNumber, error) { - if f < -FiveBillion || f > FiveBillion { - return nil, errors.New("value must be between -5e9 and +5e9 inclusive") - } - value := uint64(TenE6 * (FiveBillion + f)) - return toHexStringSkippingFirstByte(value), nil +// qNumFromFLoat is here mostly to support testing +func qNumFromFloat(f float64) qNumber { + return numbitsFromFloat64(f).toQNumber() } -func toHexStringSkippingFirstByte(value uint64) []byte { - var buf [8]byte - binary.BigEndian.PutUint64(buf[:], value) - var outputChars [14]byte - for i, utf8Byte := range buf { - if i == 0 { - continue +// for debugging +func (q qNumber) String() string { + ret := "" + for i, b := range q { + if i != 0 { + ret += "-" } - pos := (i - 1) * 2 - outputChars[pos] = Hexes[utf8Byte>>4] - outputChars[pos+1] = Hexes[buf[i]&0xf] + ret += fmt.Sprintf("%02x", b) } - return outputChars[:] + return ret } diff --git a/numbers_test.go b/numbers_test.go index eeab562..de807de 100644 --- a/numbers_test.go +++ b/numbers_test.go @@ -6,29 +6,72 @@ import ( "math" "math/rand" "sort" + "strconv" "strings" "testing" ) +func BenchmarkNumberMatching(b *testing.B) { + // we’re going to have a pattern that matches one of ten random floats, then we're going to throw + // 10K random events at it, 10% of which will match the pattern + rand.Seed(2325) + pattern := `{"x": [` + var targets []string + for i := 0; i < 10; i++ { + numString := fmt.Sprintf("%.6f", rand.Float64()) + targets = append(targets, numString) + if i != 0 { + pattern += ", " + } + pattern += numString + } + pattern += `]}` + cm := newCoreMatcher() + flattener := newJSONFlattener() + err := cm.addPattern("P", pattern) + if err != nil { + b.Error("addP") + } + b.ResetTimer() + b.ReportAllocs() + targetInd := 0 + calls := 0 + for i := 0; i < b.N; i++ { + if i%2 == 0 { + val := targets[targetInd] + event := `{"x":` + val + "}" + matches, err := cm.matchesForJSONWithFlattener([]byte(event), flattener) + calls++ + if err != nil { + b.Error("match target") + } + if len(matches) == 0 { + b.Error("Missed target") + } + targetInd = (targetInd + 1) % len(targets) + } else { + event := `{"x":` + fmt.Sprintf("%.6f", rand.Float64()) + "}" + _, err := cm.matchesForJSONEvent([]byte(event)) + if err != nil { + b.Error("match non-target") + } + } + } +} + func TestWildlyVaryingNumbersAreComparable(t *testing.T) { data := []float64{ - -FiveBillion, -4_999_999_999.99999, -4_999_999_999.99998, -4_999_999_999.99997, + -5_000_000_000, -4_999_999_999.99999, -4_999_999_999.99998, -4_999_999_999.99997, -999999999.99999, -999999999.99, -10000, -122.413496, -0.000002, 0, 0.000001, 3.8, 3.9, 11, 12, 122.415028, 2.5e4, 999999999.999998, 999999999.999999, - 4_999_999_999.99997, 4_999_999_999.99998, 4_999_999_999.99999, FiveBillion, + 4_999_999_999.99997, 4_999_999_999.99998, 4_999_999_999.99999, 5_000_000_000, } for i := 1; i < len(data); i++ { - s0, err := qNumFromFloat(data[i-1]) - if err != nil { - t.Error("s0") - } - s1, err := qNumFromFloat(data[i]) - if err != nil { - t.Error("s1") - } + s0 := qNumFromFloat(data[i-1]) + s1 := qNumFromFloat(data[i]) if bytes.Compare(s0, s1) >= 0 { t.Errorf("FOO %d / %f - %f", i, data[i-1], data[i]) - fmt.Printf("lo %s0\nhi %s\n", s0, s1) + fmt.Printf("lo %s %f\nhi %s %f\n", s0, data[i-1], s1, data[i]) } } } @@ -57,32 +100,21 @@ func TestShowBigSmall(t *testing.T) { if err != nil { t.Errorf("Problem with %s: %s", low, err.Error()) } - fmt.Printf("%s %s\n", low, c) + fmt.Printf("%s <%s>\n", low, c) } for _, high := range highs { c, err := qNumFromBytes([]byte(high)) if err != nil { t.Errorf("Problem with %s: %s", high, err.Error()) } - fmt.Printf("%s %s\n", high, c) + fmt.Printf("%s <%s>\n", high, c) } } func TestBadNumbers(t *testing.T) { var err error - _, err = qNumFromFloat(9999999999999999999) - if err == nil { - t.Error("took 20 9's") - } - _, err = qNumFromFloat(9000000000000) - if err == nil { - t.Error("took huge number") - } bads := []string{ - "5_000_000_001", "-5_000_000_001", - "5_000_000_000.001", "-5_000_000_000.001", - "3.1234567", "-5.1234567890", - "0.0000001", "-0.0000001", "124x", + "xy", "- 53", "124x", "1.5ee7", } for _, bad := range bads { _, err = qNumFromBytes([]byte(bad)) @@ -92,27 +124,11 @@ func TestBadNumbers(t *testing.T) { } } -func TestExponentialDigits(t *testing.T) { - goods := []string{ - "3.1234567e3", "-.123456789012345e10", - "0.0000001e3", "-0.0000001e2", - } - for _, good := range goods { - _, err := qNumFromBytes([]byte(good)) - if err != nil { - t.Error("Rejected: " + good + ": " + err.Error()) - } - } -} - func TestFloatVariants(t *testing.T) { f := []float64{350, 350.0, 350.0000000000, 3.5e2} var o []qNumber for _, s := range f { - c, err := qNumFromFloat(s) - if err != nil { - t.Errorf("qnum err on %f: %s", s, err.Error()) - } + c := qNumFromFloat(s) o = append(o, c) } for i := 1; i < len(o); i++ { @@ -149,20 +165,12 @@ func TestOrdering(t *testing.T) { sort.Float64s(in) var out []string for _, f := range in { - c, err := qNumFromFloat(f) - if err != nil { - t.Errorf("failed on %f", f) - } + c := qNumFromFloat(f) out = append(out, string(c)) } if !sort.StringsAreSorted(out) { t.Errorf("Not sorted") } - for i, c := range out { - if len(c) != 14 { - t.Errorf("%s: %d at %d", c, len(c), i) - } - } } func TestMatcherNumerics(t *testing.T) { @@ -170,6 +178,21 @@ func TestMatcherNumerics(t *testing.T) { shoulds := []string{ "35", "3.5e1", "35.000", "0.000035e6", } + for _, should := range shoulds { + f, err := strconv.ParseFloat(should, 64) + if err != nil { + t.Error("Parse? " + err.Error()) + } + q, err := qNumFromBytes([]byte(should)) + if err != nil { + t.Error("QF: " + err.Error()) + } + fmt.Printf("%f <%s>\n", f, q) + if f != 35.0 { + t.Error("Not 35!") + } + } + template := `{"x": NUM}` m := newCoreMatcher() err := m.addPattern("35", p) diff --git a/numbits.go b/numbits.go new file mode 100644 index 0000000..6da2f92 --- /dev/null +++ b/numbits.go @@ -0,0 +1,58 @@ +package quamina + +import ( + "math" +) + +// numbits is an alternative binary representation of float64 numbers. +// float64 are stored as (sign | exponent | mantissa) +// with 1 bit sign, 11 bits exponent, 52 bits mantissa +// They can be represented as [8]byte or as string and can be created from +// these representations. +// All possible float64 values are representable as numbits. +// numbits were implemented by Arne Hormann for Quamina; he later discovered +// that an equivalent representation was used long ago in the disk format of DB2. +// +// Arne's implementation carefully handled NaN, -0, and infinities, but +// Quamina ignores those issues because a combination of JSON rules and +// Quamina's parsers prevent those values from occurring. +type numbits uint64 + +// numbitsFromFloat64 converts a float64 value to its numbits representation. +func numbitsFromFloat64(f float64) numbits { + u := math.Float64bits(f) + // transform without branching (inverse of numbits.Float64): + // if high bit is 0, xor with sign bit 1 << 63, else negate (xor with ^0) + mask := (u>>63)*^uint64(0) | (1 << 63) + return numbits(u ^ mask) +} + +const MaxBytesInEncoding = 10 + +// toQNumber turns a numbits into a minimal variable-width encoding that preservers equality and ordering. +// Storing 8 bytes of data in base-128 would in principle require 10 bytes, but it turns out that since +// the byte-string encoding is big-endian, trailing zeroes don't count, so the encoding can be as short as +// one byte. +// Idea and some code by Axel Wagner +func (nb numbits) toQNumber() []byte { + // Iterate through the numbits 7 bits at a time, right to left, first bypassing bits that generate + // trailing zeroes in the encoded form. Note that index could go to 0 if the numbits value was uint(0) + // but that value represents NaN and can't appear in JSON + trailingZeroes := 0 + var index int + for index = MaxBytesInEncoding - 1; index >= 0; index-- { + if nb&0x7f != 0 { + break + } + trailingZeroes++ + nb >>= 7 + } + + // now we fill in the byte encoding for the digits up to the last non-zero + b := make([]byte, MaxBytesInEncoding-trailingZeroes) + for ; index >= 0; index-- { + b[index] = byte(nb & 0x7f) + nb >>= 7 + } + return b[:] +} diff --git a/numbits_test.go b/numbits_test.go new file mode 100644 index 0000000..bbfd86e --- /dev/null +++ b/numbits_test.go @@ -0,0 +1,71 @@ +package quamina + +import ( + "bytes" + "math" + "math/rand" + "sort" + "testing" + "unicode/utf8" +) + +func TestToQNumber(t *testing.T) { + rand.Seed(230948) + var nbs []numbits + var utf8s [][]byte + for i := 0; i < 10000; i++ { + nb := numbits(rand.Uint64()) + nbs = append(nbs, nb) + nbu := nb.toQNumber() + if !utf8.Valid(nbu) { + t.Error("Invalid UTF8!") + } + utf8s = append(utf8s, nbu) + } + for i := 1; i < len(nbs); i++ { + uCompare := bytes.Compare(utf8s[i], utf8s[i-1]) + if nbs[i] > nbs[i-1] { + if uCompare <= 0 { + t.Error("Out of order 1") + } + } else if nbs[i] < nbs[i-1] { + if uCompare >= 0 { + t.Error("Out of order 2") + } + } else if nbs[i] == nbs[i-1] { + if uCompare != 0 { + t.Error("Out of order 3") + } + } + } +} + +var ( + // boundaries of floating point value ranges + f64Zero = math.Float64frombits(0b0_00000000000_0000_00000000_00000000_00000000_00000000_00000000_00000000) + f64SubnormLo = math.Float64frombits(0b0_00000000000_0000_00000000_00000000_00000000_00000000_00000000_00000001) + f64SubnormHi = math.Float64frombits(0b0_00000000000_1111_11111111_11111111_11111111_11111111_11111111_11111111) + f64NormLoLo = math.Float64frombits(0b0_00000000001_0000_00000000_00000000_00000000_00000000_00000000_00000000) + f64NormLoHi = math.Float64frombits(0b0_00000000001_1111_11111111_11111111_11111111_11111111_11111111_11111111) + f64NormHiLo = math.Float64frombits(0b0_11111111110_0000_00000000_00000000_00000000_00000000_00000000_00000000) + f64NormHiHi = math.Float64frombits(0b0_11111111110_1111_11111111_11111111_11111111_11111111_11111111_11111111) + specials = []float64{f64Zero, f64SubnormHi, f64SubnormLo, f64NormLoLo, f64NormLoHi, f64NormHiLo, f64NormHiHi} +) + +func TestNumbits_Compare(t *testing.T) { + rand.Seed(203785) + floats := append([]float64{}, specials...) + + for i := 0; i < 1000; i++ { + floats = append(floats, rand.Float64()) + } + sort.Float64s(floats) + last := numbitsFromFloat64(floats[0]) + for i := 1; i < len(floats); i++ { + this := numbitsFromFloat64(floats[i]) + if last >= this { + t.Error("out of order") + } + last = this + } +} diff --git a/quamina.go b/quamina.go index 84e3ff3..1db099e 100644 --- a/quamina.go +++ b/quamina.go @@ -144,6 +144,5 @@ func (q *Quamina) MatchesForEvent(event []byte) ([]X, error) { if err != nil { return nil, err } - matches, err := q.matcher.matchesForFields(fields) - return matches, err + return q.matcher.matchesForFields(fields) } diff --git a/value_matcher.go b/value_matcher.go index ec97557..52d5541 100644 --- a/value_matcher.go +++ b/value_matcher.go @@ -13,10 +13,10 @@ type bufpair struct { // valueMatcher represents a byte-driven finite automaton (FA). The table needs to be the // equivalent of a map[byte][]nextState and is represented by smallTable. // In this implementation all the FAs are nondeterministic, which means each -// byte can cause transfers to multiple other states. The basic algorithm is to compute the FA +// byte can cause transfers to multiple other states. We compute the FA // for a pattern and merge with any existing FA. -// In some (common) cases there is only one value byte sequence forward for a field -// i.e. a string-valued field with only one string match. In this case, the FA +// In some (common) cases there is only one matching value present for some field, +// e.g. a string-valued field with only one string match. In this case, the FA // will be null and the value being matched has to exactly equal the singletonMatch // field; if so, the singletonTransition is the return value. This is to avoid // having a long chain of smallTables each with only one entry. @@ -30,7 +30,7 @@ type vmFields struct { startTable *smallTable singletonMatch []byte singletonTransition *fieldMatcher - hasQNumbers bool + hasNumbers bool isNondeterministic bool } @@ -72,7 +72,7 @@ func (m *valueMatcher) transitionOn(eventField *Field, bufs *bufpair) []*fieldMa case vmFields.startTable != nil: // if there is a potential for a numeric match, try making a Q number from the event - if vmFields.hasQNumbers && eventField.IsQNumber { + if vmFields.hasNumbers && eventField.IsNumber { qNum, err := qNumFromBytes(val) if err == nil { if vmFields.isNondeterministic { @@ -107,13 +107,10 @@ func (m *valueMatcher) addTransition(val typedVal, printer printer) *fieldMatche var nextField *fieldMatcher switch val.vType { case stringType, literalType: - newFA, nextField, _ = makeStringFA(valBytes, nil, false) + newFA, nextField = makeStringFA(valBytes, nil, false) case numberType: - isQNumber := false - newFA, nextField, isQNumber = makeStringFA(valBytes, nil, true) - if isQNumber { - fields.hasQNumbers = true - } + newFA, nextField = makeStringFA(valBytes, nil, true) + fields.hasNumbers = true case anythingButType: newFA, nextField = makeMultiAnythingButFA(val.list) case shellStyleType: @@ -143,18 +140,11 @@ func (m *valueMatcher) addTransition(val typedVal, printer printer) *fieldMatche m.update(fields) return fields.singletonTransition case numberType: - newFA, nextField, isQNumber := makeStringFA(valBytes, nil, true) - if isQNumber { - fields.hasQNumbers = true - fields.startTable = newFA - m.update(fields) - return nextField - } else { - fields.singletonMatch = valBytes - fields.singletonTransition = newFieldMatcher() - m.update(fields) - return fields.singletonTransition - } + newFA, nextField := makeStringFA(valBytes, nil, true) + fields.hasNumbers = true + fields.startTable = newFA + m.update(fields) + return nextField case anythingButType: newFA, nextField := makeMultiAnythingButFA(val.list) fields.startTable = newFA @@ -190,18 +180,15 @@ func (m *valueMatcher) addTransition(val typedVal, printer printer) *fieldMatche // singleton is here, we don't match, so our outdegree becomes 2, so we have // to build an automaton with two values in it - singletonAutomaton, _, _ := makeStringFA(fields.singletonMatch, fields.singletonTransition, false) + singletonAutomaton, _ := makeStringFA(fields.singletonMatch, fields.singletonTransition, false) var nextField *fieldMatcher var newFA *smallTable switch val.vType { case stringType, literalType: - newFA, nextField, _ = makeStringFA(valBytes, nil, false) + newFA, nextField = makeStringFA(valBytes, nil, false) case numberType: - isQNumber := false - newFA, nextField, isQNumber = makeStringFA(valBytes, nil, true) - if isQNumber { - fields.hasQNumbers = true - } + newFA, nextField = makeStringFA(valBytes, nil, true) + fields.hasNumbers = true case anythingButType: newFA, nextField = makeMultiAnythingButFA(val.list) case shellStyleType: @@ -257,7 +244,7 @@ func makeOnePrefixFAStep(val []byte, index int, nextField *fieldMatcher) *smallT // is recursive because this allows the use of the makeSmallTable call, which // reduces memory churn. Converting from a straightforward implementation to // this approximately doubled the fields/second rate in addPattern -func makeStringFA(val []byte, useThisTransition *fieldMatcher, isNumber bool) (*smallTable, *fieldMatcher, bool) { +func makeStringFA(val []byte, useThisTransition *fieldMatcher, isNumber bool) (*smallTable, *fieldMatcher) { var nextField *fieldMatcher if useThisTransition != nil { nextField = useThisTransition @@ -269,16 +256,14 @@ func makeStringFA(val []byte, useThisTransition *fieldMatcher, isNumber bool) (* // if the field is numeric, *and* if it can be converted to a float, *and* can be // made into a Q number, equip the NFA with the Q number form - isQNumber := false if isNumber { qNum, err := qNumFromBytes(val) if err == nil { - isQNumber = true numberFA := makeOneStringFAStep(qNum, 0, nextField) stringFA = mergeFAs(stringFA, numberFA, sharedNullPrinter) } } - return stringFA, nextField, isQNumber + return stringFA, nextField } // makeFAFragment makes the simplest possible byte-chain FA with its last transition being to the provided